cmMakefile.cxx 141 KB
Newer Older
1 2 3
/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4

5 6
  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.
7

8 9 10 11
  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
12
#include "cmMakefile.h"
13
#include "cmVersion.h"
14
#include "cmCommand.h"
15
#include "cmSourceFile.h"
16
#include "cmSourceFileLocation.h"
17
#include "cmSystemTools.h"
Ken Martin's avatar
Ken Martin committed
18 19
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
20
#include "cmCommands.h"
21
#include "cmCacheManager.h"
22
#include "cmFunctionBlocker.h"
23
#include "cmListFileCache.h"
24
#include "cmCommandArgumentParserHelper.h"
25
#include "cmGeneratorExpression.h"
26
#include "cmTest.h"
27 28 29
#ifdef CMAKE_BUILD_WITH_CMAKE
#  include "cmVariableWatch.h"
#endif
30
#include "cmInstallGenerator.h"
31
#include "cmTestGenerator.h"
32
#include "cmDefinitions.h"
33
#include "cmake.h"
34
#include <stdlib.h> // required for atoi
35 36

#include <cmsys/RegularExpression.hxx>
37
#include <cmsys/FStream.hxx>
38 39
#include <cmsys/auto_ptr.hxx>

40
#include <stack>
41
#include <ctype.h> // for isspace
42
#include <assert.h>
43

Stephen Kelly's avatar
Stephen Kelly committed
44
#define FOR_EACH_CXX_FEATURE(F) \
45
  F(cxx_alias_templates) \
Stephen Kelly's avatar
Stephen Kelly committed
46
  F(cxx_alignas) \
Stephen Kelly's avatar
Stephen Kelly committed
47
  F(cxx_alignof) \
Stephen Kelly's avatar
Stephen Kelly committed
48
  F(cxx_attributes) \
49
  F(cxx_auto_type) \
Stephen Kelly's avatar
Stephen Kelly committed
50
  F(cxx_constexpr) \
Stephen Kelly's avatar
Stephen Kelly committed
51
  F(cxx_decltype) \
52
  F(cxx_decltype_incomplete_return_types) \
53
  F(cxx_default_function_template_args) \
54
  F(cxx_defaulted_functions) \
55
  F(cxx_defaulted_move_initializers) \
56
  F(cxx_delegating_constructors) \
57
  F(cxx_deleted_functions) \
58
  F(cxx_enum_forward_declarations) \
59
  F(cxx_explicit_conversions) \
60
  F(cxx_extended_friend_declarations) \
61
  F(cxx_extern_templates) \
Stephen Kelly's avatar
Stephen Kelly committed
62
  F(cxx_final) \
63
  F(cxx_func_identifier) \
64
  F(cxx_generalized_initializers) \
65
  F(cxx_inheriting_constructors) \
66
  F(cxx_inline_namespaces) \
Stephen Kelly's avatar
Stephen Kelly committed
67
  F(cxx_lambdas) \
68
  F(cxx_local_type_template_args) \
69
  F(cxx_long_long_type) \
Stephen Kelly's avatar
Stephen Kelly committed
70
  F(cxx_noexcept) \
71
  F(cxx_nonstatic_member_init) \
Stephen Kelly's avatar
Stephen Kelly committed
72
  F(cxx_nullptr) \
Stephen Kelly's avatar
Stephen Kelly committed
73
  F(cxx_override) \
Stephen Kelly's avatar
Stephen Kelly committed
74
  F(cxx_range_for) \
75
  F(cxx_raw_string_literals) \
76
  F(cxx_reference_qualified_functions) \
77
  F(cxx_right_angle_brackets) \
78
  F(cxx_rvalue_references) \
79
  F(cxx_sizeof_member) \
80
  F(cxx_static_assert) \
81
  F(cxx_strong_enums) \
82
  F(cxx_template_template_parameters) \
83
  F(cxx_thread_local) \
84
  F(cxx_trailing_return_types) \
85
  F(cxx_unicode_literals) \
86
  F(cxx_uniform_initialization) \
87
  F(cxx_unrestricted_unions) \
88
  F(cxx_user_literals) \
89
  F(cxx_variadic_macros) \
90
  F(cxx_variadic_templates)
91

92 93 94 95
class cmMakefile::Internals
{
public:
  std::stack<cmDefinitions, std::list<cmDefinitions> > VarStack;
96 97
  std::stack<std::set<std::string> > VarInitStack;
  std::stack<std::set<std::string> > VarUsageStack;
98
  bool IsSourceFileTryCompile;
99 100
};

