cmMakefile.cxx 166 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"
Stephen Kelly's avatar
Stephen Kelly committed
21
#include "cmState.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 "cmAlgorithms.h"
34
#include "cmake.h"
35
#include <stdlib.h> // required for atoi
36
37

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

41
#include <stack>
42
#include <list>
43
#include <ctype.h> // for isspace
44
#include <assert.h>
45

46
47
48
class cmMakefile::Internals
{
public:
49
  std::list<cmDefinitions> VarStack;
50
51
  std::stack<std::set<std::string> > VarInitStack;
  std::stack<std::set<std::string> > VarUsageStack;
52
  bool IsSourceFileTryCompile;
53
54
55

  void PushDefinitions()
  {
56
    this->VarStack.push_back(cmDefinitions());
57
58
59
60
  }

  void InitializeDefinitions(cmMakefile* parent)
  {
61
62
63
    this->VarStack.back() =
        cmDefinitions::MakeClosure(parent->Internal->VarStack.rbegin(),
                                   parent->Internal->VarStack.rend());
64
65
66
67
  }

  const char* GetDefinition(std::string const& name)
  {
68
69
    return cmDefinitions::Get(name, this->VarStack.rbegin(),
                                    this->VarStack.rend());
70
71
72
73
  }

  void SetDefinition(std::string const& name, std::string const& value)
  {
74
    this->VarStack.back().Set(name, value.c_str());
75
76
77
78
  }

  void RemoveDefinition(std::string const& name)
  {
79
80
81
    if (this->VarStack.size() > 1)
      {
      // In lower scopes we store keys, defined or not.
82
      this->VarStack.back().Set(name, 0);
83
84
85
      }
    else
      {
86
      this->VarStack.back().Erase(name);
87
      }
88
89
  }

90
  std::vector<std::string> LocalKeys() const
91
  {
92
    return this->VarStack.back().LocalKeys();
93
94
  }

95
  std::vector<std::string> ClosureKeys() const
96
  {
97
98
    return cmDefinitions::ClosureKeys(this->VarStack.rbegin(),
                                      this->VarStack.rend());
99
100
101
102
  }

  void PopDefinitions()
  {
103
    this->VarStack.pop_back();
104
105
106
107
  }

  bool RaiseScope(std::string const& var, const char* varDef, cmMakefile* mf)
  {
108
    std::list<cmDefinitions>::reverse_iterator it = this->VarStack.rbegin();
109
    assert(it != this->VarStack.rend());
110
111
    ++it;
    if(it == this->VarStack.rend())
112
      {
113
      if(cmLocalGenerator* plg = mf->GetLocalGenerator()->GetParent())
114
        {
115
116
117
118
119
120
121
122
123
124
125
126
127
        // Update the definition in the parent directory top scope.  This
        // directory's scope was initialized by the closure of the parent
        // scope, so we do not need to localize the definition first.
        cmMakefile* parent = plg->GetMakefile();
        if (varDef)
          {
          parent->AddDefinition(var, varDef);
          }
        else
          {
          parent->RemoveDefinition(var);
          }
        return true;
128
129
130
        }
      else
        {
131
        return false;
132
133
        }
      }
134
135
136
137
138
    // First localize the definition in the current scope.
    this->GetDefinition(var);

    // Now update the definition in the parent scope.
    it->Set(var, varDef);
139
140
    return true;
  }
141
142
};

143
// default is not to be building executables
144
cmMakefile::cmMakefile(cmLocalGenerator* localGenerator)
Stephen Kelly's avatar
Stephen Kelly committed
145
146
  : Internal(new Internals),
    LocalGenerator(localGenerator),
147
    StateSnapshot(localGenerator->GetStateSnapshot())
