1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmMakefile.h"
13 #include "cmVersion.h"
14 #include "cmCommand.h"
15 #include "cmSourceFile.h"
16 #include "cmSourceFileLocation.h"
17 #include "cmSystemTools.h"
18 #include "cmGlobalGenerator.h"
19 #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 "cmDocumentCompileDefinitions.h"
27 #ifdef CMAKE_BUILD_WITH_CMAKE
28 # include "cmVariableWatch.h"
30 #include "cmInstallGenerator.h"
31 #include "cmTestGenerator.h"
32 #include "cmDefinitions.h"
34 #include <stdlib.h> // required for atoi
36 #include <cmsys/RegularExpression.hxx>
38 #include <cmsys/auto_ptr.hxx>
41 #include <ctype.h> // for isspace
43 class cmMakefile::Internals
46 std::stack<cmDefinitions, std::list<cmDefinitions> > VarStack;
47 std::stack<std::set<cmStdString> > VarInitStack;
48 std::stack<std::set<cmStdString> > VarUsageStack;
51 // default is not to be building executables
52 cmMakefile::cmMakefile(): Internal(new Internals)
54 const cmDefinitions& defs = cmDefinitions();
55 const std::set<cmStdString> globalKeys = defs.LocalKeys();
56 this->Internal->VarStack.push(defs);
57 this->Internal->VarInitStack.push(globalKeys);
58 this->Internal->VarUsageStack.push(globalKeys);
60 // Initialize these first since AddDefaultDefinitions calls AddDefinition
61 this->WarnUnused = false;
62 this->CheckSystemVars = false;
64 // Setup the default include file regular expression (match everything).
65 this->IncludeFileRegularExpression = "^.*$";
66 // Setup the default include complaint regular expression (match nothing).
67 this->ComplainFileRegularExpression = "^$";
68 // Source and header file extensions that we can handle
70 // Set up a list of source and header extensions
71 // these are used to find files when the extension
73 // The "c" extension MUST precede the "C" extension.
74 this->SourceFileExtensions.push_back( "c" );
75 this->SourceFileExtensions.push_back( "C" );
77 this->SourceFileExtensions.push_back( "c++" );
78 this->SourceFileExtensions.push_back( "cc" );
79 this->SourceFileExtensions.push_back( "cpp" );
80 this->SourceFileExtensions.push_back( "cxx" );
81 this->SourceFileExtensions.push_back( "m" );
82 this->SourceFileExtensions.push_back( "M" );
83 this->SourceFileExtensions.push_back( "mm" );
85 this->HeaderFileExtensions.push_back( "h" );
86 this->HeaderFileExtensions.push_back( "hh" );
87 this->HeaderFileExtensions.push_back( "h++" );
88 this->HeaderFileExtensions.push_back( "hm" );
89 this->HeaderFileExtensions.push_back( "hpp" );
90 this->HeaderFileExtensions.push_back( "hxx" );
91 this->HeaderFileExtensions.push_back( "in" );
92 this->HeaderFileExtensions.push_back( "txx" );
94 this->DefineFlags = " ";
95 this->LocalGenerator = 0;
97 this->AddDefaultDefinitions();
99 this->PreOrder = false;
102 cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals)
104 this->Internal->VarStack.push(mf.Internal->VarStack.top().Closure());
105 this->Internal->VarInitStack.push(mf.Internal->VarInitStack.top());
106 this->Internal->VarUsageStack.push(mf.Internal->VarUsageStack.top());
108 this->Prefix = mf.Prefix;
109 this->AuxSourceDirectories = mf.AuxSourceDirectories;
110 this->cmStartDirectory = mf.cmStartDirectory;
111 this->StartOutputDirectory = mf.StartOutputDirectory;
112 this->cmHomeDirectory = mf.cmHomeDirectory;
113 this->HomeOutputDirectory = mf.HomeOutputDirectory;
114 this->cmCurrentListFile = mf.cmCurrentListFile;
115 this->ProjectName = mf.ProjectName;
116 this->Targets = mf.Targets;
117 this->SourceFiles = mf.SourceFiles;
118 this->Tests = mf.Tests;
119 this->LinkDirectories = mf.LinkDirectories;
120 this->SystemIncludeDirectories = mf.SystemIncludeDirectories;
121 this->ListFiles = mf.ListFiles;
122 this->OutputFiles = mf.OutputFiles;
123 this->LinkLibraries = mf.LinkLibraries;
124 this->InstallGenerators = mf.InstallGenerators;
125 this->TestGenerators = mf.TestGenerators;
126 this->IncludeFileRegularExpression = mf.IncludeFileRegularExpression;
127 this->ComplainFileRegularExpression = mf.ComplainFileRegularExpression;
128 this->SourceFileExtensions = mf.SourceFileExtensions;
129 this->HeaderFileExtensions = mf.HeaderFileExtensions;
130 this->DefineFlags = mf.DefineFlags;
131 this->DefineFlagsOrig = mf.DefineFlagsOrig;
133 #if defined(CMAKE_BUILD_WITH_CMAKE)
134 this->SourceGroups = mf.SourceGroups;
137 this->LocalGenerator = mf.LocalGenerator;
138 this->FunctionBlockers = mf.FunctionBlockers;
139 this->MacrosMap = mf.MacrosMap;
140 this->SubDirectoryOrder = mf.SubDirectoryOrder;
141 this->Properties = mf.Properties;
142 this->PreOrder = mf.PreOrder;
143 this->WarnUnused = mf.WarnUnused;
145 this->CheckSystemVars = mf.CheckSystemVars;
146 this->ListFileStack = mf.ListFileStack;
149 //----------------------------------------------------------------------------
150 void cmMakefile::Initialize()
152 this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
153 this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
154 this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
156 // Enter a policy level for this directory.
159 // Protect the directory-level policies.
160 this->PushPolicyBarrier();
162 // By default the check is not done. It is enabled by
163 // cmListFileCache in the top level if necessary.
164 this->CheckCMP0000 = false;
167 unsigned int cmMakefile::GetCacheMajorVersion()
169 return this->GetCacheManager()->GetCacheMajorVersion();
172 unsigned int cmMakefile::GetCacheMinorVersion()
174 return this->GetCacheManager()->GetCacheMinorVersion();
177 bool cmMakefile::NeedCacheCompatibility(int major, int minor)
179 return this->GetCacheManager()->NeedCacheCompatibility(major, minor);
182 cmMakefile::~cmMakefile()
184 for(std::vector<cmInstallGenerator*>::iterator
185 i = this->InstallGenerators.begin();
186 i != this->InstallGenerators.end(); ++i)
190 for(std::vector<cmTestGenerator*>::iterator
191 i = this->TestGenerators.begin();
192 i != this->TestGenerators.end(); ++i)
196 for(std::vector<cmSourceFile*>::iterator i = this->SourceFiles.begin();
197 i != this->SourceFiles.end(); ++i)
201 for(std::map<cmStdString, cmTest*>::iterator i = this->Tests.begin();
202 i != this->Tests.end(); ++i)
206 for(std::vector<cmTarget*>::iterator
207 i = this->ImportedTargetsOwned.begin();
208 i != this->ImportedTargetsOwned.end(); ++i)
212 for(unsigned int i=0; i < this->FinalPassCommands.size(); i++)
214 delete this->FinalPassCommands[i];
216 std::vector<cmFunctionBlocker*>::iterator pos;
217 for (pos = this->FunctionBlockers.begin();
218 pos != this->FunctionBlockers.end(); ++pos)
220 cmFunctionBlocker* b = *pos;
223 this->FunctionBlockers.clear();
224 if (this->PolicyStack.size() != 1)
226 cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
231 void cmMakefile::PrintStringVector(const char* s,
232 const std::vector<std::string>& v) const
234 std::cout << s << ": ( \n";
235 for(std::vector<std::string>::const_iterator i = v.begin();
238 std::cout << (*i).c_str() << " ";
244 ::PrintStringVector(const char* s,
245 const std::vector<std::pair<cmStdString, bool> >& v) const
247 std::cout << s << ": ( \n";
248 for(std::vector<std::pair<cmStdString, bool> >::const_iterator i
249 = v.begin(); i != v.end(); ++i)
251 std::cout << i->first.c_str() << " " << i->second;
257 // call print on all the classes in the makefile
258 void cmMakefile::Print()
260 // print the class lists
261 std::cout << "classes:\n";
263 std::cout << " this->Targets: ";
264 for (cmTargets::iterator l = this->Targets.begin();
265 l != this->Targets.end(); l++)
267 std::cout << l->first << std::endl;
270 std::cout << " this->StartOutputDirectory; " <<
271 this->StartOutputDirectory.c_str() << std::endl;
272 std::cout << " this->HomeOutputDirectory; " <<
273 this->HomeOutputDirectory.c_str() << std::endl;
274 std::cout << " this->cmStartDirectory; " <<
275 this->cmStartDirectory.c_str() << std::endl;
276 std::cout << " this->cmHomeDirectory; " <<
277 this->cmHomeDirectory.c_str() << std::endl;
278 std::cout << " this->ProjectName; "
279 << this->ProjectName.c_str() << std::endl;
280 this->PrintStringVector("this->LinkDirectories", this->LinkDirectories);
281 #if defined(CMAKE_BUILD_WITH_CMAKE)
282 for( std::vector<cmSourceGroup>::const_iterator i =
283 this->SourceGroups.begin(); i != this->SourceGroups.end(); ++i)
285 std::cout << "Source Group: " << i->GetName() << std::endl;
290 bool cmMakefile::CommandExists(const char* name) const
292 return this->GetCMakeInstance()->CommandExists(name);
296 //----------------------------------------------------------------------------
297 void cmMakefile::IssueMessage(cmake::MessageType t,
298 std::string const& text) const
300 // Collect context information.
301 cmListFileBacktrace backtrace;
302 if(!this->CallStack.empty())
304 if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR))
306 this->CallStack.back().Status->SetNestedError(true);
308 this->GetBacktrace(backtrace);
312 cmListFileContext lfc;
313 if(this->ListFileStack.empty())
315 // We are not processing the project. Add the directory-level context.
316 lfc.FilePath = this->GetCurrentDirectory();
317 lfc.FilePath += "/CMakeLists.txt";
321 // We are processing the project but are not currently executing a
322 // command. Add whatever context information we have.
323 lfc.FilePath = this->ListFileStack.back();
326 if(!this->GetCMakeInstance()->GetIsInTryCompile())
328 lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath.c_str(),
329 cmLocalGenerator::HOME);
331 backtrace.push_back(lfc);
334 // Issue the message.
335 this->GetCMakeInstance()->IssueMessage(t, text, backtrace);
338 //----------------------------------------------------------------------------
339 bool cmMakefile::GetBacktrace(cmListFileBacktrace& backtrace) const
341 if(this->CallStack.empty())
345 for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
346 i != this->CallStack.rend(); ++i)
348 cmListFileContext lfc = *(*i).Context;
349 lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath.c_str(),
350 cmLocalGenerator::HOME);
351 backtrace.push_back(lfc);
356 //----------------------------------------------------------------------------
357 void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff)
360 msg << lff.FilePath << "(" << lff.Line << "): ";
361 msg << lff.Name << "(";
362 for(std::vector<cmListFileArgument>::const_iterator i =
363 lff.Arguments.begin(); i != lff.Arguments.end(); ++i)
369 cmSystemTools::Message(msg.str().c_str());
372 //----------------------------------------------------------------------------
373 bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
374 cmExecutionStatus &status)
378 // quick return if blocked
379 if(this->IsFunctionBlocked(lff,status))
385 std::string name = lff.Name;
387 // Place this call on the call stack.
388 cmMakefileCall stack_manager(this, lff, status);
389 static_cast<void>(stack_manager);
391 // Lookup the command prototype.
392 if(cmCommand* proto = this->GetCMakeInstance()->GetCommand(name.c_str()))
394 // Clone the prototype.
395 cmsys::auto_ptr<cmCommand> pcmd(proto->Clone());
396 pcmd->SetMakefile(this);
398 // Decide whether to invoke the command.
399 if(pcmd->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() &&
400 (this->GetCMakeInstance()->GetWorkingMode() != cmake::SCRIPT_MODE
401 || pcmd->IsScriptable()))
404 // if trace is enabled, print out invoke information
405 if(this->GetCMakeInstance()->GetTrace())
407 this->PrintCommandTrace(lff);
409 // Try invoking the command.
410 if(!pcmd->InvokeInitialPass(lff.Arguments,status) ||
411 status.GetNestedError())
413 if(!status.GetNestedError())
415 // The command invocation requested that we report an error.
416 this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError());
419 if ( this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE)
421 cmSystemTools::SetFatalErrorOccured();
424 else if(pcmd->HasFinalPass())
427 this->FinalPassCommands.push_back(pcmd.release());
430 else if ( this->GetCMakeInstance()->GetWorkingMode() == cmake::SCRIPT_MODE
431 && !pcmd->IsScriptable() )
433 std::string error = "Command ";
434 error += pcmd->GetName();
435 error += "() is not scriptable";
436 this->IssueMessage(cmake::FATAL_ERROR, error);
438 cmSystemTools::SetFatalErrorOccured();
443 if(!cmSystemTools::GetFatalErrorOccured())
445 std::string error = "Unknown CMake command \"";
448 this->IssueMessage(cmake::FATAL_ERROR, error);
450 cmSystemTools::SetFatalErrorOccured();
457 //----------------------------------------------------------------------------
458 class cmMakefile::IncludeScope
461 IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope);
463 void Quiet() { this->ReportError = false; }
465 cmMakefile* Makefile;
470 void EnforceCMP0011();
473 //----------------------------------------------------------------------------
474 cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
476 Makefile(mf), File(fname), NoPolicyScope(noPolicyScope),
477 CheckCMP0011(false), ReportError(true)
479 if(!this->NoPolicyScope)
481 // Check CMP0011 to determine the policy scope type.
482 switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
484 case cmPolicies::WARN:
485 // We need to push a scope to detect whether the script sets
486 // any policies that would affect the includer and therefore
487 // requires a warning. We use a weak scope to simulate OLD
488 // behavior by allowing policy changes to affect the includer.
489 this->Makefile->PushPolicy(true);
490 this->CheckCMP0011 = true;
492 case cmPolicies::OLD:
493 // OLD behavior is to not push a scope at all.
494 this->NoPolicyScope = true;
496 case cmPolicies::REQUIRED_IF_USED:
497 case cmPolicies::REQUIRED_ALWAYS:
498 // We should never make this policy required, but we handle it
499 // here just in case.
500 this->CheckCMP0011 = true;
501 case cmPolicies::NEW:
502 // NEW behavior is to push a (strong) scope.
503 this->Makefile->PushPolicy();
508 // The included file cannot pop our policy scope.
509 this->Makefile->PushPolicyBarrier();
512 //----------------------------------------------------------------------------
513 cmMakefile::IncludeScope::~IncludeScope()
515 // Enforce matching policy scopes inside the included file.
516 this->Makefile->PopPolicyBarrier(this->ReportError);
518 if(!this->NoPolicyScope)
520 // If we need to enforce policy CMP0011 then the top entry is the
521 // one we pushed above. If the entry is empty, then the included
522 // script did not set any policies that might affect the includer so
523 // we do not need to enforce the policy.
524 if(this->CheckCMP0011 && this->Makefile->PolicyStack.back().empty())
526 this->CheckCMP0011 = false;
529 // Pop the scope we pushed for the script.
530 this->Makefile->PopPolicy();
532 // We enforce the policy after the script's policy stack entry has
534 if(this->CheckCMP0011)
536 this->EnforceCMP0011();
541 //----------------------------------------------------------------------------
542 void cmMakefile::IncludeScope::EnforceCMP0011()
544 // We check the setting of this policy again because the included
545 // script might actually set this policy for its includer.
546 cmPolicies* policies = this->Makefile->GetPolicies();
547 switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
549 case cmPolicies::WARN:
550 // Warn because the user did not set this policy.
553 w << policies->GetPolicyWarning(cmPolicies::CMP0011) << "\n"
554 << "The included script\n " << this->File << "\n"
555 << "affects policy settings. "
556 << "CMake is implying the NO_POLICY_SCOPE option for compatibility, "
557 << "so the effects are applied to the including context.";
558 this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
561 case cmPolicies::REQUIRED_IF_USED:
562 case cmPolicies::REQUIRED_ALWAYS:
565 e << policies->GetRequiredPolicyError(cmPolicies::CMP0011) << "\n"
566 << "The included script\n " << this->File << "\n"
567 << "affects policy settings, so it requires this policy to be set.";
568 this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
571 case cmPolicies::OLD:
572 case cmPolicies::NEW:
573 // The script set this policy. We assume the purpose of the
574 // script is to initialize policies for its includer, and since
575 // the policy is now set for later scripts, we do not warn.
580 //----------------------------------------------------------------------------
581 // Parse the given CMakeLists.txt file executing all commands
583 bool cmMakefile::ReadListFile(const char* filename_in,
584 const char *external_in,
585 std::string* fullPath,
588 std::string currentParentFile
589 = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
590 std::string currentFile
591 = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
592 this->AddDefinition("CMAKE_PARENT_LIST_FILE", filename_in);
593 this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
595 const char* external = 0;
596 std::string external_abs;
598 const char* filename = filename_in;
599 std::string filename_abs;
604 cmSystemTools::CollapseFullPath(external_in,
605 this->cmStartDirectory.c_str());
606 external = external_abs.c_str();
610 cmSystemTools::CollapseFullPath(filename_in,
611 this->cmStartDirectory.c_str());
612 filename = filename_abs.c_str();
616 // keep track of the current file being read
619 if(this->cmCurrentListFile != filename)
621 this->cmCurrentListFile = filename;
625 // Now read the input file
626 const char *filenametoread= filename;
630 filenametoread= external;
633 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
634 this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
635 this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
636 cmSystemTools::GetFilenamePath(filenametoread).c_str());
637 this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
639 // try to see if the list file is the top most
640 // list file for a project, and if it is, then it
641 // must have a project command. If there is not
642 // one, then cmake will provide one via the
643 // cmListFileCache class.
644 bool requireProjectCommand = false;
645 if(!external && this->cmStartDirectory == this->cmHomeDirectory)
647 if(cmSystemTools::LowerCase(
648 cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt")
650 requireProjectCommand = true;
654 // push the listfile onto the stack
655 this->ListFileStack.push_back(filenametoread);
658 *fullPath=filenametoread;
660 cmListFile cacheFile;
661 if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
663 // pop the listfile off the stack
664 this->ListFileStack.pop_back();
669 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
670 this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
671 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
672 this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
673 this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
674 cmSystemTools::GetFilenamePath(currentFile).c_str());
675 this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
678 // add this list file to the list of dependencies
679 this->ListFiles.push_back( filenametoread);
681 // Enforce balanced blocks (if/endif, function/endfunction, etc.).
683 LexicalPushPop lexScope(this);
684 IncludeScope incScope(this, filenametoread, noPolicyScope);
686 // Run the parsed commands.
687 const size_t numberFunctions = cacheFile.Functions.size();
688 for(size_t i =0; i < numberFunctions; ++i)
690 cmExecutionStatus status;
691 this->ExecuteCommand(cacheFile.Functions[i],status);
692 if(cmSystemTools::GetFatalErrorOccured())
694 // Exit early due to error.
699 if(status.GetReturnInvoked())
701 // Exit early due to return command.
707 // If this is the directory-level CMakeLists.txt file then perform
708 // some extra checks.
709 if(this->ListFileStack.size() == 1)
711 this->EnforceDirectoryLevelRules();
714 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
715 this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
716 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
717 this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
718 this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
719 cmSystemTools::GetFilenamePath(currentFile).c_str());
720 this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
722 // pop the listfile off the stack
723 this->ListFileStack.pop_back();
725 // Check for unused variables
726 this->CheckForUnusedVariables();
731 //----------------------------------------------------------------------------
732 void cmMakefile::EnforceDirectoryLevelRules()
734 // Diagnose a violation of CMP0000 if necessary.
735 if(this->CheckCMP0000)
738 msg << "No cmake_minimum_required command is present. "
739 << "A line of code such as\n"
740 << " cmake_minimum_required(VERSION "
741 << cmVersion::GetMajorVersion() << "."
742 << cmVersion::GetMinorVersion()
744 << "should be added at the top of the file. "
745 << "The version specified may be lower if you wish to "
746 << "support older CMake versions for this project. "
747 << "For more information run "
748 << "\"cmake --help-policy CMP0000\".";
749 switch (this->GetPolicyStatus(cmPolicies::CMP0000))
751 case cmPolicies::WARN:
752 // Warn because the user did not provide a mimimum required
754 this->IssueMessage(cmake::AUTHOR_WARNING, msg.str().c_str());
755 case cmPolicies::OLD:
756 // OLD behavior is to use policy version 2.4 set in
759 case cmPolicies::REQUIRED_IF_USED:
760 case cmPolicies::REQUIRED_ALWAYS:
761 case cmPolicies::NEW:
762 // NEW behavior is to issue an error.
763 this->IssueMessage(cmake::FATAL_ERROR, msg.str().c_str());
764 cmSystemTools::SetFatalErrorOccured();
770 void cmMakefile::AddCommand(cmCommand* wg)
772 this->GetCMakeInstance()->AddCommand(wg);
776 void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
778 this->LocalGenerator = lg;
779 // the source groups need to access the global generator
780 // so don't create them until the lg is set
781 #if defined(CMAKE_BUILD_WITH_CMAKE)
782 this->AddSourceGroup("", "^.*$");
785 "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|f|f90|for|fpp"
786 "|ftn|m|mm|rc|def|r|odl|idl|hpj|bat)$");
787 this->AddSourceGroup("Header Files", CM_HEADER_REGEX);
788 this->AddSourceGroup("CMake Rules", "\\.rule$");
789 this->AddSourceGroup("Resources", "\\.plist$");
790 this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$");
793 this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
794 this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars();
797 bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
801 if(this->LocalGenerator)
804 this->LocalGenerator->NeedBackwardsCompatibility(major, minor, patch);
812 void cmMakefile::FinalPass()
814 // do all the variable expansions here
815 this->ExpandVariables();
817 // give all the commands a chance to do something
818 // after the file has been parsed before generation
819 for(std::vector<cmCommand*>::iterator i = this->FinalPassCommands.begin();
820 i != this->FinalPassCommands.end(); ++i)
827 // Generate the output file
828 void cmMakefile::ConfigureFinalPass()
832 = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
833 if (oldValue && atof(oldValue) <= 1.2)
835 cmSystemTools::Error("You have requested backwards compatibility "
836 "with CMake version 1.2 or earlier. This version "
837 "of CMake only supports backwards compatibility "
838 "with CMake 1.4 or later. For compatibility with "
839 "1.2 or earlier please use CMake 2.0");
841 for (cmTargets::iterator l = this->Targets.begin();
842 l != this->Targets.end(); l++)
844 l->second.FinishConfigure();
848 //----------------------------------------------------------------------------
850 cmMakefile::AddCustomCommandToTarget(const char* target,
851 const std::vector<std::string>& depends,
852 const cmCustomCommandLines& commandLines,
853 cmTarget::CustomCommandType type,
855 const char* workingDir,
858 // Find the target to which to add the custom command.
859 cmTargets::iterator ti = this->Targets.find(target);
860 if(ti != this->Targets.end())
862 if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY)
865 e << "Target \"" << target << "\" is an OBJECT library "
866 "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
867 this->IssueMessage(cmake::FATAL_ERROR, e.str());
870 // Add the command to the appropriate build step for the target.
871 std::vector<std::string> no_output;
872 cmCustomCommand cc(this, no_output, depends,
873 commandLines, comment, workingDir);
874 cc.SetEscapeOldStyle(escapeOldStyle);
875 cc.SetEscapeAllowMakeVars(true);
878 case cmTarget::PRE_BUILD:
879 ti->second.GetPreBuildCommands().push_back(cc);
881 case cmTarget::PRE_LINK:
882 ti->second.GetPreLinkCommands().push_back(cc);
884 case cmTarget::POST_BUILD:
885 ti->second.GetPostBuildCommands().push_back(cc);
891 //----------------------------------------------------------------------------
893 cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
894 const std::vector<std::string>& depends,
895 const char* main_dependency,
896 const cmCustomCommandLines& commandLines,
898 const char* workingDir,
902 // Make sure there is at least one output.
905 cmSystemTools::Error("Attempt to add a custom rule with no output!");
909 // Validate custom commands. TODO: More strict?
910 for(cmCustomCommandLines::const_iterator i=commandLines.begin();
911 i != commandLines.end(); ++i)
913 cmCustomCommandLine const& cl = *i;
914 if(!cl.empty() && !cl[0].empty() && cl[0][0] == '"')
917 e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n";
918 this->IssueMessage(cmake::FATAL_ERROR, e.str());
923 // Choose a source file on which to store the custom command.
924 cmSourceFile* file = 0;
925 if(main_dependency && main_dependency[0])
927 // The main dependency was specified. Use it unless a different
928 // custom command already used it.
929 file = this->GetSource(main_dependency);
930 if(file && file->GetCustomCommand() && !replace)
932 // The main dependency already has a custom command.
933 if(commandLines == file->GetCustomCommand()->GetCommandLines())
935 // The existing custom command is identical. Silently ignore
941 // The existing custom command is different. We need to
942 // generate a rule file for this new command.
948 // The main dependency does not have a custom command or we are
949 // allowed to replace it. Use it to store the command.
950 file = this->GetOrCreateSource(main_dependency);
954 // Generate a rule file if the main dependency is not available.
957 cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
959 // Construct a rule file associated with the first output produced.
960 std::string outName = gg->GenerateRuleFile(outputs[0]);
962 // Check if the rule file already exists.
963 file = this->GetSource(outName.c_str());
964 if(file && file->GetCustomCommand() && !replace)
966 // The rule file already exists.
967 if(commandLines != file->GetCustomCommand()->GetCommandLines())
969 cmSystemTools::Error("Attempt to add a custom rule to output \"",
971 "\" which already has a custom rule.");
976 // Create a cmSourceFile for the rule file.
977 file = this->GetOrCreateSource(outName.c_str(), true);
978 file->SetProperty("__CMAKE_RULE", "1");
981 // Always create the output sources and mark them generated.
982 for(std::vector<std::string>::const_iterator o = outputs.begin();
983 o != outputs.end(); ++o)
985 if(cmSourceFile* out = this->GetOrCreateSource(o->c_str(), true))
987 out->SetProperty("GENERATED", "1");
991 // Construct a complete list of dependencies.
992 std::vector<std::string> depends2(depends);
993 if(main_dependency && main_dependency[0])
995 depends2.push_back(main_dependency);
998 // Attach the custom command to the file.
1001 cmCustomCommand* cc =
1002 new cmCustomCommand(this, outputs, depends2, commandLines,
1003 comment, workingDir);
1004 cc->SetEscapeOldStyle(escapeOldStyle);
1005 cc->SetEscapeAllowMakeVars(true);
1006 file->SetCustomCommand(cc);
1011 //----------------------------------------------------------------------------
1013 cmMakefile::AddCustomCommandToOutput(const char* output,
1014 const std::vector<std::string>& depends,
1015 const char* main_dependency,
1016 const cmCustomCommandLines& commandLines,
1017 const char* comment,
1018 const char* workingDir,
1020 bool escapeOldStyle)
1022 std::vector<std::string> outputs;
1023 outputs.push_back(output);
1024 return this->AddCustomCommandToOutput(outputs, depends, main_dependency,
1025 commandLines, comment, workingDir,
1026 replace, escapeOldStyle);
1029 //----------------------------------------------------------------------------
1031 cmMakefile::AddCustomCommandOldStyle(const char* target,
1032 const std::vector<std::string>& outputs,
1033 const std::vector<std::string>& depends,
1035 const cmCustomCommandLines& commandLines,
1036 const char* comment)
1038 // Translate the old-style signature to one of the new-style
1040 if(strcmp(source, target) == 0)
1042 // In the old-style signature if the source and target were the
1043 // same then it added a post-build rule to the target. Preserve
1045 this->AddCustomCommandToTarget(target, depends, commandLines,
1046 cmTarget::POST_BUILD, comment, 0);
1050 // Each output must get its own copy of this rule.
1051 cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|"
1052 "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
1053 "hm|hpp|hxx|in|txx|inl)$");
1054 for(std::vector<std::string>::const_iterator oi = outputs.begin();
1055 oi != outputs.end(); ++oi)
1057 // Get the name of this output.
1058 const char* output = oi->c_str();
1061 // Choose whether to use a main dependency.
1062 if(sourceFiles.find(source))
1064 // The source looks like a real file. Use it as the main dependency.
1065 sf = this->AddCustomCommandToOutput(output, depends, source,
1066 commandLines, comment, 0);
1070 // The source may not be a real file. Do not use a main dependency.
1071 const char* no_main_dependency = 0;
1072 std::vector<std::string> depends2 = depends;
1073 depends2.push_back(source);
1074 sf = this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
1075 commandLines, comment, 0);
1078 // If the rule was added to the source (and not a .rule file),
1079 // then add the source to the target to make sure the rule is
1081 if(sf && !sf->GetPropertyAsBool("__CMAKE_RULE"))
1083 if (this->Targets.find(target) != this->Targets.end())
1085 this->Targets[target].AddSourceFile(sf);
1089 cmSystemTools::Error("Attempt to add a custom rule to a target "
1090 "that does not exist yet for target ", target);
1097 //----------------------------------------------------------------------------
1098 void cmMakefile::AddUtilityCommand(const char* utilityName,
1099 bool excludeFromAll,
1100 const std::vector<std::string>& depends,
1101 const char* workingDirectory,
1102 const char* command,
1108 // Construct the command line for the custom command.
1109 cmCustomCommandLine commandLine;
1110 commandLine.push_back(command);
1113 commandLine.push_back(arg1);
1117 commandLine.push_back(arg2);
1121 commandLine.push_back(arg3);
1125 commandLine.push_back(arg4);
1127 cmCustomCommandLines commandLines;
1128 commandLines.push_back(commandLine);
1130 // Call the real signature of this method.
1131 this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
1132 depends, commandLines);
1135 //----------------------------------------------------------------------------
1137 cmMakefile::AddUtilityCommand(const char* utilityName,
1138 bool excludeFromAll,
1139 const char* workingDirectory,
1140 const std::vector<std::string>& depends,
1141 const cmCustomCommandLines& commandLines,
1142 bool escapeOldStyle, const char* comment)
1144 // Create a target instance for this utility.
1145 cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
1148 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1152 // Use an empty comment to avoid generation of default comment.
1156 // Store the custom command in the target.
1157 std::string force = this->GetStartOutputDirectory();
1158 force += cmake::GetCMakeFilesDirectory();
1160 force += utilityName;
1161 const char* no_main_dependency = 0;
1162 bool no_replace = false;
1163 this->AddCustomCommandToOutput(force.c_str(), depends,
1165 commandLines, comment,
1166 workingDirectory, no_replace,
1168 cmSourceFile* sf = target->AddSource(force.c_str());
1170 // The output is not actually created so mark it symbolic.
1173 sf->SetProperty("SYMBOLIC", "1");
1177 cmSystemTools::Error("Could not get source file entry for ",
1183 void cmMakefile::AddDefineFlag(const char* flag)
1190 // Update the string used for the old DEFINITIONS property.
1191 this->AddDefineFlag(flag, this->DefineFlagsOrig);
1193 // If this is really a definition, update COMPILE_DEFINITIONS.
1194 if(this->ParseDefineFlag(flag, false))
1199 // Add this flag that does not look like a definition.
1200 this->AddDefineFlag(flag, this->DefineFlags);
1203 void cmMakefile::AddDefineFlag(const char* flag, std::string& dflags)
1206 std::string ret = flag;
1207 std::string::size_type pos = 0;
1208 while((pos = ret.find('\n', pos)) != std::string::npos)
1214 while((pos = ret.find('\r', pos)) != std::string::npos)
1225 void cmMakefile::RemoveDefineFlag(const char* flag)
1227 // Check the length of the flag to remove.
1228 std::string::size_type len = strlen(flag);
1234 // Update the string used for the old DEFINITIONS property.
1235 this->RemoveDefineFlag(flag, len, this->DefineFlagsOrig);
1237 // If this is really a definition, update COMPILE_DEFINITIONS.
1238 if(this->ParseDefineFlag(flag, true))
1243 // Remove this flag that does not look like a definition.
1244 this->RemoveDefineFlag(flag, len, this->DefineFlags);
1247 void cmMakefile::RemoveDefineFlag(const char* flag,
1248 std::string::size_type len,
1249 std::string& dflags)
1251 // Remove all instances of the flag that are surrounded by
1252 // whitespace or the beginning/end of the string.
1253 for(std::string::size_type lpos = dflags.find(flag, 0);
1254 lpos != std::string::npos; lpos = dflags.find(flag, lpos))
1256 std::string::size_type rpos = lpos + len;
1257 if((lpos <= 0 || isspace(dflags[lpos-1])) &&
1258 (rpos >= dflags.size() || isspace(dflags[rpos])))
1260 dflags.erase(lpos, len);
1269 bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
1271 // Create a regular expression to match valid definitions.
1272 static cmsys::RegularExpression
1273 valid("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=.*)?$");
1275 // Make sure the definition matches.
1276 if(!valid.find(def.c_str()))
1281 // VS6 IDE does not support definition values with spaces in
1282 // combination with '"', '$', or ';'.
1283 if((strcmp(this->LocalGenerator->GetGlobalGenerator()->GetName(),
1284 "Visual Studio 6") == 0) &&
1285 (def.find(" ") != def.npos && def.find_first_of("\"$;") != def.npos))
1290 // Definitions with non-trivial values require a policy check.
1291 static cmsys::RegularExpression
1292 trivial("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=[A-Za-z0-9_.]+)?$");
1293 if(!trivial.find(def.c_str()))
1295 // This definition has a non-trivial value.
1296 switch(this->GetPolicyStatus(cmPolicies::CMP0005))
1298 case cmPolicies::WARN:
1300 cmake::AUTHOR_WARNING,
1301 this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0005)
1303 case cmPolicies::OLD:
1304 // OLD behavior is to not escape the value. We should not
1305 // convert the definition to use the property.
1307 case cmPolicies::REQUIRED_IF_USED:
1308 case cmPolicies::REQUIRED_ALWAYS:
1311 this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0005)
1314 case cmPolicies::NEW:
1315 // NEW behavior is to escape the value. Proceed to convert it
1316 // to an entry in the property.
1321 // Get the definition part after the flag.
1322 const char* define = def.c_str() + 2;
1326 if(const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS"))
1329 std::vector<std::string> defs;
1330 cmSystemTools::ExpandListArgument(cdefs, defs);
1332 // Recompose the list without the definition.
1334 const char* sep = "";
1335 for(std::vector<std::string>::const_iterator di = defs.begin();
1336 di != defs.end(); ++di)
1346 // Store the new list.
1347 this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
1352 // Append the definition to the directory property.
1353 this->AppendProperty("COMPILE_DEFINITIONS", define);
1359 void cmMakefile::AddLinkLibrary(const char* lib,
1360 cmTarget::LinkLibraryType llt)
1362 cmTarget::LibraryID tmp;
1365 this->LinkLibraries.push_back(tmp);
1368 void cmMakefile::AddLinkLibraryForTarget(const char *target,
1370 cmTarget::LinkLibraryType llt)
1372 cmTargets::iterator i = this->Targets.find(target);
1373 if ( i != this->Targets.end())
1376 this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib);
1379 // CMake versions below 2.4 allowed linking to modules.
1380 bool allowModules = this->NeedBackwardsCompatibility(2,2);
1381 // if it is not a static or shared library then you can not link to it
1382 if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
1383 (tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
1384 tgt->IsExecutableWithExports()))
1387 e << "Target \"" << lib << "\" of type "
1388 << cmTarget::GetTargetTypeName(tgt->GetType())
1389 << " may not be linked into another target. "
1390 << "One may link only to STATIC or SHARED libraries, or "
1391 << "to executables with the ENABLE_EXPORTS property set.";
1392 // in older versions of cmake linking to modules was allowed
1393 if( tgt->GetType() == cmTarget::MODULE_LIBRARY )
1396 << "If you are developing a new project, re-organize it to avoid "
1397 << "linking to modules. "
1398 << "If you are just trying to build an existing project, "
1399 << "set CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower to allow "
1400 << "linking to modules.";
1402 // if no modules are allowed then this is always an error
1404 // if we allow modules but the type is not a module then it is
1406 (allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY))
1408 this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
1412 i->second.AddLinkLibrary( *this, target, lib, llt );
1417 e << "Attempt to add link library \""
1418 << lib << "\" to target \""
1419 << target << "\" which is not built in this directory.";
1420 this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
1424 void cmMakefile::AddLinkDirectoryForTarget(const char *target,
1427 cmTargets::iterator i = this->Targets.find(target);
1428 if ( i != this->Targets.end())
1430 i->second.AddLinkDirectory( d );
1434 cmSystemTools::Error
1435 ("Attempt to add link directories to non-existant target: ",
1436 target, " for directory ", d);
1440 void cmMakefile::AddLinkLibrary(const char* lib)
1442 this->AddLinkLibrary(lib,cmTarget::GENERAL);
1445 void cmMakefile::AddLinkDirectory(const char* dir)
1447 // Don't add a link directory that is already present. Yes, this
1448 // linear search results in n^2 behavior, but n won't be getting
1449 // much bigger than 20. We cannot use a set because of order
1450 // dependency of the link search path.
1456 // remove trailing slashes
1457 if(dir[strlen(dir)-1] == '/')
1459 std::string newdir = dir;
1460 newdir = newdir.substr(0, newdir.size()-1);
1461 if(std::find(this->LinkDirectories.begin(),
1462 this->LinkDirectories.end(),
1463 newdir.c_str()) == this->LinkDirectories.end())
1465 this->LinkDirectories.push_back(newdir);
1470 if(std::find(this->LinkDirectories.begin(),
1471 this->LinkDirectories.end(), dir)
1472 == this->LinkDirectories.end())
1474 this->LinkDirectories.push_back(dir);
1479 void cmMakefile::InitializeFromParent()
1481 cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
1483 // Initialize definitions with the closure of the parent scope.
1484 this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure();
1486 // copy include paths
1487 this->SetProperty("INCLUDE_DIRECTORIES",
1488 parent->GetProperty("INCLUDE_DIRECTORIES"));
1489 this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
1492 this->DefineFlags = parent->DefineFlags;
1493 this->DefineFlagsOrig = parent->DefineFlagsOrig;
1495 // Include transform property. There is no per-config version.
1497 const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM";
1498 this->SetProperty(prop, parent->GetProperty(prop));
1501 // compile definitions property and per-config versions
1503 this->SetProperty("COMPILE_DEFINITIONS",
1504 parent->GetProperty("COMPILE_DEFINITIONS"));
1505 std::vector<std::string> configs;
1506 this->GetConfigurations(configs);
1507 for(std::vector<std::string>::const_iterator ci = configs.begin();
1508 ci != configs.end(); ++ci)
1510 std::string defPropName = "COMPILE_DEFINITIONS_";
1511 defPropName += cmSystemTools::UpperCase(*ci);
1512 this->SetProperty(defPropName.c_str(),
1513 parent->GetProperty(defPropName.c_str()));
1518 this->LinkLibraries = parent->LinkLibraries;
1521 this->LinkDirectories = parent->LinkDirectories;
1523 // the initial project name
1524 this->ProjectName = parent->ProjectName;
1526 // Copy include regular expressions.
1527 this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
1528 this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
1530 // Imported targets.
1531 this->ImportedTargets = parent->ImportedTargets;
1534 void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
1536 // copy our variables from the child makefile
1537 lg2->GetMakefile()->InitializeFromParent();
1538 lg2->GetMakefile()->MakeStartDirectoriesCurrent();
1539 if (this->GetCMakeInstance()->GetDebugOutput())
1541 std::string msg=" Entering ";
1542 msg += lg2->GetMakefile()->GetCurrentDirectory();
1543 cmSystemTools::Message(msg.c_str());
1545 // finally configure the subdir
1547 if (this->GetCMakeInstance()->GetDebugOutput())
1549 std::string msg=" Returning to ";
1550 msg += this->GetCurrentDirectory();
1551 cmSystemTools::Message(msg.c_str());
1555 void cmMakefile::AddSubDirectory(const char* sub,
1556 bool excludeFromAll, bool preorder)
1558 // the source path must be made full if it isn't already
1559 std::string srcPath = sub;
1560 if (!cmSystemTools::FileIsFullPath(srcPath.c_str()))
1562 srcPath = this->GetCurrentDirectory();
1567 // binary path must be made full if it isn't already
1568 std::string binPath = sub;
1569 if (!cmSystemTools::FileIsFullPath(binPath.c_str()))
1571 binPath = this->GetCurrentOutputDirectory();
1577 this->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
1578 excludeFromAll, preorder, false);
1582 void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
1583 bool excludeFromAll, bool preorder,
1586 // Make sure the binary directory is unique.
1587 if(!this->EnforceUniqueDir(srcPath, binPath))
1592 // create a new local generator and set its parent
1593 cmLocalGenerator *lg2 =
1594 this->LocalGenerator->GetGlobalGenerator()->CreateLocalGenerator();
1595 lg2->SetParent(this->LocalGenerator);
1596 this->LocalGenerator->GetGlobalGenerator()->AddLocalGenerator(lg2);
1598 // set the subdirs start dirs
1599 lg2->GetMakefile()->SetStartDirectory(srcPath);
1600 lg2->GetMakefile()->SetStartOutputDirectory(binPath);
1603 lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1605 lg2->GetMakefile()->SetPreOrder(preorder);
1609 this->ConfigureSubDirectory(lg2);
1613 //----------------------------------------------------------------------------
1614 void AddStringToProperty(cmProperty *prop, const char* name, const char* s,
1622 // Don't worry about duplicates at this point. We eliminate them when
1623 // we convert the property to a vector in GetIncludeDirectories.
1627 const char *val = prop->GetValue();
1628 cmOStringStream oss;
1632 oss << s << ";" << val;
1639 std::string newVal = oss.str();
1640 prop->Set(name, newVal.c_str());
1644 prop->Append(name, s);
1648 //----------------------------------------------------------------------------
1649 void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
1656 // Directory property:
1658 this->GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES");
1659 AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
1661 // Property on each target:
1662 for (cmTargets::iterator l = this->Targets.begin();
1663 l != this->Targets.end(); ++l)
1665 cmTarget &t = l->second;
1666 prop = t.GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES");
1667 AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
1671 //----------------------------------------------------------------------------
1672 void cmMakefile::AddSystemIncludeDirectory(const char* dir)
1674 this->SystemIncludeDirectories.insert(dir);
1677 //----------------------------------------------------------------------------
1678 bool cmMakefile::IsSystemIncludeDirectory(const char* dir)
1680 return (this->SystemIncludeDirectories.find(dir) !=
1681 this->SystemIncludeDirectories.end());
1684 void cmMakefile::AddDefinition(const char* name, const char* value)
1692 if (this->GetCMakeInstance())
1694 this->GetCMakeInstance()->
1695 RecordPropertyAccess(name,cmProperty::VARIABLE);
1699 this->Internal->VarStack.top().Set(name, value);
1700 if (this->Internal->VarUsageStack.size() &&
1701 this->VariableInitialized(name))
1703 this->CheckForUnused("changing definition", name);
1704 this->Internal->VarUsageStack.top().erase(name);
1706 this->Internal->VarInitStack.top().insert(name);
1708 #ifdef CMAKE_BUILD_WITH_CMAKE
1709 cmVariableWatch* vv = this->GetVariableWatch();
1712 vv->VariableAccessed(name,
1713 cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1721 void cmMakefile::AddCacheDefinition(const char* name, const char* value,
1723 cmCacheManager::CacheEntryType type,
1726 const char* val = value;
1727 cmCacheManager::CacheIterator it =
1728 this->GetCacheManager()->GetCacheIterator(name);
1729 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1732 // if this is not a force, then use the value from the cache
1733 // if it is a force, then use the value being passed in
1736 val = it.GetValue();
1738 if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH )
1740 std::vector<std::string>::size_type cc;
1741 std::vector<std::string> files;
1742 std::string nvalue = "";
1743 cmSystemTools::ExpandListArgument(val, files);
1744 for ( cc = 0; cc < files.size(); cc ++ )
1746 if(!cmSystemTools::IsOff(files[cc].c_str()))
1748 files[cc] = cmSystemTools::CollapseFullPath(files[cc].c_str());
1754 nvalue += files[cc];
1757 this->GetCacheManager()->AddCacheEntry(name, nvalue.c_str(), doc, type);
1758 val = it.GetValue();
1762 this->GetCacheManager()->AddCacheEntry(name, val, doc, type);
1763 // if there was a definition then remove it
1764 this->Internal->VarStack.top().Set(name, 0);
1768 void cmMakefile::AddDefinition(const char* name, bool value)
1770 this->Internal->VarStack.top().Set(name, value? "ON" : "OFF");
1771 if (this->Internal->VarUsageStack.size() &&
1772 this->VariableInitialized(name))
1774 this->CheckForUnused("changing definition", name);
1775 this->Internal->VarUsageStack.top().erase(name);
1777 this->Internal->VarInitStack.top().insert(name);
1778 #ifdef CMAKE_BUILD_WITH_CMAKE
1779 cmVariableWatch* vv = this->GetVariableWatch();
1782 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1783 value?"ON":"OFF", this);
1788 void cmMakefile::CheckForUnusedVariables() const
1790 if (!this->WarnUnused)
1794 const cmDefinitions& defs = this->Internal->VarStack.top();
1795 const std::set<cmStdString>& locals = defs.LocalKeys();
1796 std::set<cmStdString>::const_iterator it = locals.begin();
1797 for (; it != locals.end(); ++it)
1799 this->CheckForUnused("out of scope", it->c_str());
1803 void cmMakefile::MarkVariableAsUsed(const char* var)
1805 this->Internal->VarUsageStack.top().insert(var);
1808 bool cmMakefile::VariableInitialized(const char* var) const
1810 if(this->Internal->VarInitStack.top().find(var) !=
1811 this->Internal->VarInitStack.top().end())
1818 bool cmMakefile::VariableUsed(const char* var) const
1820 if(this->Internal->VarUsageStack.top().find(var) !=
1821 this->Internal->VarUsageStack.top().end())
1828 void cmMakefile::CheckForUnused(const char* reason, const char* name) const
1830 if (this->WarnUnused && !this->VariableUsed(name))
1833 cmListFileBacktrace bt;
1834 if (this->CallStack.size())
1836 const cmListFileContext* file = this->CallStack.back().Context;
1837 bt.push_back(*file);
1838 path = file->FilePath.c_str();
1842 path = this->GetStartDirectory();
1843 path += "/CMakeLists.txt";
1844 cmListFileContext lfc;
1845 lfc.FilePath = path;
1849 if (this->CheckSystemVars ||
1850 cmSystemTools::IsSubDirectory(path.c_str(),
1851 this->GetHomeDirectory()) ||
1852 (cmSystemTools::IsSubDirectory(path.c_str(),
1853 this->GetHomeOutputDirectory()) &&
1854 !cmSystemTools::IsSubDirectory(path.c_str(),
1855 cmake::GetCMakeFilesDirectory())))
1857 cmOStringStream msg;
1858 msg << "unused variable (" << reason << ") \'" << name << "\'";
1859 this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING,
1866 void cmMakefile::RemoveDefinition(const char* name)
1868 this->Internal->VarStack.top().Set(name, 0);
1869 if (this->Internal->VarUsageStack.size() &&
1870 this->VariableInitialized(name))
1872 this->CheckForUnused("unsetting", name);
1873 this->Internal->VarUsageStack.top().erase(name);
1875 this->Internal->VarInitStack.top().insert(name);
1876 #ifdef CMAKE_BUILD_WITH_CMAKE
1877 cmVariableWatch* vv = this->GetVariableWatch();
1880 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
1886 void cmMakefile::RemoveCacheDefinition(const char* name)
1888 this->GetCacheManager()->RemoveCacheEntry(name);
1891 void cmMakefile::SetProjectName(const char* p)
1893 this->ProjectName = p;
1897 void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
1899 // for these targets do not add anything
1900 switch(target.GetType())
1902 case cmTarget::UTILITY:
1903 case cmTarget::GLOBAL_TARGET:
1907 std::vector<std::string>::iterator j;
1908 for(j = this->LinkDirectories.begin();
1909 j != this->LinkDirectories.end(); ++j)
1911 target.AddLinkDirectory(j->c_str());
1913 target.MergeLinkLibraries( *this, name, this->LinkLibraries );
1917 cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
1918 const std::vector<std::string> &srcs,
1919 bool excludeFromAll)
1921 // wrong type ? default to STATIC
1922 if ( (type != cmTarget::STATIC_LIBRARY)
1923 && (type != cmTarget::SHARED_LIBRARY)
1924 && (type != cmTarget::MODULE_LIBRARY)
1925 && (type != cmTarget::OBJECT_LIBRARY))
1927 this->IssueMessage(cmake::INTERNAL_ERROR,
1928 "cmMakefile::AddLibrary given invalid target type.");
1929 type = cmTarget::STATIC_LIBRARY;
1932 cmTarget* target = this->AddNewTarget(type, lname);
1933 // Clear its dependencies. Otherwise, dependencies might persist
1934 // over changes in CMakeLists.txt, making the information stale and
1936 target->ClearDependencyInformation( *this, lname );
1939 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1941 target->AddSources(srcs);
1942 this->AddGlobalLinkInformation(lname, *target);
1946 cmTarget* cmMakefile::AddExecutable(const char *exeName,
1947 const std::vector<std::string> &srcs,
1948 bool excludeFromAll)
1950 cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName);
1953 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1955 target->AddSources(srcs);
1956 this->AddGlobalLinkInformation(exeName, *target);
1960 //----------------------------------------------------------------------------
1962 cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name)
1964 cmTargets::iterator it =
1965 this->Targets.insert(cmTargets::value_type(name, cmTarget())).first;
1966 cmTarget& target = it->second;
1967 target.SetType(type, name);
1968 target.SetMakefile(this);
1969 this->LocalGenerator->GetGlobalGenerator()->AddTarget(&it->second);
1973 cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
1975 std::string name = cname;
1978 // look through all the source files that have custom commands
1979 // and see if the custom command has the passed source file as an output
1980 for(std::vector<cmSourceFile*>::const_iterator i =
1981 this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
1983 // does this source file have a custom command?
1984 if ((*i)->GetCustomCommand())
1986 // is the output of the custom command match the source files name
1987 const std::vector<std::string>& outputs =
1988 (*i)->GetCustomCommand()->GetOutputs();
1989 for(std::vector<std::string>::const_iterator o = outputs.begin();
1990 o != outputs.end(); ++o)
1993 std::string::size_type pos = out.rfind(name);
1994 // If the output matches exactly
1995 if (pos != out.npos &&
1996 pos == out.size() - name.size() &&
1997 (pos ==0 || out[pos-1] == '/'))
2005 // otherwise return NULL
2009 #if defined(CMAKE_BUILD_WITH_CMAKE)
2010 cmSourceGroup* cmMakefile::GetSourceGroup(const std::vector<std::string>&name)
2012 cmSourceGroup* sg = 0;
2014 // first look for source group starting with the same as the one we wants
2015 for (std::vector<cmSourceGroup>::iterator sgIt = this->SourceGroups.begin();
2016 sgIt != this->SourceGroups.end(); ++sgIt)
2019 std::string sgName = sgIt->GetName();
2020 if(sgName == name[0])
2029 // iterate through its children to find match source group
2030 for(unsigned int i=1; i<name.size(); ++i)
2032 sg = sg->lookupChild(name[i].c_str());
2042 void cmMakefile::AddSourceGroup(const char* name,
2047 std::vector<std::string> nameVector;
2048 nameVector.push_back(name);
2049 AddSourceGroup(nameVector, regex);
2053 void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
2056 cmSourceGroup* sg = 0;
2057 std::vector<std::string> currentName;
2059 const int lastElement = static_cast<int>(name.size()-1);
2060 for(i=lastElement; i>=0; --i)
2062 currentName.assign(name.begin(), name.begin()+i+1);
2063 sg = this->GetSourceGroup(currentName);
2070 // i now contains the index of the last found component
2073 // group already exists, replace its regular expression
2076 // We only want to set the regular expression. If there are already
2077 // source files in the group, we don't want to remove them.
2078 sg->SetGroupRegex(regex);
2084 // group does not exists nor belong to any existing group
2085 // add its first component
2086 this->SourceGroups.push_back(cmSourceGroup(name[0].c_str(), regex));
2087 sg = this->GetSourceGroup(currentName);
2088 i = 0; // last component found
2091 // build the whole source group path
2092 const char* fullname = sg->GetFullName();
2093 cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
2094 if(strlen(fullname))
2096 std::string guidName = "SG_Filter_";
2097 guidName += fullname;
2098 gg->CreateGUID(guidName.c_str());
2100 for(++i; i<=lastElement; ++i)
2102 sg->AddChild(cmSourceGroup(name[i].c_str(), 0, sg->GetFullName()));
2103 sg = sg->lookupChild(name[i].c_str());
2104 fullname = sg->GetFullName();
2105 if(strlen(fullname))
2107 std::string guidName = "SG_Filter_";
2108 guidName += fullname;
2109 gg->CreateGUID(guidName.c_str());
2113 sg->SetGroupRegex(regex);
2118 void cmMakefile::AddExtraDirectory(const char* dir)
2120 this->AuxSourceDirectories.push_back(dir);
2124 // expand CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
2125 // include and library directories.
2127 void cmMakefile::ExpandVariables()
2129 // Now expand variables in the include and link strings
2131 // May not be necessary anymore... But may need a policy for strict
2132 // backwards compatibility
2133 const char *includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
2136 std::string dirs = includeDirs;
2137 this->ExpandVariablesInString(dirs, true, true);
2138 this->SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
2141 // Also for each target's INCLUDE_DIRECTORIES property:
2142 for (cmTargets::iterator l = this->Targets.begin();
2143 l != this->Targets.end(); ++l)
2145 cmTarget &t = l->second;
2146 includeDirs = t.GetProperty("INCLUDE_DIRECTORIES");
2149 std::string dirs = includeDirs;
2150 this->ExpandVariablesInString(dirs, true, true);
2151 t.SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
2155 for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
2156 d != this->LinkDirectories.end(); ++d)
2158 this->ExpandVariablesInString(*d, true, true);
2160 for(cmTarget::LinkLibraryVectorType::iterator l =
2161 this->LinkLibraries.begin();
2162 l != this->LinkLibraries.end(); ++l)
2164 this->ExpandVariablesInString(l->first, true, true);
2168 bool cmMakefile::IsOn(const char* name) const
2170 const char* value = this->GetDefinition(name);
2171 return cmSystemTools::IsOn(value);
2174 bool cmMakefile::IsSet(const char* name) const
2176 const char* value = this->GetDefinition(name);
2187 if ( cmSystemTools::IsNOTFOUND(value) )
2195 bool cmMakefile::PlatformIs64Bit() const
2197 if(const char* sizeof_dptr = this->GetDefinition("CMAKE_SIZEOF_VOID_P"))
2199 return atoi(sizeof_dptr) == 8;
2204 const char* cmMakefile::GetSONameFlag(const char* language) const
2206 std::string name = "CMAKE_SHARED_LIBRARY_SONAME";
2213 return GetDefinition(name.c_str());
2216 bool cmMakefile::CanIWriteThisFile(const char* fileName)
2218 if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
2222 // If we are doing an in-source build, than the test will always fail
2223 if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
2224 this->GetHomeOutputDirectory()) )
2226 if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
2233 // Check if this is subdirectory of the source tree but not a
2234 // subdirectory of a build tree
2235 if ( cmSystemTools::IsSubDirectory(fileName,
2236 this->GetHomeDirectory()) &&
2237 !cmSystemTools::IsSubDirectory(fileName,
2238 this->GetHomeOutputDirectory()) )
2245 const char* cmMakefile::GetRequiredDefinition(const char* name) const
2247 const char* ret = this->GetDefinition(name);
2250 cmSystemTools::Error("Error required internal CMake variable not "
2251 "set, cmake may be not be built correctly.\n",
2252 "Missing variable is:\n",
2259 bool cmMakefile::IsDefinitionSet(const char* name) const
2261 const char* def = this->Internal->VarStack.top().Get(name);
2262 this->Internal->VarUsageStack.top().insert(name);
2265 def = this->GetCacheManager()->GetCacheValue(name);
2267 #ifdef CMAKE_BUILD_WITH_CMAKE
2268 if(cmVariableWatch* vv = this->GetVariableWatch())
2272 vv->VariableAccessed
2273 (name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS,
2278 return def?true:false;
2281 const char* cmMakefile::GetDefinition(const char* name) const
2284 if (this->GetCMakeInstance())
2286 this->GetCMakeInstance()->
2287 RecordPropertyAccess(name,cmProperty::VARIABLE);
2290 if (this->WarnUnused)
2292 this->Internal->VarUsageStack.top().insert(name);
2294 const char* def = this->Internal->VarStack.top().Get(name);
2297 def = this->GetCacheManager()->GetCacheValue(name);
2299 #ifdef CMAKE_BUILD_WITH_CMAKE
2300 cmVariableWatch* vv = this->GetVariableWatch();
2305 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
2310 // are unknown access allowed
2311 const char* allow = this->Internal->VarStack.top()
2312 .Get("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
2313 if(cmSystemTools::IsOn(allow))
2315 vv->VariableAccessed(name,
2316 cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, def, this);
2320 vv->VariableAccessed(name,
2321 cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
2329 const char* cmMakefile::GetSafeDefinition(const char* def) const
2331 const char* ret = this->GetDefinition(def);
2339 std::vector<std::string> cmMakefile
2340 ::GetDefinitions(int cacheonly /* = 0 */) const
2342 std::set<cmStdString> definitions;
2345 definitions = this->Internal->VarStack.top().ClosureKeys();
2347 cmCacheManager::CacheIterator cit =
2348 this->GetCacheManager()->GetCacheIterator();
2349 for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
2351 definitions.insert(cit.GetName());
2354 std::vector<std::string> res;
2356 std::set<cmStdString>::iterator fit;
2357 for ( fit = definitions.begin(); fit != definitions.end(); fit ++ )
2359 res.push_back(*fit);
2365 const char *cmMakefile::ExpandVariablesInString(std::string& source)
2367 return this->ExpandVariablesInString(source, false, false);
2370 const char *cmMakefile::ExpandVariablesInString(std::string& source,
2374 const char* filename,
2379 if ( source.empty() || source.find_first_of("$@\\") == source.npos)
2381 return source.c_str();
2384 // Special-case the @ONLY mode.
2387 if(!noEscapes || !removeEmpty || !replaceAt)
2389 // This case should never be called. At-only is for
2390 // configure-file/string which always does no escapes.
2391 this->IssueMessage(cmake::INTERNAL_ERROR,
2392 "ExpandVariablesInString @ONLY called "
2393 "on something with escapes.");
2396 // Store an original copy of the input.
2397 std::string input = source;
2399 // Start with empty output.
2402 // Look for one @VAR@ at a time.
2403 const char* in = input.c_str();
2404 while(this->cmAtVarRegex.find(in))
2406 // Get the range of the string to replace.
2407 const char* first = in + this->cmAtVarRegex.start();
2408 const char* last = in + this->cmAtVarRegex.end();
2410 // Store the unchanged part of the string now.
2411 source.append(in, first-in);
2413 // Lookup the definition of VAR.
2414 std::string var(first+1, last-first-2);
2415 if(const char* val = this->GetDefinition(var.c_str()))
2417 // Store the value in the output escaping as requested.
2420 source.append(cmSystemTools::EscapeQuotes(val));
2428 // Continue looking for @VAR@ further along the string.
2432 // Append the rest of the unchanged part of the string.
2435 return source.c_str();
2438 // This method replaces ${VAR} and @VAR@ where VAR is looked up
2439 // with GetDefinition(), if not found in the map, nothing is expanded.
2440 // It also supports the $ENV{VAR} syntax where VAR is looked up in
2441 // the current environment variables.
2443 cmCommandArgumentParserHelper parser;
2444 parser.SetMakefile(this);
2445 parser.SetLineFile(line, filename);
2446 parser.SetEscapeQuotes(escapeQuotes);
2447 parser.SetNoEscapeMode(noEscapes);
2448 parser.SetReplaceAtSyntax(replaceAt);
2449 parser.SetRemoveEmpty(removeEmpty);
2450 int res = parser.ParseString(source.c_str(), 0);
2451 const char* emsg = parser.GetError();
2452 if ( res && !emsg[0] )
2454 source = parser.GetResult();
2458 // Construct the main error message.
2459 cmOStringStream error;
2460 error << "Syntax error in cmake code ";
2461 if(filename && line > 0)
2463 // This filename and line number may be more specific than the
2464 // command context because one command invocation can have
2465 // arguments on multiple lines.
2467 << " " << filename << ":" << line << "\n";
2469 error << "when parsing string\n"
2470 << " " << source.c_str() << "\n";
2473 // If the parser failed ("res" is false) then this is a real
2474 // argument parsing error, so the policy applies. Otherwise the
2475 // parser reported an error message without failing because the
2476 // helper implementation is unhappy, which has always reported an
2478 cmake::MessageType mtype = cmake::FATAL_ERROR;
2481 // This is a real argument parsing error. Use policy CMP0010 to
2482 // decide whether it is an error.
2483 switch(this->GetPolicyStatus(cmPolicies::CMP0010))
2485 case cmPolicies::WARN:
2487 << (this->GetPolicies()
2488 ->GetPolicyWarning(cmPolicies::CMP0010));
2489 case cmPolicies::OLD:
2490 // OLD behavior is to just warn and continue.
2491 mtype = cmake::AUTHOR_WARNING;
2493 case cmPolicies::REQUIRED_IF_USED:
2494 case cmPolicies::REQUIRED_ALWAYS:
2496 << (this->GetPolicies()
2497 ->GetRequiredPolicyError(cmPolicies::CMP0010));
2498 case cmPolicies::NEW:
2499 // NEW behavior is to report the error.
2500 cmSystemTools::SetFatalErrorOccured();
2504 this->IssueMessage(mtype, error.str());
2506 return source.c_str();
2509 void cmMakefile::RemoveVariablesInString(std::string& source,
2514 cmsys::RegularExpression var("(\\${[A-Za-z_0-9]*})");
2515 while (var.find(source))
2517 source.erase(var.start(),var.end() - var.start());
2523 cmsys::RegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
2524 while (varb.find(source))
2526 source.erase(varb.start(),varb.end() - varb.start());
2529 cmsys::RegularExpression var2("(@[A-Za-z_0-9]*@)");
2530 while (var2.find(source))
2532 source.erase(var2.start(),var2.end() - var2.start());
2537 * Add the default definitions to the makefile. These values must not
2538 * be dependent on anything that isn't known when this cmMakefile instance
2541 void cmMakefile::AddDefaultDefinitions()
2543 /* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set.
2544 With CMake must separate between target and host platform. In most cases
2545 the tests for WIN32, UNIX and APPLE will be for the target system, so an
2546 additional set of variables for the host system is required ->
2547 CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE.
2548 WIN32, UNIX and APPLE are now set in the platform files in
2550 To keep cmake scripts (-P) and custom language and compiler modules
2551 working, these variables are still also set here in this place, but they
2552 will be reset in CMakeSystemSpecificInformation.cmake before the platform
2553 files are executed. */
2555 this->AddDefinition("WIN32", "1");
2556 this->AddDefinition("CMAKE_HOST_WIN32", "1");
2558 this->AddDefinition("UNIX", "1");
2559 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2561 #if defined(__CYGWIN__)
2562 if(cmSystemTools::IsOn(cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32")))
2564 this->AddDefinition("WIN32", "1");
2565 this->AddDefinition("CMAKE_HOST_WIN32", "1");
2568 #if defined(__APPLE__)
2569 this->AddDefinition("APPLE", "1");
2570 this->AddDefinition("CMAKE_HOST_APPLE", "1");
2574 sprintf(temp, "%d", cmVersion::GetMinorVersion());
2575 this->AddDefinition("CMAKE_MINOR_VERSION", temp);
2576 sprintf(temp, "%d", cmVersion::GetMajorVersion());
2577 this->AddDefinition("CMAKE_MAJOR_VERSION", temp);
2578 sprintf(temp, "%d", cmVersion::GetPatchVersion());
2579 this->AddDefinition("CMAKE_PATCH_VERSION", temp);
2580 sprintf(temp, "%d", cmVersion::GetTweakVersion());
2581 this->AddDefinition("CMAKE_TWEAK_VERSION", temp);
2582 this->AddDefinition("CMAKE_VERSION", cmVersion::GetCMakeVersion());
2584 this->AddDefinition("CMAKE_FILES_DIRECTORY",
2585 cmake::GetCMakeFilesDirectory());
2588 //----------------------------------------------------------------------------
2590 cmMakefile::GetConfigurations(std::vector<std::string>& configs,
2593 if(this->LocalGenerator->GetGlobalGenerator()->IsMultiConfig())
2595 if(const char* configTypes =
2596 this->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
2598 cmSystemTools::ExpandListArgument(configTypes, configs);
2604 const char* buildType = this->GetDefinition("CMAKE_BUILD_TYPE");
2605 if(single && buildType && *buildType)
2607 configs.push_back(buildType);
2613 #if defined(CMAKE_BUILD_WITH_CMAKE)
2615 * Find a source group whose regular expression matches the filename
2616 * part of the given source name. Search backward through the list of
2617 * source groups, and take the first matching group found. This way
2618 * non-inherited SOURCE_GROUP commands will have precedence over
2622 cmMakefile::FindSourceGroup(const char* source,
2623 std::vector<cmSourceGroup> &groups)
2625 // First search for a group that lists the file explicitly.
2626 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2627 sg != groups.rend(); ++sg)
2629 cmSourceGroup *result = sg->MatchChildrenFiles(source);
2636 // Now search for a group whose regex matches the file.
2637 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2638 sg != groups.rend(); ++sg)
2640 cmSourceGroup *result = sg->MatchChildrenRegex(source);
2648 // Shouldn't get here, but just in case, return the default group.
2649 return groups.front();
2653 bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
2654 cmExecutionStatus &status)
2656 // if there are no blockers get out of here
2657 if (this->FunctionBlockers.begin() == this->FunctionBlockers.end())
2662 // loop over all function blockers to see if any block this command
2663 // evaluate in reverse, this is critical for balanced IF statements etc
2664 std::vector<cmFunctionBlocker*>::reverse_iterator pos;
2665 for (pos = this->FunctionBlockers.rbegin();
2666 pos != this->FunctionBlockers.rend(); ++pos)
2668 if((*pos)->IsFunctionBlocked(lff, *this, status))
2677 //----------------------------------------------------------------------------
2678 void cmMakefile::PushFunctionBlockerBarrier()
2680 this->FunctionBlockerBarriers.push_back(this->FunctionBlockers.size());
2683 //----------------------------------------------------------------------------
2684 void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
2686 // Remove any extra entries pushed on the barrier.
2687 FunctionBlockersType::size_type barrier =
2688 this->FunctionBlockerBarriers.back();
2689 while(this->FunctionBlockers.size() > barrier)
2691 cmsys::auto_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back());
2692 this->FunctionBlockers.pop_back();
2695 // Report the context in which the unclosed block was opened.
2696 cmListFileContext const& lfc = fb->GetStartingContext();
2698 e << "A logical block opening on the line\n"
2699 << " " << lfc << "\n"
2700 << "is not closed.";
2701 this->IssueMessage(cmake::FATAL_ERROR, e.str());
2702 reportError = false;
2706 // Remove the barrier.
2707 this->FunctionBlockerBarriers.pop_back();
2710 bool cmMakefile::ExpandArguments(
2711 std::vector<cmListFileArgument> const& inArgs,
2712 std::vector<std::string>& outArgs)
2714 std::vector<cmListFileArgument>::const_iterator i;
2716 outArgs.reserve(inArgs.size());
2717 for(i = inArgs.begin(); i != inArgs.end(); ++i)
2719 // Expand the variables in the argument.
2721 this->ExpandVariablesInString(value, false, false, false,
2722 i->FilePath, i->Line,
2725 // If the argument is quoted, it should be one argument.
2726 // Otherwise, it may be a list of arguments.
2729 outArgs.push_back(value);
2733 cmSystemTools::ExpandListArgument(value, outArgs);
2736 return !cmSystemTools::GetFatalErrorOccured();
2739 //----------------------------------------------------------------------------
2740 void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
2742 if(!this->CallStack.empty())
2744 // Record the context in which the blocker is created.
2745 fb->SetStartingContext(*(this->CallStack.back().Context));
2748 this->FunctionBlockers.push_back(fb);
2751 cmsys::auto_ptr<cmFunctionBlocker>
2752 cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb,
2753 const cmListFileFunction& lff)
2755 // Find the function blocker stack barrier for the current scope.
2756 // We only remove a blocker whose index is not less than the barrier.
2757 FunctionBlockersType::size_type barrier = 0;
2758 if(!this->FunctionBlockerBarriers.empty())
2760 barrier = this->FunctionBlockerBarriers.back();
2763 // Search for the function blocker whose scope this command ends.
2764 for(FunctionBlockersType::size_type
2765 i = this->FunctionBlockers.size(); i > barrier; --i)
2767 std::vector<cmFunctionBlocker*>::iterator pos =
2768 this->FunctionBlockers.begin() + (i - 1);
2771 // Warn if the arguments do not match, but always remove.
2772 if(!(*pos)->ShouldRemove(lff, *this))
2774 cmListFileContext const& lfc = fb->GetStartingContext();
2776 e << "A logical block opening on the line\n"
2777 << " " << lfc << "\n"
2778 << "closes on the line\n"
2779 << " " << lff << "\n"
2780 << "with mis-matching arguments.";
2781 this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
2783 cmFunctionBlocker* b = *pos;
2784 this->FunctionBlockers.erase(pos);
2785 return cmsys::auto_ptr<cmFunctionBlocker>(b);
2789 return cmsys::auto_ptr<cmFunctionBlocker>();
2792 //----------------------------------------------------------------------------
2793 cmMakefile::LexicalPushPop::LexicalPushPop(cmMakefile* mf):
2794 Makefile(mf), ReportError(true)
2796 this->Makefile->PushFunctionBlockerBarrier();
2799 //----------------------------------------------------------------------------
2800 cmMakefile::LexicalPushPop::~LexicalPushPop()
2802 this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
2805 void cmMakefile::SetHomeDirectory(const char* dir)
2807 this->cmHomeDirectory = dir;
2808 cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
2809 this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
2810 if ( !this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR") )
2812 this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", this->GetHomeDirectory());
2816 void cmMakefile::SetHomeOutputDirectory(const char* lib)
2818 this->HomeOutputDirectory = lib;
2819 cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
2820 this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
2821 if ( !this->GetDefinition("CMAKE_CURRENT_BINARY_DIR") )
2823 this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
2824 this->GetHomeOutputDirectory());
2828 void cmMakefile::SetScriptModeFile(const char* scriptfile)
2830 this->AddDefinition("CMAKE_SCRIPT_MODE_FILE", scriptfile);
2833 void cmMakefile::SetArgcArgv(const std::vector<std::string>& args)
2835 cmOStringStream strStream;
2836 strStream << args.size();
2837 this->AddDefinition("CMAKE_ARGC", strStream.str().c_str());
2838 //this->MarkVariableAsUsed("CMAKE_ARGC");
2840 for (unsigned int t = 0; t < args.size(); ++t)
2842 cmOStringStream tmpStream;
2843 tmpStream << "CMAKE_ARGV" << t;
2844 this->AddDefinition(tmpStream.str().c_str(), args[t].c_str());
2845 //this->MarkVariableAsUsed(tmpStream.str().c_str());
2849 //----------------------------------------------------------------------------
2850 cmSourceFile* cmMakefile::GetSource(const char* sourceName)
2852 cmSourceFileLocation sfl(this, sourceName);
2853 for(std::vector<cmSourceFile*>::const_iterator
2854 sfi = this->SourceFiles.begin();
2855 sfi != this->SourceFiles.end(); ++sfi)
2857 cmSourceFile* sf = *sfi;
2858 if(sf->Matches(sfl))
2866 //----------------------------------------------------------------------------
2867 cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
2870 if(cmSourceFile* esf = this->GetSource(sourceName))
2876 cmSourceFile* sf = new cmSourceFile(this, sourceName);
2879 sf->SetProperty("GENERATED", "1");
2881 this->SourceFiles.push_back(sf);
2886 void cmMakefile::EnableLanguage(std::vector<std::string> const & lang,
2889 this->AddDefinition("CMAKE_CFG_INTDIR",
2890 this->LocalGenerator->GetGlobalGenerator()
2891 ->GetCMakeCFGIntDir());
2892 this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this,
2896 void cmMakefile::ExpandSourceListArguments(
2897 std::vector<std::string> const& arguments,
2898 std::vector<std::string>& newargs, unsigned int /* start */)
2900 // now expand the args
2902 for(i = 0; i < arguments.size(); ++i)
2904 // List expansion will have been done already.
2905 newargs.push_back(arguments[i]);
2909 int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
2910 const char *projectName, const char *targetName,
2912 const std::vector<std::string> *cmakeArgs,
2913 std::string *output)
2915 // does the binary directory exist ? If not create it...
2916 if (!cmSystemTools::FileIsDirectory(bindir))
2918 cmSystemTools::MakeDirectory(bindir);
2921 // change to the tests directory and run cmake
2922 // use the cmake object instead of calling cmake
2923 std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
2924 cmSystemTools::ChangeDirectory(bindir);
2926 // make sure the same generator is used
2927 // use this program as the cmake to be run, it should not
2928 // be run that way but the cmake object requires a vailid path
2929 std::string cmakeCommand = this->GetDefinition("CMAKE_COMMAND");
2931 cm.SetIsInTryCompile(true);
2932 cmGlobalGenerator *gg = cm.CreateGlobalGenerator
2933 (this->LocalGenerator->GetGlobalGenerator()->GetName());
2936 cmSystemTools::Error(
2937 "Internal CMake error, TryCompile bad GlobalGenerator");
2938 // return to the original directory
2939 cmSystemTools::ChangeDirectory(cwd.c_str());
2942 cm.SetGlobalGenerator(gg);
2945 cm.SetHomeDirectory(srcdir);
2946 cm.SetHomeOutputDirectory(bindir);
2947 cm.SetStartDirectory(srcdir);
2948 cm.SetStartOutputDirectory(bindir);
2949 cm.SetCMakeCommand(cmakeCommand.c_str());
2951 if(!gg->IsMultiConfig())
2953 if(const char* config =
2954 this->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"))
2956 // Tell the single-configuration generator which one to use.
2957 // Add this before the user-provided CMake arguments in case
2958 // one of the arguments is -DCMAKE_BUILD_TYPE=...
2959 cm.AddCacheEntry("CMAKE_BUILD_TYPE", config,
2960 "Build configuration", cmCacheManager::STRING);
2963 // if cmake args were provided then pass them in
2966 // FIXME: Workaround to ignore unused CLI variables in try-compile.
2968 // Ideally we should use SetArgs to honor options like --warn-unused-vars.
2969 // However, there is a subtle problem when certain arguments are passed to
2970 // a macro wrapping around try_compile or try_run that does not escape
2971 // semicolons in its parameters but just passes ${ARGV} or ${ARGN}. In
2972 // this case a list argument like "-DVAR=a;b" gets split into multiple
2973 // cmake arguments "-DVAR=a" and "b". Currently SetCacheArgs ignores
2974 // argument "b" and uses just "-DVAR=a", leading to a subtle bug in that
2975 // the try_compile or try_run does not get the proper value of VAR. If we
2976 // call SetArgs here then it would treat "b" as the source directory and
2977 // cause an error such as "The source directory .../CMakeFiles/CMakeTmp/b
2978 // does not exist", thus breaking the try_compile or try_run completely.
2980 // Strictly speaking the bug is in the wrapper macro because the CMake
2981 // language has always flattened nested lists and the macro should escape
2982 // the semicolons in its arguments before forwarding them. However, this
2983 // bug is so subtle that projects typically work anyway, usually because
2984 // the value VAR=a is sufficient for the try_compile or try_run to get the
2985 // correct result. Calling SetArgs here would break such projects that
2986 // previously built. Instead we work around the issue by never reporting
2987 // unused arguments and ignoring options such as --warn-unused-vars.
2988 cm.SetWarnUnusedCli(false);
2989 //cm.SetArgs(*cmakeArgs, true);
2991 cm.SetCacheArgs(*cmakeArgs);
2993 // to save time we pass the EnableLanguage info directly
2994 gg->EnableLanguagesFromGenerator
2995 (this->LocalGenerator->GetGlobalGenerator(), this);
2996 if(this->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"))
2998 cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
2999 "TRUE", "", cmCacheManager::INTERNAL);
3003 cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
3004 "FALSE", "", cmCacheManager::INTERNAL);
3006 if (cm.Configure() != 0)
3008 cmSystemTools::Error(
3009 "Internal CMake error, TryCompile configure of cmake failed");
3010 // return to the original directory
3011 cmSystemTools::ChangeDirectory(cwd.c_str());
3015 if (cm.Generate() != 0)
3017 cmSystemTools::Error(
3018 "Internal CMake error, TryCompile generation of cmake failed");
3019 // return to the original directory
3020 cmSystemTools::ChangeDirectory(cwd.c_str());
3024 // finally call the generator to actually build the resulting project
3026 this->LocalGenerator->GetGlobalGenerator()->TryCompile(srcdir,bindir,
3033 cmSystemTools::ChangeDirectory(cwd.c_str());
3037 cmake *cmMakefile::GetCMakeInstance() const
3039 if ( this->LocalGenerator && this->LocalGenerator->GetGlobalGenerator() )
3041 return this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
3046 #ifdef CMAKE_BUILD_WITH_CMAKE
3047 cmVariableWatch *cmMakefile::GetVariableWatch() const
3049 if ( this->GetCMakeInstance() &&
3050 this->GetCMakeInstance()->GetVariableWatch() )
3052 return this->GetCMakeInstance()->GetVariableWatch();
3058 void cmMakefile::AddMacro(const char* name, const char* signature)
3060 if ( !name || !signature )
3064 this->MacrosMap[name] = signature;
3067 void cmMakefile::GetListOfMacros(std::string& macros)
3069 StringStringMap::iterator it;
3072 for ( it = this->MacrosMap.begin(); it != this->MacrosMap.end(); ++it )
3078 macros += it->first;
3083 cmCacheManager *cmMakefile::GetCacheManager() const
3085 return this->GetCMakeInstance()->GetCacheManager();
3088 void cmMakefile::DisplayStatus(const char* message, float s)
3090 cmake* cm = this->GetLocalGenerator()->GetGlobalGenerator()
3091 ->GetCMakeInstance();
3092 if (cm->GetWorkingMode() == cmake::FIND_PACKAGE_MODE)
3094 // don't output any STATUS message in FIND_PACKAGE_MODE, since they will
3095 // directly be fed to the compiler, which will be confused.
3098 cm->UpdateProgress(message, s);
3101 std::string cmMakefile::GetModulesFile(const char* filename)
3105 // We search the module always in CMAKE_ROOT and in CMAKE_MODULE_PATH,
3106 // and then decide based on the policy setting which one to return.
3107 // See CMP0017 for more details.
3108 // The specific problem was that KDE 4.5.0 installs a
3109 // FindPackageHandleStandardArgs.cmake which doesn't have the new features
3110 // of FPHSA.cmake introduced in CMake 2.8.3 yet, and by setting
3111 // CMAKE_MODULE_PATH also e.g. FindZLIB.cmake from cmake included
3112 // FPHSA.cmake from kdelibs and not from CMake, and tried to use the
3113 // new features, which were not there in the version from kdelibs, and so
3115 std::string moduleInCMakeRoot;
3116 std::string moduleInCMakeModulePath;
3118 // Always search in CMAKE_MODULE_PATH:
3119 const char* cmakeModulePath = this->GetDefinition("CMAKE_MODULE_PATH");
3122 std::vector<std::string> modulePath;
3123 cmSystemTools::ExpandListArgument(cmakeModulePath, modulePath);
3125 //Look through the possible module directories.
3126 for(std::vector<std::string>::iterator i = modulePath.begin();
3127 i != modulePath.end(); ++i)
3129 std::string itempl = *i;
3130 cmSystemTools::ConvertToUnixSlashes(itempl);
3133 if(cmSystemTools::FileExists(itempl.c_str()))
3135 moduleInCMakeModulePath = itempl;
3141 // Always search in the standard modules location.
3142 const char* cmakeRoot = this->GetDefinition("CMAKE_ROOT");
3145 moduleInCMakeRoot = cmakeRoot;
3146 moduleInCMakeRoot += "/Modules/";
3147 moduleInCMakeRoot += filename;
3148 cmSystemTools::ConvertToUnixSlashes(moduleInCMakeRoot);
3149 if(!cmSystemTools::FileExists(moduleInCMakeRoot.c_str()))
3151 moduleInCMakeRoot = "";
3155 // Normally, prefer the files found in CMAKE_MODULE_PATH. Only when the file
3156 // from which we are being called is located itself in CMAKE_ROOT, then
3157 // prefer results from CMAKE_ROOT depending on the policy setting.
3158 result = moduleInCMakeModulePath;
3159 if (result.size() == 0)
3161 result = moduleInCMakeRoot;
3164 if ((moduleInCMakeModulePath.size()>0) && (moduleInCMakeRoot.size()>0))
3166 const char* currentFile = this->GetDefinition("CMAKE_CURRENT_LIST_FILE");
3167 if (currentFile && (strstr(currentFile, cmakeRoot) == currentFile))
3169 switch (this->GetPolicyStatus(cmPolicies::CMP0017))
3171 case cmPolicies::WARN:
3174 e << "File " << currentFile << " includes "
3175 << moduleInCMakeModulePath
3176 << " (found via CMAKE_MODULE_PATH) which shadows "
3177 << moduleInCMakeRoot << ". This may cause errors later on .\n"
3178 << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0017);
3180 this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
3181 // break; // fall through to OLD behaviour
3183 case cmPolicies::OLD:
3184 result = moduleInCMakeModulePath;
3186 case cmPolicies::REQUIRED_IF_USED:
3187 case cmPolicies::REQUIRED_ALWAYS:
3188 case cmPolicies::NEW:
3190 result = moduleInCMakeRoot;
3199 void cmMakefile::ConfigureString(const std::string& input,
3200 std::string& output, bool atOnly,
3203 // Split input to handle one line at a time.
3204 std::string::const_iterator lineStart = input.begin();
3205 while(lineStart != input.end())
3207 // Find the end of this line.
3208 std::string::const_iterator lineEnd = lineStart;
3209 while(lineEnd != input.end() && *lineEnd != '\n')
3215 std::string line(lineStart, lineEnd);
3217 // Skip the newline character.
3218 bool haveNewline = (lineEnd != input.end());
3224 // Replace #cmakedefine instances.
3225 if(this->cmDefineRegex.find(line))
3228 this->GetDefinition(this->cmDefineRegex.match(1).c_str());
3229 if(!cmSystemTools::IsOff(def))
3231 cmSystemTools::ReplaceString(line, "#cmakedefine", "#define");
3236 output += "/* #undef ";
3237 output += this->cmDefineRegex.match(1);
3241 else if(this->cmDefine01Regex.find(line))
3244 this->GetDefinition(this->cmDefine01Regex.match(1).c_str());
3245 cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define");
3247 if(!cmSystemTools::IsOff(def))
3266 // Move to the next line.
3267 lineStart = lineEnd;
3270 // Perform variable replacements.
3271 this->ExpandVariablesInString(output, escapeQuotes, true,
3272 atOnly, 0, -1, true);
3275 int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
3276 bool copyonly, bool atOnly, bool escapeQuotes,
3277 const cmNewLineStyle& newLine)
3280 if ( !this->CanIWriteThisFile(outfile) )
3282 cmSystemTools::Error("Attempt to write file: ",
3283 outfile, " into a source directory.");
3286 if ( !cmSystemTools::FileExists(infile) )
3288 cmSystemTools::Error("File ", infile, " does not exist.");
3291 std::string soutfile = outfile;
3292 std::string sinfile = infile;
3293 this->AddCMakeDependFile(infile);
3294 cmSystemTools::ConvertToUnixSlashes(soutfile);
3296 cmSystemTools::GetPermissions(sinfile.c_str(), perm);
3297 std::string::size_type pos = soutfile.rfind('/');
3298 if(pos != std::string::npos)
3300 std::string path = soutfile.substr(0, pos);
3301 cmSystemTools::MakeDirectory(path.c_str());
3306 if ( !cmSystemTools::CopyFileIfDifferent(sinfile.c_str(),
3314 std::string newLineCharacters;
3315 std::ios_base::openmode omode = std::ios_base::out | std::ios_base::trunc;
3316 if (newLine.IsValid())
3318 newLineCharacters = newLine.GetCharacters();
3319 omode |= std::ios::binary;
3323 newLineCharacters = "\n";
3325 std::string tempOutputFile = soutfile;
3326 tempOutputFile += ".tmp";
3327 std::ofstream fout(tempOutputFile.c_str(), omode);
3330 cmSystemTools::Error(
3331 "Could not open file for write in copy operation ",
3332 tempOutputFile.c_str());
3333 cmSystemTools::ReportLastSystemError("");
3336 std::ifstream fin(sinfile.c_str());
3339 cmSystemTools::Error("Could not open file for read in copy operation ",
3344 // now copy input to output and expand variables in the
3345 // input file at the same time
3347 std::string outLine;
3348 while( cmSystemTools::GetLineFromStream(fin, inLine) )
3351 this->ConfigureString(inLine, outLine, atOnly, escapeQuotes);
3352 fout << outLine.c_str() << newLineCharacters;
3354 // close the files before attempting to copy
3357 if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
3364 cmSystemTools::SetPermissions(soutfile.c_str(), perm);
3366 cmSystemTools::RemoveFile(tempOutputFile.c_str());
3371 void cmMakefile::SetProperty(const char* prop, const char* value)
3378 // handle special props
3379 std::string propname = prop;
3381 if ( propname == "LINK_DIRECTORIES" )
3383 std::vector<std::string> varArgsExpanded;
3386 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
3388 this->SetLinkDirectories(varArgsExpanded);
3392 if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
3394 this->SetIncludeRegularExpression(value);
3398 if ( propname == "ADDITIONAL_MAKE_CLEAN_FILES" )
3400 // This property is not inherrited
3401 if ( strcmp(this->GetCurrentDirectory(),
3402 this->GetStartDirectory()) != 0 )
3408 this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
3411 void cmMakefile::AppendProperty(const char* prop, const char* value,
3419 // handle special props
3420 std::string propname = prop;
3422 if ( propname == "LINK_DIRECTORIES" )
3424 std::vector<std::string> varArgsExpanded;
3425 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
3426 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
3427 vi != varArgsExpanded.end(); ++vi)
3429 this->AddLinkDirectory(vi->c_str());
3434 this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY,asString);
3437 const char *cmMakefile::GetPropertyOrDefinition(const char* prop)
3439 const char *ret = this->GetProperty(prop, cmProperty::DIRECTORY);
3442 ret = this->GetDefinition(prop);
3447 const char *cmMakefile::GetProperty(const char* prop)
3449 return this->GetProperty(prop, cmProperty::DIRECTORY);
3452 const char *cmMakefile::GetProperty(const char* prop,
3453 cmProperty::ScopeType scope)
3459 // watch for specific properties
3460 static std::string output;
3462 if (!strcmp("PARENT_DIRECTORY",prop))
3464 if(cmLocalGenerator* plg = this->LocalGenerator->GetParent())
3466 output = plg->GetMakefile()->GetStartDirectory();
3468 return output.c_str();
3470 else if (!strcmp("INCLUDE_REGULAR_EXPRESSION",prop) )
3472 output = this->GetIncludeRegularExpression();
3473 return output.c_str();
3475 else if (!strcmp("LISTFILE_STACK",prop))
3477 for (std::deque<cmStdString>::iterator i = this->ListFileStack.begin();
3478 i != this->ListFileStack.end(); ++i)
3480 if (i != this->ListFileStack.begin())
3486 return output.c_str();
3488 else if (!strcmp("VARIABLES",prop) || !strcmp("CACHE_VARIABLES",prop))
3491 if ( !strcmp("CACHE_VARIABLES",prop) )
3495 std::vector<std::string> vars = this->GetDefinitions(cacheonly);
3496 for (unsigned int cc = 0; cc < vars.size(); cc ++ )
3504 return output.c_str();
3506 else if (!strcmp("MACROS",prop))
3508 this->GetListOfMacros(output);
3509 return output.c_str();
3511 else if (!strcmp("DEFINITIONS",prop))
3513 output += this->DefineFlagsOrig;
3514 return output.c_str();
3516 else if (!strcmp("LINK_DIRECTORIES",prop))
3518 cmOStringStream str;
3519 for (std::vector<std::string>::const_iterator
3520 it = this->GetLinkDirectories().begin();
3521 it != this->GetLinkDirectories().end();
3524 if ( it != this->GetLinkDirectories().begin())
3531 return output.c_str();
3535 const char *retVal =
3536 this->Properties.GetPropertyValue(prop, scope, chain);
3539 if(this->LocalGenerator->GetParent())
3541 return this->LocalGenerator->GetParent()->GetMakefile()->
3542 GetProperty(prop, scope);
3544 return this->GetCMakeInstance()->GetProperty(prop,scope);
3550 bool cmMakefile::GetPropertyAsBool(const char* prop)
3552 return cmSystemTools::IsOn(this->GetProperty(prop));
3555 //----------------------------------------------------------------------------
3556 const char* cmMakefile::GetFeature(const char* feature, const char* config)
3558 // TODO: Define accumulation policy for features (prepend, append, replace).
3559 // Currently we always replace.
3560 if(config && *config)
3562 std::string featureConfig = feature;
3563 featureConfig += "_";
3564 featureConfig += cmSystemTools::UpperCase(config);
3565 if(const char* value = this->GetProperty(featureConfig.c_str()))
3570 if(const char* value = this->GetProperty(feature))
3574 if(cmLocalGenerator* parent = this->LocalGenerator->GetParent())
3576 return parent->GetMakefile()->GetFeature(feature, config);
3581 cmTarget* cmMakefile::FindTarget(const char* name)
3583 cmTargets& tgts = this->GetTargets();
3585 cmTargets::iterator i = tgts.find ( name );
3586 if ( i != tgts.end() )
3594 //----------------------------------------------------------------------------
3595 cmTest* cmMakefile::CreateTest(const char* testName)
3601 cmTest* test = this->GetTest(testName);
3606 test = new cmTest(this);
3607 test->SetName(testName);
3608 this->Tests[testName] = test;
3612 //----------------------------------------------------------------------------
3613 cmTest* cmMakefile::GetTest(const char* testName) const
3617 std::map<cmStdString, cmTest*>::const_iterator
3618 mi = this->Tests.find(testName);
3619 if(mi != this->Tests.end())
3627 std::string cmMakefile::GetListFileStack()
3629 cmOStringStream tmp;
3630 size_t depth = this->ListFileStack.size();
3633 std::deque<cmStdString>::iterator it = this->ListFileStack.end();
3636 if (depth != this->ListFileStack.size())
3647 while (it != this->ListFileStack.begin());
3653 void cmMakefile::PushScope()
3655 cmDefinitions* parent = &this->Internal->VarStack.top();
3656 const std::set<cmStdString>& init = this->Internal->VarInitStack.top();
3657 const std::set<cmStdString>& usage = this->Internal->VarUsageStack.top();
3658 this->Internal->VarStack.push(cmDefinitions(parent));
3659 this->Internal->VarInitStack.push(init);
3660 this->Internal->VarUsageStack.push(usage);
3663 void cmMakefile::PopScope()
3665 cmDefinitions* current = &this->Internal->VarStack.top();
3666 std::set<cmStdString> init = this->Internal->VarInitStack.top();
3667 std::set<cmStdString> usage = this->Internal->VarUsageStack.top();
3668 const std::set<cmStdString>& locals = current->LocalKeys();
3669 // Remove initialization and usage information for variables in the local
3671 std::set<cmStdString>::const_iterator it = locals.begin();
3672 for (; it != locals.end(); ++it)
3675 if (!this->VariableUsed(it->c_str()))
3677 this->CheckForUnused("out of scope", it->c_str());
3684 this->Internal->VarStack.pop();
3685 this->Internal->VarInitStack.pop();
3686 this->Internal->VarUsageStack.pop();
3687 // Push initialization and usage up to the parent scope.
3689 for (; it != init.end(); ++it)
3691 this->Internal->VarInitStack.top().insert(*it);
3694 for (; it != usage.end(); ++it)
3696 this->Internal->VarUsageStack.top().insert(*it);
3700 void cmMakefile::RaiseScope(const char *var, const char *varDef)
3702 if (!var || !strlen(var))
3707 cmDefinitions& cur = this->Internal->VarStack.top();
3708 if(cmDefinitions* up = cur.GetParent())
3710 // First localize the definition in the current scope.
3713 // Now update the definition in the parent scope.
3714 up->Set(var, varDef);
3716 else if(cmLocalGenerator* plg = this->LocalGenerator->GetParent())
3718 // Update the definition in the parent directory top scope. This
3719 // directory's scope was initialized by the closure of the parent
3720 // scope, so we do not need to localize the definition first.
3721 cmMakefile* parent = plg->GetMakefile();
3724 parent->AddDefinition(var, varDef);
3728 parent->RemoveDefinition(var);
3734 m << "Cannot set \"" << var << "\": current scope has no parent.";
3735 this->IssueMessage(cmake::AUTHOR_WARNING, m.str());
3740 // define properties
3741 void cmMakefile::DefineProperties(cmake *cm)
3744 ("ADDITIONAL_MAKE_CLEAN_FILES", cmProperty::DIRECTORY,
3745 "Additional files to clean during the make clean stage.",
3746 "A list of files that will be cleaned as a part of the "
3747 "\"make clean\" stage. ");
3750 ("CLEAN_NO_CUSTOM", cmProperty::DIRECTORY,
3751 "Should the output of custom commands be left.",
3752 "If this is true then the outputs of custom commands for this "
3753 "directory will not be removed during the \"make clean\" stage. ");
3756 ("LISTFILE_STACK", cmProperty::DIRECTORY,
3757 "The current stack of listfiles being processed.",
3758 "This property is mainly useful when trying to debug errors "
3759 "in your CMake scripts. It returns a list of what list files "
3760 "are currently being processed, in order. So if one listfile "
3761 "does an INCLUDE command then that is effectively pushing "
3762 "the included listfile onto the stack.", false);
3765 ("TEST_INCLUDE_FILE", cmProperty::DIRECTORY,
3766 "A cmake file that will be included when ctest is run.",
3767 "If you specify TEST_INCLUDE_FILE, that file will be "
3768 "included and processed when ctest is run on the directory.");
3771 ("COMPILE_DEFINITIONS", cmProperty::DIRECTORY,
3772 "Preprocessor definitions for compiling a directory's sources.",
3773 "The COMPILE_DEFINITIONS property may be set to a "
3774 "semicolon-separated list of preprocessor "
3775 "definitions using the syntax VAR or VAR=value. Function-style "
3776 "definitions are not supported. CMake will automatically escape "
3777 "the value correctly for the native build system (note that CMake "
3778 "language syntax may require escapes to specify some values). "
3779 "This property may be set on a per-configuration basis using the name "
3780 "COMPILE_DEFINITIONS_<CONFIG> where <CONFIG> is an upper-case name "
3781 "(ex. \"COMPILE_DEFINITIONS_DEBUG\"). "
3782 "This property will be initialized in each directory by its value "
3783 "in the directory's parent.\n"
3784 "CMake will automatically drop some definitions that "
3785 "are not supported by the native build tool. "
3786 "The VS6 IDE does not support definition values with spaces "
3787 "(but NMake does).\n"
3788 CM_DOCUMENT_COMPILE_DEFINITIONS_DISCLAIMER);
3791 ("COMPILE_DEFINITIONS_<CONFIG>", cmProperty::DIRECTORY,
3792 "Per-configuration preprocessor definitions in a directory.",
3793 "This is the configuration-specific version of COMPILE_DEFINITIONS. "
3794 "This property will be initialized in each directory by its value "
3795 "in the directory's parent.\n");
3798 ("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM", cmProperty::DIRECTORY,
3799 "Specify #include line transforms for dependencies in a directory.",
3800 "This property specifies rules to transform macro-like #include lines "
3801 "during implicit dependency scanning of C and C++ source files. "
3802 "The list of rules must be semicolon-separated with each entry of "
3803 "the form \"A_MACRO(%)=value-with-%\" (the % must be literal). "
3804 "During dependency scanning occurrences of A_MACRO(...) on #include "
3805 "lines will be replaced by the value given with the macro argument "
3806 "substituted for '%'. For example, the entry\n"
3807 " MYDIR(%)=<mydir/%>\n"
3808 "will convert lines of the form\n"
3809 " #include MYDIR(myheader.h)\n"
3811 " #include <mydir/myheader.h>\n"
3812 "allowing the dependency to be followed.\n"
3813 "This property applies to sources in all targets within a directory. "
3814 "The property value is initialized in each directory by its value "
3815 "in the directory's parent.");
3818 ("EXCLUDE_FROM_ALL", cmProperty::DIRECTORY,
3819 "Exclude the directory from the all target of its parent.",
3820 "A property on a directory that indicates if its targets are excluded "
3821 "from the default build target. If it is not, then with a Makefile "
3822 "for example typing make will cause the targets to be built. "
3823 "The same concept applies to the default build of other generators.",
3827 ("PARENT_DIRECTORY", cmProperty::DIRECTORY,
3828 "Source directory that added current subdirectory.",
3829 "This read-only property specifies the source directory that "
3830 "added the current source directory as a subdirectory of the build. "
3831 "In the top-level directory the value is the empty-string.", false);
3834 ("INCLUDE_REGULAR_EXPRESSION", cmProperty::DIRECTORY,
3835 "Include file scanning regular expression.",
3836 "This read-only property specifies the regular expression used "
3837 "during dependency scanning to match include files that should "
3838 "be followed. See the include_regular_expression command.", false);
3841 ("INTERPROCEDURAL_OPTIMIZATION", cmProperty::DIRECTORY,
3842 "Enable interprocedural optimization for targets in a directory.",
3843 "If set to true, enables interprocedural optimizations "
3844 "if they are known to be supported by the compiler.");
3847 ("INTERPROCEDURAL_OPTIMIZATION_<CONFIG>", cmProperty::DIRECTORY,
3848 "Per-configuration interprocedural optimization for a directory.",
3849 "This is a per-configuration version of INTERPROCEDURAL_OPTIMIZATION. "
3850 "If set, this property overrides the generic property "
3851 "for the named configuration.");
3854 ("VARIABLES", cmProperty::DIRECTORY,
3855 "List of variables defined in the current directory.",
3856 "This read-only property specifies the list of CMake variables "
3857 "currently defined. "
3858 "It is intended for debugging purposes.", false);
3861 ("CACHE_VARIABLES", cmProperty::DIRECTORY,
3862 "List of cache variables available in the current directory.",
3863 "This read-only property specifies the list of CMake cache "
3864 "variables currently defined. "
3865 "It is intended for debugging purposes.", false);
3868 ("MACROS", cmProperty::DIRECTORY,
3869 "List of macro commands available in the current directory.",
3870 "This read-only property specifies the list of CMake macros "
3871 "currently defined. "
3872 "It is intended for debugging purposes. "
3873 "See the macro command.", false);
3876 ("DEFINITIONS", cmProperty::DIRECTORY,
3877 "For CMake 2.4 compatibility only. Use COMPILE_DEFINITIONS instead.",
3878 "This read-only property specifies the list of flags given so far "
3879 "to the add_definitions command. "
3880 "It is intended for debugging purposes. "
3881 "Use the COMPILE_DEFINITIONS instead.", false);
3884 ("INCLUDE_DIRECTORIES", cmProperty::DIRECTORY,
3885 "List of preprocessor include file search directories.",
3886 "This property specifies the list of directories given "
3887 "so far to the include_directories command. "
3888 "This property exists on directories and targets. "
3889 "In addition to accepting values from the include_directories "
3890 "command, values may be set directly on any directory or any "
3891 "target using the set_property command. "
3892 "A target gets its initial value for this property from the value "
3893 "of the directory property. "
3894 "A directory gets its initial value from its parent directory if "
3896 "Both directory and target property values are adjusted by calls "
3897 "to the include_directories command."
3899 "The target property values are used by the generators to set "
3900 "the include paths for the compiler. "
3901 "See also the include_directories command.");
3904 ("LINK_DIRECTORIES", cmProperty::DIRECTORY,
3905 "List of linker search directories.",
3906 "This read-only property specifies the list of directories given "
3907 "so far to the link_directories command. "
3908 "It is intended for debugging purposes.", false);
3911 ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
3912 "Specify a launcher for compile rules.",
3913 "See the global property of the same name for details. "
3914 "This overrides the global property for a directory.",
3917 ("RULE_LAUNCH_LINK", cmProperty::DIRECTORY,
3918 "Specify a launcher for link rules.",
3919 "See the global property of the same name for details. "
3920 "This overrides the global property for a directory.",
3923 ("RULE_LAUNCH_CUSTOM", cmProperty::DIRECTORY,
3924 "Specify a launcher for custom rules.",
3925 "See the global property of the same name for details. "
3926 "This overrides the global property for a directory.",
3930 //----------------------------------------------------------------------------
3932 cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type,
3935 // Create the target.
3936 cmsys::auto_ptr<cmTarget> target(new cmTarget);
3937 target->SetType(type, name);
3938 target->SetMakefile(this);
3939 target->MarkAsImported();
3941 // Add to the set of available imported targets.
3942 this->ImportedTargets[name] = target.get();
3945 this->LocalGenerator->GetGlobalGenerator()->AddTarget(target.get());
3948 // Transfer ownership to this cmMakefile object.
3949 this->ImportedTargetsOwned.push_back(target.get());
3950 return target.release();
3953 //----------------------------------------------------------------------------
3954 cmTarget* cmMakefile::FindTargetToUse(const char* name)
3956 // Look for an imported target. These take priority because they
3957 // are more local in scope and do not have to be globally unique.
3958 std::map<cmStdString, cmTarget*>::const_iterator
3959 imported = this->ImportedTargets.find(name);
3960 if(imported != this->ImportedTargets.end())
3962 return imported->second;
3965 // Look for a target built in this directory.
3966 if(cmTarget* t = this->FindTarget(name))
3971 // Look for a target built in this project.
3972 return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name);
3975 //----------------------------------------------------------------------------
3976 bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
3979 if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
3981 // The name given conflicts with an existing target. Produce an
3982 // error in a compatible way.
3983 if(existing->IsImported())
3985 // Imported targets were not supported in previous versions.
3986 // This is new code, so we can make it an error.
3988 e << "cannot create target \"" << name
3989 << "\" because an imported target with the same name already exists.";
3995 // target names must be globally unique
3996 switch (this->GetPolicyStatus(cmPolicies::CMP0002))
3998 case cmPolicies::WARN:
3999 this->IssueMessage(cmake::AUTHOR_WARNING, this->GetPolicies()->
4000 GetPolicyWarning(cmPolicies::CMP0002));
4001 case cmPolicies::OLD:
4003 case cmPolicies::REQUIRED_IF_USED:
4004 case cmPolicies::REQUIRED_ALWAYS:
4005 this->IssueMessage(cmake::FATAL_ERROR,
4006 this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0002)
4009 case cmPolicies::NEW:
4013 // The conflict is with a non-imported target.
4014 // Allow this if the user has requested support.
4016 this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
4017 if(isCustom && existing->GetType() == cmTarget::UTILITY &&
4018 this != existing->GetMakefile() &&
4019 cm->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
4024 // Produce an error that tells the user how to work around the
4027 e << "cannot create target \"" << name
4028 << "\" because another target with the same name already exists. "
4029 << "The existing target is ";
4030 switch(existing->GetType())
4032 case cmTarget::EXECUTABLE:
4033 e << "an executable ";
4035 case cmTarget::STATIC_LIBRARY:
4036 e << "a static library ";
4038 case cmTarget::SHARED_LIBRARY:
4039 e << "a shared library ";
4041 case cmTarget::MODULE_LIBRARY:
4042 e << "a module library ";
4044 case cmTarget::UTILITY:
4045 e << "a custom target ";
4049 e << "created in source directory \""
4050 << existing->GetMakefile()->GetCurrentDirectory() << "\". "
4051 << "See documentation for policy CMP0002 for more details.";
4059 //----------------------------------------------------------------------------
4060 bool cmMakefile::EnforceUniqueDir(const char* srcPath, const char* binPath)
4062 // Make sure the binary directory is unique.
4063 cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
4064 if(gg->BinaryDirectoryIsNew(binPath))
4069 switch (this->GetPolicyStatus(cmPolicies::CMP0013))
4071 case cmPolicies::WARN:
4072 // Print the warning.
4073 e << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0013)
4075 << "The binary directory\n"
4076 << " " << binPath << "\n"
4077 << "is already used to build a source directory. "
4078 << "This command uses it to build source directory\n"
4079 << " " << srcPath << "\n"
4080 << "which can generate conflicting build files. "
4081 << "CMake does not support this use case but it used "
4082 << "to work accidentally and is being allowed for "
4083 << "compatibility.";
4084 this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
4085 case cmPolicies::OLD:
4086 // OLD behavior does not warn.
4088 case cmPolicies::REQUIRED_IF_USED:
4089 case cmPolicies::REQUIRED_ALWAYS:
4090 e << this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0013)
4092 case cmPolicies::NEW:
4093 // NEW behavior prints the error.
4094 e << "The binary directory\n"
4095 << " " << binPath << "\n"
4096 << "is already used to build a source directory. "
4097 << "It cannot be used to build source directory\n"
4098 << " " << srcPath << "\n"
4099 << "Specify a unique binary directory name.";
4100 this->IssueMessage(cmake::FATAL_ERROR, e.str());
4107 //----------------------------------------------------------------------------
4108 cmPolicies::PolicyStatus
4109 cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id)
4111 // Get the current setting of the policy.
4112 cmPolicies::PolicyStatus cur = this->GetPolicyStatusInternal(id);
4114 // If the policy is required to be set to NEW but is not, ignore the
4115 // current setting and tell the caller.
4116 if(cur != cmPolicies::NEW)
4118 if(cur == cmPolicies::REQUIRED_ALWAYS ||
4119 cur == cmPolicies::REQUIRED_IF_USED)
4123 cmPolicies::PolicyStatus def = this->GetPolicies()->GetPolicyStatus(id);
4124 if(def == cmPolicies::REQUIRED_ALWAYS ||
4125 def == cmPolicies::REQUIRED_IF_USED)
4131 // The current setting is okay.
4135 //----------------------------------------------------------------------------
4136 cmPolicies::PolicyStatus
4137 cmMakefile::GetPolicyStatusInternal(cmPolicies::PolicyID id)
4139 // Is the policy set in our stack?
4140 for(PolicyStackType::reverse_iterator psi = this->PolicyStack.rbegin();
4141 psi != this->PolicyStack.rend(); ++psi)
4143 PolicyStackEntry::const_iterator pse = psi->find(id);
4144 if(pse != psi->end())
4150 // If we have a parent directory, recurse up to it.
4151 if(this->LocalGenerator->GetParent())
4153 cmMakefile* parent = this->LocalGenerator->GetParent()->GetMakefile();
4154 return parent->GetPolicyStatusInternal(id);
4157 // The policy is not set. Use the default for this CMake version.
4158 return this->GetPolicies()->GetPolicyStatus(id);
4161 bool cmMakefile::SetPolicy(const char *id,
4162 cmPolicies::PolicyStatus status)
4164 cmPolicies::PolicyID pid;
4165 if (!this->GetPolicies()->GetPolicyID(id, /* out */ pid))
4168 e << "Policy \"" << id << "\" is not known to this version of CMake.";
4169 this->IssueMessage(cmake::FATAL_ERROR, e.str());
4172 return this->SetPolicy(pid,status);
4175 //----------------------------------------------------------------------------
4176 bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
4177 cmPolicies::PolicyStatus status)
4179 // A REQUIRED_ALWAYS policy may be set only to NEW.
4180 if(status != cmPolicies::NEW &&
4181 this->GetPolicies()->GetPolicyStatus(id) ==
4182 cmPolicies::REQUIRED_ALWAYS)
4185 this->GetPolicies()->GetRequiredAlwaysPolicyError(id);
4186 this->IssueMessage(cmake::FATAL_ERROR, msg.c_str());
4190 // Update the policy stack from the top to the top-most strong entry.
4191 bool previous_was_weak = true;
4192 for(PolicyStackType::reverse_iterator psi = this->PolicyStack.rbegin();
4193 previous_was_weak && psi != this->PolicyStack.rend(); ++psi)
4195 (*psi)[id] = status;
4196 previous_was_weak = psi->Weak;
4199 // Special hook for presenting compatibility variable as soon as
4200 // the user requests it.
4201 if(id == cmPolicies::CMP0001 &&
4202 (status == cmPolicies::WARN || status == cmPolicies::OLD))
4204 if(!(this->GetCacheManager()
4205 ->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
4207 // Set it to 2.4 because that is the last version where the
4208 // variable had meaning.
4209 this->AddCacheDefinition
4210 ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
4211 "For backwards compatibility, what version of CMake "
4213 "syntax should this version of CMake try to support.",
4214 cmCacheManager::STRING);
4221 //----------------------------------------------------------------------------
4222 cmMakefile::PolicyPushPop::PolicyPushPop(cmMakefile* m, bool weak,
4223 cmPolicies::PolicyMap const& pm):
4224 Makefile(m), ReportError(true)
4226 this->Makefile->PushPolicy(weak, pm);
4227 this->Makefile->PushPolicyBarrier();
4230 //----------------------------------------------------------------------------
4231 cmMakefile::PolicyPushPop::~PolicyPushPop()
4233 this->Makefile->PopPolicyBarrier(this->ReportError);
4234 this->Makefile->PopPolicy();
4237 //----------------------------------------------------------------------------
4238 void cmMakefile::PushPolicy(bool weak, cmPolicies::PolicyMap const& pm)
4240 // Allocate a new stack entry.
4241 this->PolicyStack.push_back(PolicyStackEntry(pm, weak));
4244 //----------------------------------------------------------------------------
4245 void cmMakefile::PopPolicy()
4247 if(this->PolicyStack.size() > this->PolicyBarriers.back())
4249 this->PolicyStack.pop_back();
4253 this->IssueMessage(cmake::FATAL_ERROR,
4254 "cmake_policy POP without matching PUSH");
4258 //----------------------------------------------------------------------------
4259 void cmMakefile::PushPolicyBarrier()
4261 this->PolicyBarriers.push_back(this->PolicyStack.size());
4264 //----------------------------------------------------------------------------
4265 void cmMakefile::PopPolicyBarrier(bool reportError)
4267 // Remove any extra entries pushed on the barrier.
4268 PolicyStackType::size_type barrier = this->PolicyBarriers.back();
4269 while(this->PolicyStack.size() > barrier)
4273 this->IssueMessage(cmake::FATAL_ERROR,
4274 "cmake_policy PUSH without matching POP");
4275 reportError = false;
4280 // Remove the barrier.
4281 this->PolicyBarriers.pop_back();
4284 bool cmMakefile::SetPolicyVersion(const char *version)
4286 return this->GetCMakeInstance()->GetPolicies()->
4287 ApplyPolicyVersion(this,version);
4290 cmPolicies *cmMakefile::GetPolicies()
4292 if (!this->GetCMakeInstance())
4296 return this->GetCMakeInstance()->GetPolicies();
4299 //----------------------------------------------------------------------------
4300 void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
4302 /* Record the setting of every policy. */
4303 typedef cmPolicies::PolicyID PolicyID;
4304 for(PolicyID pid = cmPolicies::CMP0000;
4305 pid != cmPolicies::CMPCOUNT; pid = PolicyID(pid+1))
4307 pm[pid] = this->GetPolicyStatus(pid);