101
// default is not to be building executables
102
cmMakefile::cmMakefile(): Internal(new Internals)
103
{
104
  const cmDefinitions& defs = cmDefinitions();
105
  const std::set<std::string> globalKeys = defs.LocalKeys();
106 107
  this->Internal->VarStack.push(defs);
  this->Internal->VarInitStack.push(globalKeys);
108
  this->Internal->VarUsageStack.push(globalKeys);
109
  this->Internal->IsSourceFileTryCompile = false;
110

111 112 113
  // Initialize these first since AddDefaultDefinitions calls AddDefinition
  this->WarnUnused = false;
  this->CheckSystemVars = false;
114

115
  // Setup the default include file regular expression (match everything).
Ken Martin's avatar
Ken Martin committed
116
  this->IncludeFileRegularExpression = "^.*$";
117
  // Setup the default include complaint regular expression (match nothing).
Ken Martin's avatar
Ken Martin committed
118
  this->ComplainFileRegularExpression = "^$";
119
  // Source and header file extensions that we can handle
120

121
  // Set up a list of source and header extensions
Alexander Neundorf's avatar
 
Alexander Neundorf committed
122
  // these are used to find files when the extension
123
  // is not given
124
  // The "c" extension MUST precede the "C" extension.
Ken Martin's avatar
Ken Martin committed
125 126
  this->SourceFileExtensions.push_back( "c" );
  this->SourceFileExtensions.push_back( "C" );
Alexander Neundorf's avatar
 
Alexander Neundorf committed
127

Ken Martin's avatar
Ken Martin committed
128 129 130 131 132
  this->SourceFileExtensions.push_back( "c++" );
  this->SourceFileExtensions.push_back( "cc" );
  this->SourceFileExtensions.push_back( "cpp" );
  this->SourceFileExtensions.push_back( "cxx" );
  this->SourceFileExtensions.push_back( "m" );
Alexander Neundorf's avatar
 
Alexander Neundorf committed
133
  this->SourceFileExtensions.push_back( "M" );
Ken Martin's avatar
Ken Martin committed
134 135 136
  this->SourceFileExtensions.push_back( "mm" );

  this->HeaderFileExtensions.push_back( "h" );
137
  this->HeaderFileExtensions.push_back( "hh" );
Ken Martin's avatar
Ken Martin committed
138 139 140 141 142 143
  this->HeaderFileExtensions.push_back( "h++" );
  this->HeaderFileExtensions.push_back( "hm" );
  this->HeaderFileExtensions.push_back( "hpp" );
  this->HeaderFileExtensions.push_back( "hxx" );
  this->HeaderFileExtensions.push_back( "in" );
  this->HeaderFileExtensions.push_back( "txx" );
Alexander Neundorf's avatar
 
Alexander Neundorf committed
144

Ken Martin's avatar
Ken Martin committed
145 146
  this->DefineFlags = " ";
  this->LocalGenerator = 0;
147

148
  this->AddDefaultDefinitions();
149
  this->Initialize();
150
  this->PreOrder = false;
151
  this->GeneratingBuildSystem = false;
152
}
153