148
{
149
150
151
  this->Internal->PushDefinitions();
  this->Internal->VarInitStack.push(std::set<std::string>());
  this->Internal->VarUsageStack.push(std::set<std::string>());
152
  this->Internal->IsSourceFileTryCompile = false;
153

154
  // Initialize these first since AddDefaultDefinitions calls AddDefinition
155
156
  this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
  this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars();
157

158
159
160
  this->GeneratingBuildSystem = false;
  this->SuppressWatches = false;

161
  // Setup the default include file regular expression (match everything).
Ken Martin's avatar
Ken Martin committed
162
  this->IncludeFileRegularExpression = "^.*$";
163
  // Setup the default include complaint regular expression (match nothing).
Ken Martin's avatar
Ken Martin committed
164
  this->ComplainFileRegularExpression = "^$";
165
  // Source and header file extensions that we can handle
166

167
  // Set up a list of source and header extensions
Alexander Neundorf's avatar
   
Alexander Neundorf committed
168
  // these are used to find files when the extension
169
  // is not given
170
  // The "c" extension MUST precede the "C" extension.
Ken Martin's avatar
Ken Martin committed
171
172
  this->SourceFileExtensions.push_back( "c" );
  this->SourceFileExtensions.push_back( "C" );
Alexander Neundorf's avatar
   
Alexander Neundorf committed
173

Ken Martin's avatar
Ken Martin committed
174
175
176
177
178
  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
179
  this->SourceFileExtensions.push_back( "M" );
Ken Martin's avatar
Ken Martin committed
180
181
182
  this->SourceFileExtensions.push_back( "mm" );

  this->HeaderFileExtensions.push_back( "h" );
183
  this->HeaderFileExtensions.push_back( "hh" );
Ken Martin's avatar
Ken Martin committed
184
185
186
187
188
189
  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
190

Ken Martin's avatar
Ken Martin committed
191
  this->DefineFlags = " ";
192

193
  this->AddDefaultDefinitions();
194

195
196
197
  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/.+-]+@)");
198
  this->cmNamedCurly.compile("^[A-Za-z0-9/_.+-]+{");
199
200
201

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

Brad King's avatar
Brad King committed
203
204
205
  // Protect the directory-level policies.
  this->PushPolicyBarrier();

206
207
208
  // push empty loop block
  this->PushLoopBlockBarrier();

209
210
211
  // By default the check is not done.  It is enabled by
  // cmListFileCache in the top level if necessary.
  this->CheckCMP0000 = false;
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

#if defined(CMAKE_BUILD_WITH_CMAKE)
  this->AddSourceGroup("", "^.*$");
  this->AddSourceGroup
    ("Source Files",
     "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|f|f90|for|fpp"
     "|ftn|m|mm|rc|def|r|odl|idl|hpj|bat)$");
  this->AddSourceGroup("Header Files", CM_HEADER_REGEX);
  this->AddSourceGroup("CMake Rules", "\\.rule$");
  this->AddSourceGroup("Resources", "\\.plist$");
  this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$");
#endif

  this->Properties.SetCMakeInstance(this->GetCMakeInstance());

  {
  const char* dir = this->GetCMakeInstance()->GetHomeDirectory();
  this->AddDefinition("CMAKE_SOURCE_DIR", dir);
230
  this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", dir);
231
232
233
234
  }
  {
  const char* dir = this->GetCMakeInstance()->GetHomeOutputDirectory();
  this->AddDefinition("CMAKE_BINARY_DIR", dir);
235
  this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", dir);
236
  }
237
}
238

239
240
cmMakefile::~cmMakefile()
{
241
242
243
244
245
246
247
  cmDeleteAll(this->InstallGenerators);
  cmDeleteAll(this->TestGenerators);
  cmDeleteAll(this->SourceFiles);
  cmDeleteAll(this->Tests);
  cmDeleteAll(this->ImportedTargetsOwned);
  cmDeleteAll(this->FinalPassCommands);
  cmDeleteAll(this->FunctionBlockers);
Ken Martin's avatar
Ken Martin committed
248
  this->FunctionBlockers.clear();
249
250
251
252
253
  if (this->PolicyStack.size() != 1)
  {
    cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
      " popped properly");
  }
254
255
}

256
//----------------------------------------------------------------------------
Bill Hoffman's avatar
Bill Hoffman committed
257
258
void cmMakefile::IssueMessage(cmake::MessageType t,
                              std::string const& text) const