154
cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals)
155
{
156
  this->Internal->VarStack.push(mf.Internal->VarStack.top().Closure());
157 158
  this->Internal->VarInitStack.push(mf.Internal->VarInitStack.top());
  this->Internal->VarUsageStack.push(mf.Internal->VarUsageStack.top());
159

160 161
  this->Prefix = mf.Prefix;
  this->AuxSourceDirectories = mf.AuxSourceDirectories;
Alexander Neundorf's avatar
 
Alexander Neundorf committed
162 163 164
  this->cmStartDirectory = mf.cmStartDirectory;
  this->StartOutputDirectory = mf.StartOutputDirectory;
  this->cmHomeDirectory = mf.cmHomeDirectory;
165 166 167 168 169 170 171
  this->HomeOutputDirectory = mf.HomeOutputDirectory;
  this->cmCurrentListFile = mf.cmCurrentListFile;
  this->ProjectName = mf.ProjectName;
  this->Targets = mf.Targets;
  this->SourceFiles = mf.SourceFiles;
  this->Tests = mf.Tests;
  this->LinkDirectories = mf.LinkDirectories;
172
  this->SystemIncludeDirectories = mf.SystemIncludeDirectories;
173 174 175 176
  this->ListFiles = mf.ListFiles;
  this->OutputFiles = mf.OutputFiles;
  this->LinkLibraries = mf.LinkLibraries;
  this->InstallGenerators = mf.InstallGenerators;
177
  this->TestGenerators = mf.TestGenerators;
178 179 180 181 182
  this->IncludeFileRegularExpression = mf.IncludeFileRegularExpression;
  this->ComplainFileRegularExpression = mf.ComplainFileRegularExpression;
  this->SourceFileExtensions = mf.SourceFileExtensions;
  this->HeaderFileExtensions = mf.HeaderFileExtensions;
  this->DefineFlags = mf.DefineFlags;
183
  this->DefineFlagsOrig = mf.DefineFlagsOrig;
184 185 186 187 188 189 190 191 192 193 194

#if defined(CMAKE_BUILD_WITH_CMAKE)
  this->SourceGroups = mf.SourceGroups;
#endif

  this->LocalGenerator = mf.LocalGenerator;
  this->FunctionBlockers = mf.FunctionBlockers;
  this->MacrosMap = mf.MacrosMap;
  this->SubDirectoryOrder = mf.SubDirectoryOrder;
  this->Properties = mf.Properties;
  this->PreOrder = mf.PreOrder;
195
  this->WarnUnused = mf.WarnUnused;
196
  this->Initialize();
197
  this->CheckSystemVars = mf.CheckSystemVars;
198
  this->ListFileStack = mf.ListFileStack;
199
  this->OutputToSource = mf.OutputToSource;
200 201
}

202 203 204 205 206 207
//----------------------------------------------------------------------------
void cmMakefile::Initialize()
{
  this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
  this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
  this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
208 209 210

  // Enter a policy level for this directory.
  this->PushPolicy();
211

Brad King's avatar
Brad King committed
212 213 214
  // Protect the directory-level policies.
  this->PushPolicyBarrier();

215 216 217
  // By default the check is not done.  It is enabled by
  // cmListFileCache in the top level if necessary.
  this->CheckCMP0000 = false;
218
}
219

220
unsigned int cmMakefile::GetCacheMajorVersion() const
221
{
222
  return this->GetCacheManager()->GetCacheMajorVersion();
223 224
}

225
unsigned int cmMakefile::GetCacheMinorVersion() const
226
{
227
  return this->GetCacheManager()->GetCacheMinorVersion();
228 229
}

230
bool cmMakefile::NeedCacheCompatibility(int major, int minor) const
231 232 233
{
  return this->GetCacheManager()->NeedCacheCompatibility(major, minor);
}
234

235 236
cmMakefile::~cmMakefile()
{
237
  for(std::vector<cmInstallGenerator*>::iterator
Ken Martin's avatar
Ken Martin committed
238 239
        i = this->InstallGenerators.begin();
      i != this->InstallGenerators.end(); ++i)
240 241 242
    {
    delete *i;
    }
243 244 245 246 247 248
  for(std::vector<cmTestGenerator*>::iterator
        i = this->TestGenerators.begin();
      i != this->TestGenerators.end(); ++i)
    {
    delete *i;
    }
Ken Martin's avatar
Ken Martin committed
249 250
  for(std::vector<cmSourceFile*>::iterator i = this->SourceFiles.begin();
      i != this->SourceFiles.end(); ++i)
251 252 253
    {
    delete *i;
    }
254
  for(std::map<std::string, cmTest*>::iterator i = this->Tests.begin();
Ken Martin's avatar
Ken Martin committed
255
      i != this->Tests.end(); ++i)
256
    {
257
    delete i->second;
258
    }
259 260 261 262 263 264
  for(std::vector<cmTarget*>::iterator
        i = this->ImportedTargetsOwned.begin();
      i != this->ImportedTargetsOwned.end(); ++i)
    {
    delete *i;
    }
265
  for(unsigned int i=0; i < this->FinalPassCommands.size(); i++)
266
    {
267
    delete this->FinalPassCommands[i];
268
    }
269
  std::vector<cmFunctionBlocker*>::iterator pos;
Alexander Neundorf's avatar
 
Alexander Neundorf committed
270
  for (pos = this->FunctionBlockers.begin();
Ken Martin's avatar
Ken Martin committed
271
       pos != this->FunctionBlockers.end(); ++pos)
Bill Hoffman's avatar
Bill Hoffman committed
272 273 274 275
    {
    cmFunctionBlocker* b = *pos;
    delete b;
    }
Ken Martin's avatar
Ken Martin committed
276
  this->FunctionBlockers.clear();
277 278 279 280 281
  if (this->PolicyStack.size() != 1)
  {
    cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
      " popped properly");
  }