259
{
260
  // Collect context information.
261
262
263
264
265
266
  cmLocalGenerator* localGen = this->GetLocalGenerator();
  if(this->CallStack.empty() && this->GetCMakeInstance()->GetIsInTryCompile())
    {
    localGen = 0;
    }
  cmListFileBacktrace backtrace(localGen);
267
  if(!this->CallStack.empty())
268
    {
269
    if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR))
270
      {
271
      this->CallStack.back().Status->SetNestedError(true);
272
      }
Ben Boeckel's avatar
Ben Boeckel committed
273
    backtrace = this->GetBacktrace();
274
    }
275
  else
276
    {
277
    cmListFileContext lfc;
278
279
280
    if(this->ListFileStack.empty())
      {
      // We are not processing the project.  Add the directory-level context.
281
      lfc.FilePath = this->GetCurrentSourceDirectory();
282
283
284
285
286
287
288
289
      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();
      }
290
    lfc.Line = 0;
291
    backtrace.Append(lfc);
292
    }
293

294
295
296
  // Issue the message.
  this->GetCMakeInstance()->IssueMessage(t, text, backtrace);
}
297

298
//----------------------------------------------------------------------------
Ben Boeckel's avatar
Ben Boeckel committed
299
cmListFileBacktrace cmMakefile::GetBacktrace() const
300
{
301
  cmListFileBacktrace backtrace(this->GetLocalGenerator());
302
303
  for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
      i != this->CallStack.rend(); ++i)
304
    {
305
    backtrace.Append(*i->Context);
306
    }
Ben Boeckel's avatar
Ben Boeckel committed
307
  return backtrace;
308
309
}

310
311
312
313
314
315
//----------------------------------------------------------------------------
cmListFileContext cmMakefile::GetExecutionContext() const
{
  return *this->CallStack.back().Context;
}

316
//----------------------------------------------------------------------------
317
void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
318
{
319
  std::ostringstream msg;
320
321
322
323
324
325
326
327
328
329
330
331
  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());
}

332
//----------------------------------------------------------------------------
333
334
bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
                                cmExecutionStatus &status)
Ken Martin's avatar
Ken Martin committed
335
{
336
  bool result = true;
337

338
  // quick return if blocked
339
  if(this->IsFunctionBlocked(lff,status))
340
    {
341
342
    // No error.
    return result;
343
    }
344

Ken Martin's avatar
Ken Martin committed
345
  std::string name = lff.Name;
346

347
348
349
350
351
  // Place this call on the call stack.
  cmMakefileCall stack_manager(this, lff, status);
  static_cast<void>(stack_manager);

  // Lookup the command prototype.
352
  if(cmCommand* proto = this->GetState()->GetCommand(name))
353
354
355
356
357
358
359
    {
    // Clone the prototype.
    cmsys::auto_ptr<cmCommand> pcmd(proto->Clone());
    pcmd->SetMakefile(this);

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

363
      {
364
      // if trace is enabled, print out invoke information
Bill Hoffman's avatar
Bill Hoffman committed
365
366
      if(this->GetCMakeInstance()->GetTrace())
        {
367
        this->PrintCommandTrace(lff);
Bill Hoffman's avatar
Bill Hoffman committed
368
        }
369
370
371
      // Try invoking the command.
      if(!pcmd->InvokeInitialPass(lff.Arguments,status) ||
         status.GetNestedError())
Ken Martin's avatar
Ken Martin committed
372
        {
373
374
375
        if(!status.GetNestedError())
          {
          // The command invocation requested that we report an error.
Bill Hoffman's avatar
Bill Hoffman committed
376
          this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError());
377
          }
378
        result = false;
379
        if ( this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE)
Ken Martin's avatar
Ken Martin committed
380
          {
381
          cmSystemTools::SetFatalErrorOccured();
Ken Martin's avatar
Ken Martin committed
382
383
          }
        }
384
      else if(pcmd->HasFinalPass())
385
386
        {
        // use the command
387
        this->FinalPassCommands.push_back(pcmd.release());
388
        }
Ken Martin's avatar
Ken Martin committed
389
      }
390
    else if ( this->GetCMakeInstance()->GetWorkingMode() == cmake::SCRIPT_MODE
391
              && !pcmd->IsScriptable() )
392
      {
393
394
395
      std::string error = "Command ";
      error += pcmd->GetName();
      error += "() is not scriptable";
Bill Hoffman's avatar
Bill Hoffman committed
396
      this->IssueMessage(cmake::FATAL_ERROR, error);
397
398
399
      result = false;
      cmSystemTools::SetFatalErrorOccured();
      }
Ken Martin's avatar
Ken Martin committed
400
401
402
    }
  else
    {
403
404
    if(!cmSystemTools::GetFatalErrorOccured())
      {
405
406
407
      std::string error = "Unknown CMake command \"";
      error += lff.Name;
      error += "\".";
Bill Hoffman's avatar
Bill Hoffman committed
408
      this->IssueMessage(cmake::FATAL_ERROR, error);
409
      result = false;
410
      cmSystemTools::SetFatalErrorOccured();
411
      }
Ken Martin's avatar
Ken Martin committed
412
    }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