282 283
}

Alexander Neundorf's avatar
 
Alexander Neundorf committed
284
void cmMakefile::PrintStringVector(const char* s,
Ken Martin's avatar
Ken Martin committed
285
                                   const std::vector<std::string>& v) const
286 287
{
  std::cout << s << ": ( \n";
288
  for(std::vector<std::string>::const_iterator i = v.begin();
289 290
      i != v.end(); ++i)
    {
291
    std::cout << *i << " ";
292 293
    }
  std::cout << " )\n";
294 295
}

Ken Martin's avatar
Ken Martin committed
296
void cmMakefile
Alexander Neundorf's avatar
 
Alexander Neundorf committed
297
::PrintStringVector(const char* s,
298
                    const std::vector<std::pair<std::string, bool> >& v) const
299 300
{
  std::cout << s << ": ( \n";
301
  for(std::vector<std::pair<std::string, bool> >::const_iterator i
Ken Martin's avatar
Ken Martin committed
302
        = v.begin(); i != v.end(); ++i)
303
    {
304
    std::cout << i->first << " " << i->second;
305 306 307 308
    }
  std::cout << " )\n";
}

309 310

// call print on all the classes in the makefile
311
void cmMakefile::Print() const
312
{
313
  // print the class lists
314
  std::cout << "classes:\n";
315

Ken Martin's avatar
Ken Martin committed
316 317 318
  std::cout << " this->Targets: ";
  for (cmTargets::iterator l = this->Targets.begin();
       l != this->Targets.end(); l++)
319 320 321 322
    {
    std::cout << l->first << std::endl;
    }

Alexander Neundorf's avatar
 
Alexander Neundorf committed
323
  std::cout << " this->StartOutputDirectory; " <<
324
    this->StartOutputDirectory << std::endl;
Alexander Neundorf's avatar
 
Alexander Neundorf committed
325
  std::cout << " this->HomeOutputDirectory; " <<
326
    this->HomeOutputDirectory << std::endl;
Alexander Neundorf's avatar
 
Alexander Neundorf committed
327
  std::cout << " this->cmStartDirectory; " <<
328
    this->cmStartDirectory << std::endl;
Alexander Neundorf's avatar
 
Alexander Neundorf committed
329
  std::cout << " this->cmHomeDirectory; " <<
330
    this->cmHomeDirectory << std::endl;
Alexander Neundorf's avatar
 
Alexander Neundorf committed
331
  std::cout << " this->ProjectName; "
332
            <<  this->ProjectName << std::endl;
Ken Martin's avatar
Ken Martin committed
333
  this->PrintStringVector("this->LinkDirectories", this->LinkDirectories);
334
#if defined(CMAKE_BUILD_WITH_CMAKE)
Alexander Neundorf's avatar
 
Alexander Neundorf committed
335
  for( std::vector<cmSourceGroup>::const_iterator i =
Ken Martin's avatar
Ken Martin committed
336
         this->SourceGroups.begin(); i != this->SourceGroups.end(); ++i)
337
    {
338
    std::cout << "Source Group: " << i->GetName() << std::endl;
339
    }
340
#endif
341 342
}

343 344
bool cmMakefile::CommandExists(const char* name) const
{
345
  return this->GetCMakeInstance()->CommandExists(name);
346
}
347

348 349

//----------------------------------------------------------------------------
Bill Hoffman's avatar
Bill Hoffman committed
350 351
void cmMakefile::IssueMessage(cmake::MessageType t,
                              std::string const& text) const
352
{
353 354 355
  // Collect context information.
  cmListFileBacktrace backtrace;
  if(!this->CallStack.empty())
356
    {
357
    if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR))
358
      {
359
      this->CallStack.back().Status->SetNestedError(true);
360
      }
361
    this->GetBacktrace(backtrace);
362
    }
363
  else
364
    {
365
    cmListFileContext lfc;
366 367 368 369 370 371 372 373 374 375 376 377
    if(this->ListFileStack.empty())
      {
      // We are not processing the project.  Add the directory-level context.
      lfc.FilePath = this->GetCurrentDirectory();
      lfc.FilePath += "/CMakeLists.txt";
      }
    else
      {
      // We are processing the project but are not currently executing a
      // command.  Add whatever context information we have.
      lfc.FilePath = this->ListFileStack.back();
      }
378 379
    lfc.Line = 0;
    if(!this->GetCMakeInstance()->GetIsInTryCompile())
380
      {
Stephen Kelly's avatar
Stephen Kelly committed
381
      lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath,
382
                                                   cmLocalGenerator::HOME);
383
      }
384
    backtrace.push_back(lfc);
385
    }
386

387 388 389
  // Issue the message.
  this->GetCMakeInstance()->IssueMessage(t, text, backtrace);
}
390

391 392 393 394
//----------------------------------------------------------------------------
bool cmMakefile::GetBacktrace(cmListFileBacktrace& backtrace) const
{
  if(this->CallStack.empty())
395
    {
396
    return false;
397
    }
398 399
  for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
      i != this->CallStack.rend(); ++i)
400
    {
401
    cmListFileContext lfc = *(*i).Context;
Stephen Kelly's avatar
Stephen Kelly committed
402
    lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath,
403 404
                                                 cmLocalGenerator::HOME);
    backtrace.push_back(lfc);
405
    }
406
  return true;
407 408
}

409
//----------------------------------------------------------------------------
410
void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
411 412 413 414 415 416 417 418 419 420 421 422 423 424
{
  cmOStringStream msg;
  msg << lff.FilePath << "(" << lff.Line << "):  ";
  msg << lff.Name << "(";
  for(std::vector<cmListFileArgument>::const_iterator i =
        lff.Arguments.begin(); i != lff.Arguments.end(); ++i)
    {
    msg << i->Value;
    msg << " ";
    }
  msg << ")";
  cmSystemTools::Message(msg.str().c_str());
}

425
//----------------------------------------------------------------------------
426 427
bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
                                cmExecutionStatus &status)
Ken Martin's avatar
Ken Martin committed
428
{
429
  bool result = true;
430

431
  // quick return if blocked
432
  if(this->IsFunctionBlocked(lff,status))
433
    {
434 435
    // No error.
    return result;
436
    }
437

Ken Martin's avatar
Ken Martin committed
438
  std::string name = lff.Name;
439

440 441 442 443 444
  // Place this call on the call stack.
  cmMakefileCall stack_manager(this, lff, status);
  static_cast<void>(stack_manager);

  // Lookup the command prototype.
Stephen Kelly's avatar
Stephen Kelly committed
445
  if(cmCommand* proto = this->GetCMakeInstance()->GetCommand(name))
446 447 448 449 450 451 452
    {
    // Clone the prototype.
    cmsys::auto_ptr<cmCommand> pcmd(proto->Clone());
    pcmd->SetMakefile(this);

    // Decide whether to invoke the command.
    if(pcmd->GetEnabled() && !cmSystemTools::GetFatalErrorOccured()  &&
453 454
       (this->GetCMakeInstance()->GetWorkingMode() != cmake::SCRIPT_MODE
       || pcmd->IsScriptable()))
455

456
      {
457
      // if trace is enabled, print out invoke information
Bill Hoffman's avatar
Bill Hoffman committed
458 459
      if(this->GetCMakeInstance()->GetTrace())
        {
460
        this->PrintCommandTrace(lff);
Bill Hoffman's avatar
Bill Hoffman committed
461
        }
462 463 464
      // Try invoking the command.
      if(!pcmd->InvokeInitialPass(lff.Arguments,status) ||
         status.GetNestedError())
Ken Martin's avatar
Ken Martin committed
465
        {
466 467 468
        if(!status.GetNestedError())
          {
          // The command invocation requested that we report an error.
Bill Hoffman's avatar
Bill Hoffman committed
469
          this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError());
470
          }
471
        result = false;
472
        if ( this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE)
Ken Martin's avatar
Ken Martin committed
473
          {
474
          cmSystemTools::SetFatalErrorOccured();
Ken Martin's avatar
Ken Martin committed
475 476
          }
        }
477
      else if(pcmd->HasFinalPass())
478 479
        {
        // use the command
480
        this->FinalPassCommands.push_back(pcmd.release());
481
        }
Ken Martin's avatar
Ken Martin committed
482
      }
483
    else if ( this->GetCMakeInstance()->GetWorkingMode() == cmake::SCRIPT_MODE
484
              && !pcmd->IsScriptable() )
485
      {
486 487 488
      std::string error = "Command ";
      error += pcmd->GetName();
      error += "() is not scriptable";
Bill Hoffman's avatar
Bill Hoffman committed
489
      this->IssueMessage(cmake::FATAL_ERROR, error);
490 491 492
      result = false;
      cmSystemTools::SetFatalErrorOccured();
      }
Ken Martin's avatar
Ken Martin committed
493 494 495
    }
  else
    {
496 497
    if(!cmSystemTools::GetFatalErrorOccured())
      {
498 499 500
      std::string error = "Unknown CMake command \"";
      error += lff.Name;
      error += "\".";
Bill Hoffman's avatar
Bill Hoffman committed
501
      this->IssueMessage(cmake::FATAL_ERROR, error);
502
      result = false;
503
      cmSystemTools::SetFatalErrorOccured();
504
      }
Ken Martin's avatar
Ken Martin committed
505
    }