413

414
  return result;
Ken Martin's avatar
Ken Martin committed
415
416
}

Brad King's avatar
Brad King committed
417
418
419
420
//----------------------------------------------------------------------------
class cmMakefile::IncludeScope
{
public:
421
  IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope);
Brad King's avatar
Brad King committed
422
423
424
425
  ~IncludeScope();
  void Quiet() { this->ReportError = false; }
private:
  cmMakefile* Makefile;
426
427
428
  const char* File;
  bool NoPolicyScope;
  bool CheckCMP0011;
Brad King's avatar
Brad King committed
429
  bool ReportError;
430
  void EnforceCMP0011();
Brad King's avatar
Brad King committed
431
432
433
};

//----------------------------------------------------------------------------
434
435
436
437
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
438
{
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
  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
468
469
470
471
472
473
474
475
476
  // 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);
477
478
479
480
481
482
483

  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.
484
    if(this->CheckCMP0011 && this->Makefile->PolicyStack.back().IsEmpty())
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
      {
      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.
  switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
    {
    case cmPolicies::WARN:
      // Warn because the user did not set this policy.
      {
511
      std::ostringstream w;
Stephen Kelly's avatar
Stephen Kelly committed
512
      w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0011) << "\n"
513
514
515
516
517
518
519
520
521
522
        << "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:
      {
523
      std::ostringstream e;
Stephen Kelly's avatar
Stephen Kelly committed
524
      e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0011) << "\n"
525
526
527
528
529
530
531
532
533
534
535
536
        << "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
537
538
}

539
540
bool cmMakefile::ProcessBuildsystemFile(const char* listfile)
{
541
  this->AddDefinition("CMAKE_PARENT_LIST_FILE", listfile);
542
  std::string curSrc = this->GetCurrentSourceDirectory();
543
  return this->ReadListFile(listfile, true,
544
                            curSrc == this->GetHomeDirectory());
545
546
}

547
548
bool cmMakefile::ReadDependentFile(const char* listfile, bool noPolicyScope)
{
549
550
  this->AddDefinition("CMAKE_PARENT_LIST_FILE",
                      this->GetDefinition("CMAKE_CURRENT_LIST_FILE"));
551
552
553
554
555
556
  return this->ReadListFile(listfile, noPolicyScope, false);
}

bool cmMakefile::ReadListFile(const char* listfile)
{
  return this->ReadListFile(listfile, true, false);
557
558
}

559
bool cmMakefile::ReadListFile(const char* listfile,
560
561
                              bool noPolicyScope,
                              bool requireProjectCommand)
562
{
563
564
  std::string filenametoread =
    cmSystemTools::CollapseFullPath(listfile,
565
                                    this->GetCurrentSourceDirectory());
566

567
568
569
570
571
  std::string currentParentFile
      = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
  std::string currentFile
    = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");

572
573
574
575
  this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread.c_str());
  this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
                       cmSystemTools::GetFilenamePath(filenametoread).c_str());

576
  this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
577
578
579
580
  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");

  this->ListFileStack.push_back(filenametoread);
581

582
  bool res = this->ReadListFileInternal(filenametoread.c_str(),
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
                                        noPolicyScope, requireProjectCommand);

  this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
  this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
  this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
                      cmSystemTools::GetFilenamePath(currentFile).c_str());
  this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");

  this->ListFileStack.pop_back();

  if (res)
    {
    // Check for unused variables
    this->CheckForUnusedVariables();
    }

  return res;
}