Alexander Neundorf's avatar
 
Alexander Neundorf committed
506

507
  return result;
Ken Martin's avatar
Ken Martin committed
508 509
}

Brad King's avatar
Brad King committed
510 511 512 513
//----------------------------------------------------------------------------
class cmMakefile::IncludeScope
{
public:
514
  IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope);
Brad King's avatar
Brad King committed
515 516 517 518
  ~IncludeScope();
  void Quiet() { this->ReportError = false; }
private:
  cmMakefile* Makefile;
519 520 521
  const char* File;
  bool NoPolicyScope;
  bool CheckCMP0011;
Brad King's avatar
Brad King committed
522
  bool ReportError;
523
  void EnforceCMP0011();
Brad King's avatar
Brad King committed
524 525 526
};

//----------------------------------------------------------------------------
527 528 529 530
cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
                                       bool noPolicyScope):
  Makefile(mf), File(fname), NoPolicyScope(noPolicyScope),
  CheckCMP0011(false), ReportError(true)
Brad King's avatar
Brad King committed
531
{
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
  if(!this->NoPolicyScope)
    {
    // Check CMP0011 to determine the policy scope type.
    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
      {
      case cmPolicies::WARN:
        // We need to push a scope to detect whether the script sets
        // any policies that would affect the includer and therefore
        // requires a warning.  We use a weak scope to simulate OLD
        // behavior by allowing policy changes to affect the includer.
        this->Makefile->PushPolicy(true);
        this->CheckCMP0011 = true;
        break;
      case cmPolicies::OLD:
        // OLD behavior is to not push a scope at all.
        this->NoPolicyScope = true;
        break;
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
        // We should never make this policy required, but we handle it
        // here just in case.
        this->CheckCMP0011 = true;
      case cmPolicies::NEW:
        // NEW behavior is to push a (strong) scope.
        this->Makefile->PushPolicy();
        break;
      }
    }

Brad King's avatar
Brad King committed
561 562 563 564 565 566 567 568 569
  // The included file cannot pop our policy scope.
  this->Makefile->PushPolicyBarrier();
}

//----------------------------------------------------------------------------
cmMakefile::IncludeScope::~IncludeScope()
{
  // Enforce matching policy scopes inside the included file.
  this->Makefile->PopPolicyBarrier(this->ReportError);
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630

  if(!this->NoPolicyScope)
    {
    // If we need to enforce policy CMP0011 then the top entry is the
    // one we pushed above.  If the entry is empty, then the included
    // script did not set any policies that might affect the includer so
    // we do not need to enforce the policy.
    if(this->CheckCMP0011 && this->Makefile->PolicyStack.back().empty())
      {
      this->CheckCMP0011 = false;
      }

    // Pop the scope we pushed for the script.
    this->Makefile->PopPolicy();

    // We enforce the policy after the script's policy stack entry has
    // been removed.
    if(this->CheckCMP0011)
      {
      this->EnforceCMP0011();
      }
    }
}