bool cmMakefile::ReadListFileInternal(const char* filenametoread,
                                      bool noPolicyScope,
                                      bool requireProjectCommand)
{
608
  cmListFile cacheFile;
609
  if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
610
611
612
    {
    return false;
    }
613
  // add this list file to the list of dependencies
Ken Martin's avatar
Ken Martin committed
614
  this->ListFiles.push_back( filenametoread);
615
616
617
618

  // Enforce balanced blocks (if/endif, function/endfunction, etc.).
  {
  LexicalPushPop lexScope(this);
619
  IncludeScope incScope(this, filenametoread, noPolicyScope);
620
621

  // Run the parsed commands.
Ken Martin's avatar
Ken Martin committed
622
  const size_t numberFunctions = cacheFile.Functions.size();
623
  for(size_t i =0; i < numberFunctions; ++i)
624
    {
625
626
    cmExecutionStatus status;
    this->ExecuteCommand(cacheFile.Functions[i],status);
627
    if(cmSystemTools::GetFatalErrorOccured())
628
      {
629
630
      // Exit early due to error.
      lexScope.Quiet();
Brad King's avatar
Brad King committed
631
      incScope.Quiet();
632
633
634
635
636
      break;
      }
    if(status.GetReturnInvoked())
      {
      // Exit early due to return command.
637
      break;
638
      }
639
    }
640
  }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
641

642
643
  // If this is the directory-level CMakeLists.txt file then perform
  // some extra checks.
644
645
  if(this->ListFileStack.size() == 1)
    {
646
    this->EnforceDirectoryLevelRules();
647
648
    }

649
650
  return true;
}
651

652
//----------------------------------------------------------------------------
653
void cmMakefile::EnforceDirectoryLevelRules() const
654
655
656
657
{
  // Diagnose a violation of CMP0000 if necessary.
  if(this->CheckCMP0000)
    {
658
    std::ostringstream msg;
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
    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
675
        this->IssueMessage(cmake::AUTHOR_WARNING, msg.str());
676
677
678
679
680
681
682
683
      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
684
        this->IssueMessage(cmake::FATAL_ERROR, msg.str());
685
686
687
688
689
        cmSystemTools::SetFatalErrorOccured();
        return;
      }
    }
}
690

691
692
namespace
{
693
  struct file_not_persistent
694
695
  {
    bool operator()(const std::string& path) const
696
697
698
699
      {
      return !(path.find("CMakeTmp") == path.npos &&
               cmSystemTools::FileExists(path.c_str()));
      }
700
701
702
  };
}

703
void cmMakefile::FinalPass()
704
705
{
  // do all the variable expansions here
706
  this->ExpandVariablesCMP0019();
707

708
  // give all the commands a chance to do something
709
  // after the file has been parsed before generation
710
711
  for(std::vector<cmCommand*>::iterator i = this->FinalPassCommands.begin();
      i != this->FinalPassCommands.end(); ++i)
712
713
    {
    (*i)->FinalPass();
714
    }
715

716
717
718
719
720
721
722
  //go through all configured files and see which ones still exist.
  //we don't want cmake to re-run if a configured file is created and deleted
  //during processing as that would make it a transient file that can't
  //influence the build process

  //remove_if will move all items that don't have a valid file name to the
  //back of the vector
723
724
725
726
  std::vector<std::string>::iterator new_output_files_end = std::remove_if(
                                                     this->OutputFiles.begin(),
                                                     this->OutputFiles.end(),
                                                     file_not_persistent() );
727
  //we just have to erase all items at the back
728
729
730
731
732
733
734
735
736
  this->OutputFiles.erase(new_output_files_end, this->OutputFiles.end() );

  //if a configured file is used as input for another configured file,
  //and then deleted it will show up in the input list files so we
  //need to scan those too
  std::vector<std::string>::iterator new_list_files_end = std::remove_if(
                                                   this->ListFiles.begin(),
                                                   this->ListFiles.end(),
                                                   file_not_persistent() );
737

738
  this->ListFiles.erase(new_list_files_end, this->ListFiles.end() );
739
740
}