//----------------------------------------------------------------------------
void cmMakefile::IncludeScope::EnforceCMP0011()
{
  // We check the setting of this policy again because the included
  // script might actually set this policy for its includer.
  cmPolicies* policies = this->Makefile->GetPolicies();
  switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
    {
    case cmPolicies::WARN:
      // Warn because the user did not set this policy.
      {
      cmOStringStream w;
      w << policies->GetPolicyWarning(cmPolicies::CMP0011) << "\n"
        << "The included script\n  " << this->File << "\n"
        << "affects policy settings.  "
        << "CMake is implying the NO_POLICY_SCOPE option for compatibility, "
        << "so the effects are applied to the including context.";
      this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
      }
      break;
    case cmPolicies::REQUIRED_IF_USED:
    case cmPolicies::REQUIRED_ALWAYS:
      {
      cmOStringStream e;
      e << policies->GetRequiredPolicyError(cmPolicies::CMP0011) << "\n"
        << "The included script\n  " << this->File << "\n"
        << "affects policy settings, so it requires this policy to be set.";
      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
      }
      break;
    case cmPolicies::OLD:
    case cmPolicies::NEW:
      // The script set this policy.  We assume the purpose of the
      // script is to initialize policies for its includer, and since
      // the policy is now set for later scripts, we do not warn.
      break;
    }
Brad King's avatar
Brad King committed
631 632 633
}

//----------------------------------------------------------------------------
634
// Parse the given CMakeLists.txt file executing all commands
Anonymous's avatar
Anonymous committed
635
//
Alexander Neundorf's avatar
 
Alexander Neundorf committed
636
bool cmMakefile::ReadListFile(const char* filename_in,
Alexander Neundorf's avatar
 
Alexander Neundorf committed
637
                              const char *external_in,
638 639
                              std::string* fullPath,
                              bool noPolicyScope)
640
{
641 642 643 644
  std::string currentParentFile
    = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
  std::string currentFile
    = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
645
  this->AddDefinition("CMAKE_PARENT_LIST_FILE", filename_in);
646
  this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
647

Brad King's avatar
Brad King committed
648 649 650 651 652 653 654 655 656 657
  const char* external = 0;
  std::string external_abs;

  const char* filename = filename_in;
  std::string filename_abs;

  if (external_in)
    {
    external_abs =
      cmSystemTools::CollapseFullPath(external_in,
Ken Martin's avatar
Ken Martin committed
658
                                      this->cmStartDirectory.c_str());
Brad King's avatar
Brad King committed
659 660 661 662 663
    external = external_abs.c_str();
    if (filename_in)
      {
      filename_abs =
        cmSystemTools::CollapseFullPath(filename_in,
Ken Martin's avatar
Ken Martin committed
664
                                        this->cmStartDirectory.c_str());
Brad King's avatar
Brad King committed
665 666 667
      filename = filename_abs.c_str();
      }
    }
Alexander Neundorf's avatar
 
Alexander Neundorf committed
668

669
  // keep track of the current file being read
670 671
  if (filename)
    {
Ken Martin's avatar
Ken Martin committed
672
    if(this->cmCurrentListFile != filename)
Bill Hoffman's avatar
Bill Hoffman committed
673
      {
Ken Martin's avatar
Ken Martin committed
674
      this->cmCurrentListFile = filename;
Bill Hoffman's avatar
Bill Hoffman committed
675
      }
676 677
    }

678
  // Now read the input file
Anonymous's avatar
Anonymous committed
679 680 681
  const char *filenametoread= filename;

  if( external)
682
    {
Anonymous's avatar
Anonymous committed
683
    filenametoread= external;
684
    }
685 686

  this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
687
  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
688 689
  this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
                       cmSystemTools::GetFilenamePath(filenametoread).c_str());
690
  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
691

692 693 694
  // try to see if the list file is the top most
  // list file for a project, and if it is, then it
  // must have a project command.   If there is not
Alexander Neundorf's avatar
 
Alexander Neundorf committed
695
  // one, then cmake will provide one via the
696 697
  // cmListFileCache class.
  bool requireProjectCommand = false;
Ken Martin's avatar
Ken Martin committed
698
  if(!external && this->cmStartDirectory == this->cmHomeDirectory)