Bill Hoffman's avatar
Bill Hoffman committed
741
// Generate the output file
742
void cmMakefile::ConfigureFinalPass()
743
744
{
  this->FinalPass();
745
746
  const char* oldValue
    = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
747
748
  if (oldValue && cmSystemTools::VersionCompare(
        cmSystemTools::OP_LESS, oldValue, "2.4"))
749
    {
750
751
752
753
754
755
    this->IssueMessage(
      cmake::FATAL_ERROR,
      "You have set CMAKE_BACKWARDS_COMPATIBILITY to a CMake version less "
      "than 2.4. This version of CMake only supports backwards compatibility "
      "with CMake 2.4 or later. For compatibility with older versions please "
      "use any CMake 2.8.x release or lower.");
756
    }
Ken Martin's avatar
Ken Martin committed
757
758
  for (cmTargets::iterator l = this->Targets.begin();
       l != this->Targets.end(); l++)
759
    {
760
761
762
763
    if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
      {
      continue;
      }
764
    l->second.FinishConfigure();
765
    }
766
767
}

768
769
//----------------------------------------------------------------------------
void
770
cmMakefile::AddCustomCommandToTarget(const std::string& target,
771
                                   const std::vector<std::string>& byproducts,
772
773
774
                                     const std::vector<std::string>& depends,
                                     const cmCustomCommandLines& commandLines,
                                     cmTarget::CustomCommandType type,
775
                                     const char* comment,
776
                                     const char* workingDir,
777
                                     bool escapeOldStyle,
778
                                     bool uses_terminal)
779
{
780
  // Find the target to which to add the custom command.
Ken Martin's avatar
Ken Martin committed
781
  cmTargets::iterator ti = this->Targets.find(target);
782
783

  if(ti == this->Targets.end())
784
    {
785
786
    cmake::MessageType messageType = cmake::AUTHOR_WARNING;
    bool issueMessage = false;
787
    std::ostringstream e;
788
    switch(this->GetPolicyStatus(cmPolicies::CMP0040))
Brad King's avatar
Brad King committed
789
      {
790
      case cmPolicies::WARN:
Stephen Kelly's avatar
Stephen Kelly committed
791
        e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0040) << "\n";
792
793
794
795
796
797
798
799
        issueMessage = true;
      case cmPolicies::OLD:
        break;
      case cmPolicies::NEW:
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
        issueMessage = true;
        messageType = cmake::FATAL_ERROR;
Brad King's avatar
Brad King committed
800
      }
801
802

    if(issueMessage)
803
      {
804
      e << "The target name \"" << target << "\" is unknown in this context.";
Stephen Kelly's avatar
Stephen Kelly committed
805
      IssueMessage(messageType, e.str());
806
      }
807
808
809
810
811
812

      return;
    }

  if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY)
    {
813
    std::ostringstream e;
814
815
816
817
818
    e << "Target \"" << target << "\" is an OBJECT library "
      "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
    this->IssueMessage(cmake::FATAL_ERROR, e.str());
    return;
    }
819
820
  if(ti->second.GetType() == cmTarget::INTERFACE_LIBRARY)
    {
821
    std::ostringstream e;
822
823
824
825
826
    e << "Target \"" << target << "\" is an INTERFACE library "
      "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
    this->IssueMessage(cmake::FATAL_ERROR, e.str());
    return;
    }
827
828
829
830
831
832
833
834
835
836
837

  // Always create the byproduct sources and mark them generated.
  for(std::vector<std::string>::const_iterator o = byproducts.begin();
      o != byproducts.end(); ++o)
    {
    if(cmSourceFile* out = this->GetOrCreateSource(*o, true))
      {
      out->SetProperty("GENERATED", "1");
      }
    }

838
839
  // Add the command to the appropriate build step for the target.
  std::vector<std::string> no_output;
840
  cmCustomCommand cc(this, no_output, byproducts, depends,
841
842
843
                     commandLines, comment, workingDir);
  cc.SetEscapeOldStyle(escapeOldStyle);
  cc.SetEscapeAllowMakeVars(true);
844
  cc.SetUsesTerminal(uses_terminal);
845
846
847
848
849
850
851
852
853
854
855
  switch(type)
    {
    case cmTarget::PRE_BUILD:
      ti->second.AddPreBuildCommand(cc);
      break;
    case cmTarget::PRE_LINK:
      ti->second.AddPreLinkCommand(cc);
      break;
    case cmTarget::POST_BUILD:
      ti->second.AddPostBuildCommand(cc);
      break;
856
857
858
    }
}

859
//----------------------------------------------------------------------------
860
cmSourceFile*
861
cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
862
                                  const std::vector<std::string>& byproducts,
863
                                     const std::vector<std::string>& depends,
864
                                     const std::string& main_dependency,
865
866
                                     const cmCustomCommandLines& commandLines,
                                     const char* comment,
867
                                     const char* workingDir,
868
                                     bool replace,
869
870
                                     bool escapeOldStyle,
                                     bool uses_terminal)
871
{
872
873
874
875
  // Make sure there is at least one output.
  if(outputs.empty())
    {
    cmSystemTools::Error("Attempt to add a custom rule with no output!");
876
    return 0;
877
878
    }

879
880
881
882
883
884
885
  // Validate custom commands.  TODO: More strict?
  for(cmCustomCommandLines::const_iterator i=commandLines.begin();
      i != commandLines.end(); ++i)
    {
    cmCustomCommandLine const& cl = *i;
    if(!cl.empty() && !cl[0].empty() && cl[0][0] == '"')
      {
886
      std::ostringstream e;
887
888
      e << "COMMAND may not contain literal quotes:\n  " << cl[0] << "\n";
      this->IssueMessage(cmake::FATAL_ERROR, e.str());
889
      return 0;
890
891
892
      }
    }

893
894
  // Choose a source file on which to store the custom command.
  cmSourceFile* file = 0;
895
  if(!commandLines.empty() && !main_dependency.empty())
896
897
898
899
900
    {
    // The main dependency was specified.  Use it unless a different
    // custom command already used it.
    file = this->GetSource(main_dependency);
    if(file && file->GetCustomCommand() && !replace)
901
      {
902
903
      // The main dependency already has a custom command.
      if(commandLines == file->GetCustomCommand()->GetCommandLines())
904
        {
905
906
        // The existing custom command is identical.  Silently ignore
        // the duplicate.
907
        return file;
908
909
910
        }
      else
        {
911
912
913
        // The existing custom command is different.  We need to
        // generate a rule file for this new command.
        file = 0;
914
        }
915
      }
916
    else if (!file)
917
      {
918
      file = this->CreateSource(main_dependency);
919
920
921
      }
    }

922
923
  // Generate a rule file if the main dependency is not available.
  if(!file)
924
    {
925
    cmGlobalGenerator* gg = this->GetGlobalGenerator();
926

927
    // Construct a rule file associated with the first output produced.
928
929
    std::string outName = gg->GenerateRuleFile(outputs[0]);

930
    // Check if the rule file already exists.
Stephen Kelly's avatar
Stephen Kelly committed
931
    file = this->GetSource(outName);
932
    if(file && file->GetCustomCommand() && !replace)
933
      {
934
935
      // The rule file already exists.
      if(commandLines != file->GetCustomCommand()->GetCommandLines())
936
        {
937
        cmSystemTools::Error("Attempt to add a custom rule to output \"",
938
939
                             outName.c_str(),
                             "\" which already has a custom rule.");
940
        }
941
      return file;
942
      }
943
944

    // Create a cmSourceFile for the rule file.
945
946
947
948
    if (!file)
      {
      file = this->CreateSource(outName, true);
      }
949
    file->SetProperty("__CMAKE_RULE", "1");
950
    }
951

952
953
954
  // Always create the output sources and mark them generated.
  for(std::vector<std::string>::const_iterator o = outputs.begin();
      o != outputs.end(); ++o)