699 700
    {
    if(cmSystemTools::LowerCase(
Bill Hoffman's avatar
Bill Hoffman committed
701
      cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt")
702 703 704 705
      {
      requireProjectCommand = true;
      }
    }
Alexander Neundorf's avatar
 
Alexander Neundorf committed
706

Ken Martin's avatar
Ken Martin committed
707 708
  // push the listfile onto the stack
  this->ListFileStack.push_back(filenametoread);
Alexander Neundorf's avatar
 
Alexander Neundorf committed
709 710 711 712
  if(fullPath!=0)
    {
    *fullPath=filenametoread;
    }
713
  cmListFile cacheFile;
714
  if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
715
    {
Alexander Neundorf's avatar
 
Alexander Neundorf committed
716 717
    // pop the listfile off the stack
    this->ListFileStack.pop_back();
Alexander Neundorf's avatar
 
Alexander Neundorf committed
718 719
    if(fullPath!=0)
      {
720
      *fullPath = "";
Alexander Neundorf's avatar
 
Alexander Neundorf committed
721
      }
722
    this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
723
    this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
724
    this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
725
    this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
726 727
    this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
                        cmSystemTools::GetFilenamePath(currentFile).c_str());
728
    this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
729 730
    return false;
    }
731
  // add this list file to the list of dependencies
Ken Martin's avatar
Ken Martin committed
732
  this->ListFiles.push_back( filenametoread);
733 734 735 736

  // Enforce balanced blocks (if/endif, function/endfunction, etc.).
  {
  LexicalPushPop lexScope(this);
737
  IncludeScope incScope(this, filenametoread, noPolicyScope);
738 739

  // Run the parsed commands.
Ken Martin's avatar
Ken Martin committed
740
  const size_t numberFunctions = cacheFile.Functions.size();
741
  for(size_t i =0; i < numberFunctions; ++i)
742
    {
743 744
    cmExecutionStatus status;
    this->ExecuteCommand(cacheFile.Functions[i],status);
745
    if(cmSystemTools::GetFatalErrorOccured())
746
      {
747 748
      // Exit early due to error.
      lexScope.Quiet();
Brad King's avatar
Brad King committed
749
      incScope.Quiet();
750 751 752 753 754
      break;
      }
    if(status.GetReturnInvoked())
      {
      // Exit early due to return command.
755
      break;
756
      }
757
    }
758
  }
Alexander Neundorf's avatar
 
Alexander Neundorf committed
759

760 761
  // If this is the directory-level CMakeLists.txt file then perform
  // some extra checks.
762 763
  if(this->ListFileStack.size() == 1)
    {
764
    this->EnforceDirectoryLevelRules();
765 766
    }

767
  this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
768
  this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
769
  this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
770
  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
771 772
  this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
                      cmSystemTools::GetFilenamePath(currentFile).c_str());
773
  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
Ken Martin's avatar
Ken Martin committed
774 775 776 777

  // pop the listfile off the stack
  this->ListFileStack.pop_back();

778 779 780
  // Check for unused variables
  this->CheckForUnusedVariables();

781 782
  return true;
}
783

784
//----------------------------------------------------------------------------
785
void cmMakefile::EnforceDirectoryLevelRules() const
786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806
{
  // Diagnose a violation of CMP0000 if necessary.
  if(this->CheckCMP0000)
    {
    cmOStringStream msg;
    msg << "No cmake_minimum_required command is present.  "
        << "A line of code such as\n"
        << "  cmake_minimum_required(VERSION "
        << cmVersion::GetMajorVersion() << "."
        << cmVersion::GetMinorVersion()
        << ")\n"
        << "should be added at the top of the file.  "
        << "The version specified may be lower if you wish to "
        << "support older CMake versions for this project.  "
        << "For more information run "
        << "\"cmake --help-policy CMP0000\".";
    switch (this->GetPolicyStatus(cmPolicies::CMP0000))
      {
      case cmPolicies::WARN:
        // Warn because the user did not provide a mimimum required
        // version.
Stephen Kelly's avatar
Stephen Kelly committed
807
        this->IssueMessage(cmake::AUTHOR_WARNING, msg.str());
808 809 810 811 812 813 814 815
      case cmPolicies::OLD:
        // OLD behavior is to use policy version 2.4 set in
        // cmListFileCache.
        break;
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
      case cmPolicies::NEW:
        // NEW behavior is to issue an error.
Stephen Kelly's avatar
Stephen Kelly committed
816
        this->IssueMessage(cmake::FATAL_ERROR, msg.str());
817 818 819 820 821
        cmSystemTools::SetFatalErrorOccured();
        return;
      }
    }
}
822

823
void cmMakefile::AddCommand(cmCommand* wg)
824
{
825
  this->GetCMakeInstance()->AddCommand(wg);
826 827
}

Alexander Neundorf's avatar
 
Alexander Neundorf committed
828
// Set the make file
Ken Martin's avatar
Ken Martin committed
829
void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
830
{
Ken Martin's avatar
Ken Martin committed
831
  this->LocalGenerator = lg;
832 833 834 835 836 837 838 839
  // the source groups need to access the global generator
  // so don't create them until the lg is set