Introduce "generator expressions" to add_test()
[cmake.git] / Source / cmMakefile.cxx
blob7c03d2f72c41ef300620b39d4206fa6128378283
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmMakefile.cxx,v $
5 Language: C++
6 Date: $Date: 2009-08-11 13:07:28 $
7 Version: $Revision: 1.517 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmMakefile.h"
18 #include "cmVersion.h"
19 #include "cmCommand.h"
20 #include "cmSourceFile.h"
21 #include "cmSourceFileLocation.h"
22 #include "cmSystemTools.h"
23 #include "cmGlobalGenerator.h"
24 #include "cmLocalGenerator.h"
25 #include "cmCommands.h"
26 #include "cmCacheManager.h"
27 #include "cmFunctionBlocker.h"
28 #include "cmListFileCache.h"
29 #include "cmCommandArgumentParserHelper.h"
30 #include "cmTest.h"
31 #ifdef CMAKE_BUILD_WITH_CMAKE
32 # include "cmVariableWatch.h"
33 #endif
34 #include "cmInstallGenerator.h"
35 #include "cmTestGenerator.h"
36 #include "cmDefinitions.h"
37 #include "cmake.h"
38 #include <stdlib.h> // required for atoi
40 #include <cmsys/RegularExpression.hxx>
42 #include <cmsys/auto_ptr.hxx>
44 #include <stack>
45 #include <ctype.h> // for isspace
47 class cmMakefile::Internals
49 public:
50 std::stack<cmDefinitions, std::list<cmDefinitions> > VarStack;
53 // default is not to be building executables
54 cmMakefile::cmMakefile(): Internal(new Internals)
56 this->Internal->VarStack.push(cmDefinitions());
58 // Setup the default include file regular expression (match everything).
59 this->IncludeFileRegularExpression = "^.*$";
60 // Setup the default include complaint regular expression (match nothing).
61 this->ComplainFileRegularExpression = "^$";
62 // Source and header file extensions that we can handle
64 // Set up a list of source and header extensions
65 // these are used to find files when the extension
66 // is not given
67 // The "c" extension MUST precede the "C" extension.
68 this->SourceFileExtensions.push_back( "c" );
69 this->SourceFileExtensions.push_back( "C" );
71 this->SourceFileExtensions.push_back( "c++" );
72 this->SourceFileExtensions.push_back( "cc" );
73 this->SourceFileExtensions.push_back( "cpp" );
74 this->SourceFileExtensions.push_back( "cxx" );
75 this->SourceFileExtensions.push_back( "m" );
76 this->SourceFileExtensions.push_back( "M" );
77 this->SourceFileExtensions.push_back( "mm" );
79 this->HeaderFileExtensions.push_back( "h" );
80 this->HeaderFileExtensions.push_back( "hh" );
81 this->HeaderFileExtensions.push_back( "h++" );
82 this->HeaderFileExtensions.push_back( "hm" );
83 this->HeaderFileExtensions.push_back( "hpp" );
84 this->HeaderFileExtensions.push_back( "hxx" );
85 this->HeaderFileExtensions.push_back( "in" );
86 this->HeaderFileExtensions.push_back( "txx" );
88 this->DefineFlags = " ";
89 this->LocalGenerator = 0;
91 this->AddDefaultDefinitions();
92 this->Initialize();
93 this->PreOrder = false;
96 cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals)
98 this->Internal->VarStack.push(mf.Internal->VarStack.top().Closure());
100 this->Prefix = mf.Prefix;
101 this->AuxSourceDirectories = mf.AuxSourceDirectories;
102 this->cmStartDirectory = mf.cmStartDirectory;
103 this->StartOutputDirectory = mf.StartOutputDirectory;
104 this->cmHomeDirectory = mf.cmHomeDirectory;
105 this->HomeOutputDirectory = mf.HomeOutputDirectory;
106 this->cmCurrentListFile = mf.cmCurrentListFile;
107 this->ProjectName = mf.ProjectName;
108 this->Targets = mf.Targets;
109 this->SourceFiles = mf.SourceFiles;
110 this->Tests = mf.Tests;
111 this->IncludeDirectories = mf.IncludeDirectories;
112 this->LinkDirectories = mf.LinkDirectories;
113 this->SystemIncludeDirectories = mf.SystemIncludeDirectories;
114 this->ListFiles = mf.ListFiles;
115 this->OutputFiles = mf.OutputFiles;
116 this->LinkLibraries = mf.LinkLibraries;
117 this->InstallGenerators = mf.InstallGenerators;
118 this->TestGenerators = mf.TestGenerators;
119 this->IncludeFileRegularExpression = mf.IncludeFileRegularExpression;
120 this->ComplainFileRegularExpression = mf.ComplainFileRegularExpression;
121 this->SourceFileExtensions = mf.SourceFileExtensions;
122 this->HeaderFileExtensions = mf.HeaderFileExtensions;
123 this->DefineFlags = mf.DefineFlags;
124 this->DefineFlagsOrig = mf.DefineFlagsOrig;
126 #if defined(CMAKE_BUILD_WITH_CMAKE)
127 this->SourceGroups = mf.SourceGroups;
128 #endif
130 this->LocalGenerator = mf.LocalGenerator;
131 this->FunctionBlockers = mf.FunctionBlockers;
132 this->DataMap = mf.DataMap;
133 this->MacrosMap = mf.MacrosMap;
134 this->SubDirectoryOrder = mf.SubDirectoryOrder;
135 this->Properties = mf.Properties;
136 this->PreOrder = mf.PreOrder;
137 this->ListFileStack = mf.ListFileStack;
138 this->Initialize();
141 //----------------------------------------------------------------------------
142 void cmMakefile::Initialize()
144 this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
145 this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
146 this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
148 // Enter a policy level for this directory.
149 this->PushPolicy();
151 // Protect the directory-level policies.
152 this->PushPolicyBarrier();
154 // By default the check is not done. It is enabled by
155 // cmListFileCache in the top level if necessary.
156 this->CheckCMP0000 = false;
159 unsigned int cmMakefile::GetCacheMajorVersion()
161 return this->GetCacheManager()->GetCacheMajorVersion();
164 unsigned int cmMakefile::GetCacheMinorVersion()
166 return this->GetCacheManager()->GetCacheMinorVersion();
169 bool cmMakefile::NeedCacheCompatibility(int major, int minor)
171 return this->GetCacheManager()->NeedCacheCompatibility(major, minor);
174 cmMakefile::~cmMakefile()
176 for(std::vector<cmInstallGenerator*>::iterator
177 i = this->InstallGenerators.begin();
178 i != this->InstallGenerators.end(); ++i)
180 delete *i;
182 for(std::vector<cmTestGenerator*>::iterator
183 i = this->TestGenerators.begin();
184 i != this->TestGenerators.end(); ++i)
186 delete *i;
188 for(std::vector<cmSourceFile*>::iterator i = this->SourceFiles.begin();
189 i != this->SourceFiles.end(); ++i)
191 delete *i;
193 for(std::map<cmStdString, cmTest*>::iterator i = this->Tests.begin();
194 i != this->Tests.end(); ++i)
196 delete i->second;
198 for(std::vector<cmTarget*>::iterator
199 i = this->ImportedTargetsOwned.begin();
200 i != this->ImportedTargetsOwned.end(); ++i)
202 delete *i;
204 for(unsigned int i=0; i < this->UsedCommands.size(); i++)
206 delete this->UsedCommands[i];
208 for(DataMapType::const_iterator d = this->DataMap.begin();
209 d != this->DataMap.end(); ++d)
211 if(d->second)
213 delete d->second;
216 std::vector<cmFunctionBlocker*>::iterator pos;
217 for (pos = this->FunctionBlockers.begin();
218 pos != this->FunctionBlockers.end(); ++pos)
220 cmFunctionBlocker* b = *pos;
221 delete b;
223 this->FunctionBlockers.clear();
224 if (this->PolicyStack.size() != 1)
226 cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
227 " popped properly");
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();
236 i != v.end(); ++i)
238 std::cout << (*i).c_str() << " ";
240 std::cout << " )\n";
243 void cmMakefile
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;
253 std::cout << " )\n";
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->IncludeDirectories;",
281 this->IncludeDirectories);
282 this->PrintStringVector("this->LinkDirectories", this->LinkDirectories);
283 #if defined(CMAKE_BUILD_WITH_CMAKE)
284 for( std::vector<cmSourceGroup>::const_iterator i =
285 this->SourceGroups.begin(); i != this->SourceGroups.end(); ++i)
287 std::cout << "Source Group: " << i->GetName() << std::endl;
289 #endif
292 bool cmMakefile::CommandExists(const char* name) const
294 return this->GetCMakeInstance()->CommandExists(name);
298 //----------------------------------------------------------------------------
299 void cmMakefile::IssueMessage(cmake::MessageType t,
300 std::string const& text) const
302 // Collect context information.
303 cmListFileBacktrace backtrace;
304 if(!this->CallStack.empty())
306 if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR))
308 this->CallStack.back().Status->SetNestedError(true);
310 this->GetBacktrace(backtrace);
312 else
314 cmListFileContext lfc;
315 if(this->ListFileStack.empty())
317 // We are not processing the project. Add the directory-level context.
318 lfc.FilePath = this->GetCurrentDirectory();
319 lfc.FilePath += "/CMakeLists.txt";
321 else
323 // We are processing the project but are not currently executing a
324 // command. Add whatever context information we have.
325 lfc.FilePath = this->ListFileStack.back();
327 lfc.Line = 0;
328 if(!this->GetCMakeInstance()->GetIsInTryCompile())
330 lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath.c_str(),
331 cmLocalGenerator::HOME);
333 backtrace.push_back(lfc);
336 // Issue the message.
337 this->GetCMakeInstance()->IssueMessage(t, text, backtrace);
340 //----------------------------------------------------------------------------
341 bool cmMakefile::GetBacktrace(cmListFileBacktrace& backtrace) const
343 if(this->CallStack.empty())
345 return false;
347 for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
348 i != this->CallStack.rend(); ++i)
350 cmListFileContext lfc = *(*i).Context;
351 lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath.c_str(),
352 cmLocalGenerator::HOME);
353 backtrace.push_back(lfc);
355 return true;
358 //----------------------------------------------------------------------------
359 bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
360 cmExecutionStatus &status)
362 bool result = true;
364 // quick return if blocked
365 if(this->IsFunctionBlocked(lff,status))
367 // No error.
368 return result;
371 std::string name = lff.Name;
373 // Place this call on the call stack.
374 cmMakefileCall stack_manager(this, lff, status);
375 static_cast<void>(stack_manager);
377 // Lookup the command prototype.
378 if(cmCommand* proto = this->GetCMakeInstance()->GetCommand(name.c_str()))
380 // Clone the prototype.
381 cmsys::auto_ptr<cmCommand> pcmd(proto->Clone());
382 pcmd->SetMakefile(this);
384 // Decide whether to invoke the command.
385 if(pcmd->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() &&
386 (!this->GetCMakeInstance()->GetScriptMode() || pcmd->IsScriptable()))
388 // if trace is one, print out invoke information
389 if(this->GetCMakeInstance()->GetTrace())
391 cmOStringStream msg;
392 msg << lff.FilePath << "(" << lff.Line << "): ";
393 msg << lff.Name << "(";
394 for(std::vector<cmListFileArgument>::const_iterator i =
395 lff.Arguments.begin(); i != lff.Arguments.end(); ++i)
397 msg << i->Value;
398 msg << " ";
400 msg << ")";
401 cmSystemTools::Message(msg.str().c_str());
403 // Try invoking the command.
404 if(!pcmd->InvokeInitialPass(lff.Arguments,status) ||
405 status.GetNestedError())
407 if(!status.GetNestedError())
409 // The command invocation requested that we report an error.
410 this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError());
412 result = false;
413 if ( this->GetCMakeInstance()->GetScriptMode() )
415 cmSystemTools::SetFatalErrorOccured();
418 else if(pcmd->HasFinalPass())
420 // use the command
421 this->UsedCommands.push_back(pcmd.release());
424 else if ( this->GetCMakeInstance()->GetScriptMode()
425 && !pcmd->IsScriptable() )
427 std::string error = "Command ";
428 error += pcmd->GetName();
429 error += "() is not scriptable";
430 this->IssueMessage(cmake::FATAL_ERROR, error);
431 result = false;
432 cmSystemTools::SetFatalErrorOccured();
435 else
437 if(!cmSystemTools::GetFatalErrorOccured())
439 std::string error = "Unknown CMake command \"";
440 error += lff.Name;
441 error += "\".";
442 this->IssueMessage(cmake::FATAL_ERROR, error);
443 result = false;
444 cmSystemTools::SetFatalErrorOccured();
448 return result;
451 //----------------------------------------------------------------------------
452 class cmMakefile::IncludeScope
454 public:
455 IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope);
456 ~IncludeScope();
457 void Quiet() { this->ReportError = false; }
458 private:
459 cmMakefile* Makefile;
460 const char* File;
461 bool NoPolicyScope;
462 bool CheckCMP0011;
463 bool ReportError;
464 void EnforceCMP0011();
467 //----------------------------------------------------------------------------
468 cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
469 bool noPolicyScope):
470 Makefile(mf), File(fname), NoPolicyScope(noPolicyScope),
471 CheckCMP0011(false), ReportError(true)
473 if(!this->NoPolicyScope)
475 // Check CMP0011 to determine the policy scope type.
476 switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
478 case cmPolicies::WARN:
479 // We need to push a scope to detect whether the script sets
480 // any policies that would affect the includer and therefore
481 // requires a warning. We use a weak scope to simulate OLD
482 // behavior by allowing policy changes to affect the includer.
483 this->Makefile->PushPolicy(true);
484 this->CheckCMP0011 = true;
485 break;
486 case cmPolicies::OLD:
487 // OLD behavior is to not push a scope at all.
488 this->NoPolicyScope = true;
489 break;
490 case cmPolicies::REQUIRED_IF_USED:
491 case cmPolicies::REQUIRED_ALWAYS:
492 // We should never make this policy required, but we handle it
493 // here just in case.
494 this->CheckCMP0011 = true;
495 case cmPolicies::NEW:
496 // NEW behavior is to push a (strong) scope.
497 this->Makefile->PushPolicy();
498 break;
502 // The included file cannot pop our policy scope.
503 this->Makefile->PushPolicyBarrier();
506 //----------------------------------------------------------------------------
507 cmMakefile::IncludeScope::~IncludeScope()
509 // Enforce matching policy scopes inside the included file.
510 this->Makefile->PopPolicyBarrier(this->ReportError);
512 if(!this->NoPolicyScope)
514 // If we need to enforce policy CMP0011 then the top entry is the
515 // one we pushed above. If the entry is empty, then the included
516 // script did not set any policies that might affect the includer so
517 // we do not need to enforce the policy.
518 if(this->CheckCMP0011 && this->Makefile->PolicyStack.back().empty())
520 this->CheckCMP0011 = false;
523 // Pop the scope we pushed for the script.
524 this->Makefile->PopPolicy();
526 // We enforce the policy after the script's policy stack entry has
527 // been removed.
528 if(this->CheckCMP0011)
530 this->EnforceCMP0011();
535 //----------------------------------------------------------------------------
536 void cmMakefile::IncludeScope::EnforceCMP0011()
538 // We check the setting of this policy again because the included
539 // script might actually set this policy for its includer.
540 cmPolicies* policies = this->Makefile->GetPolicies();
541 switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
543 case cmPolicies::WARN:
544 // Warn because the user did not set this policy.
546 cmOStringStream w;
547 w << policies->GetPolicyWarning(cmPolicies::CMP0011) << "\n"
548 << "The included script\n " << this->File << "\n"
549 << "affects policy settings. "
550 << "CMake is implying the NO_POLICY_SCOPE option for compatibility, "
551 << "so the effects are applied to the including context.";
552 this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
554 break;
555 case cmPolicies::REQUIRED_IF_USED:
556 case cmPolicies::REQUIRED_ALWAYS:
558 cmOStringStream e;
559 e << policies->GetRequiredPolicyError(cmPolicies::CMP0011) << "\n"
560 << "The included script\n " << this->File << "\n"
561 << "affects policy settings, so it requires this policy to be set.";
562 this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
564 break;
565 case cmPolicies::OLD:
566 case cmPolicies::NEW:
567 // The script set this policy. We assume the purpose of the
568 // script is to initialize policies for its includer, and since
569 // the policy is now set for later scripts, we do not warn.
570 break;
574 //----------------------------------------------------------------------------
575 // Parse the given CMakeLists.txt file executing all commands
577 bool cmMakefile::ReadListFile(const char* filename_in,
578 const char *external_in,
579 std::string* fullPath,
580 bool noPolicyScope)
582 std::string currentParentFile
583 = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
584 std::string currentFile
585 = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
586 this->AddDefinition("CMAKE_PARENT_LIST_FILE", filename_in);
588 const char* external = 0;
589 std::string external_abs;
591 const char* filename = filename_in;
592 std::string filename_abs;
594 if (external_in)
596 external_abs =
597 cmSystemTools::CollapseFullPath(external_in,
598 this->cmStartDirectory.c_str());
599 external = external_abs.c_str();
600 if (filename_in)
602 filename_abs =
603 cmSystemTools::CollapseFullPath(filename_in,
604 this->cmStartDirectory.c_str());
605 filename = filename_abs.c_str();
609 // keep track of the current file being read
610 if (filename)
612 if(this->cmCurrentListFile != filename)
614 this->cmCurrentListFile = filename;
618 // Now read the input file
619 const char *filenametoread= filename;
621 if( external)
623 filenametoread= external;
626 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
628 // try to see if the list file is the top most
629 // list file for a project, and if it is, then it
630 // must have a project command. If there is not
631 // one, then cmake will provide one via the
632 // cmListFileCache class.
633 bool requireProjectCommand = false;
634 if(!external && this->cmStartDirectory == this->cmHomeDirectory)
636 if(cmSystemTools::LowerCase(
637 cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt")
639 requireProjectCommand = true;
643 // push the listfile onto the stack
644 this->ListFileStack.push_back(filenametoread);
645 if(fullPath!=0)
647 *fullPath=filenametoread;
649 cmListFile cacheFile;
650 if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
652 // pop the listfile off the stack
653 this->ListFileStack.pop_back();
654 if(fullPath!=0)
656 *fullPath = "";
658 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
659 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
660 return false;
662 // add this list file to the list of dependencies
663 this->ListFiles.push_back( filenametoread);
665 // Enforce balanced blocks (if/endif, function/endfunction, etc.).
667 LexicalPushPop lexScope(this);
668 IncludeScope incScope(this, filenametoread, noPolicyScope);
670 // Run the parsed commands.
671 const size_t numberFunctions = cacheFile.Functions.size();
672 for(size_t i =0; i < numberFunctions; ++i)
674 cmExecutionStatus status;
675 this->ExecuteCommand(cacheFile.Functions[i],status);
676 if(cmSystemTools::GetFatalErrorOccured())
678 // Exit early due to error.
679 lexScope.Quiet();
680 incScope.Quiet();
681 break;
683 if(status.GetReturnInvoked())
685 // Exit early due to return command.
686 break;
691 // If this is the directory-level CMakeLists.txt file then perform
692 // some extra checks.
693 if(this->ListFileStack.size() == 1)
695 this->EnforceDirectoryLevelRules();
698 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
699 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
701 // pop the listfile off the stack
702 this->ListFileStack.pop_back();
704 return true;
707 //----------------------------------------------------------------------------
708 void cmMakefile::EnforceDirectoryLevelRules()
710 // Diagnose a violation of CMP0000 if necessary.
711 if(this->CheckCMP0000)
713 cmOStringStream msg;
714 msg << "No cmake_minimum_required command is present. "
715 << "A line of code such as\n"
716 << " cmake_minimum_required(VERSION "
717 << cmVersion::GetMajorVersion() << "."
718 << cmVersion::GetMinorVersion()
719 << ")\n"
720 << "should be added at the top of the file. "
721 << "The version specified may be lower if you wish to "
722 << "support older CMake versions for this project. "
723 << "For more information run "
724 << "\"cmake --help-policy CMP0000\".";
725 switch (this->GetPolicyStatus(cmPolicies::CMP0000))
727 case cmPolicies::WARN:
728 // Warn because the user did not provide a mimimum required
729 // version.
730 this->IssueMessage(cmake::AUTHOR_WARNING, msg.str().c_str());
731 case cmPolicies::OLD:
732 // OLD behavior is to use policy version 2.4 set in
733 // cmListFileCache.
734 break;
735 case cmPolicies::REQUIRED_IF_USED:
736 case cmPolicies::REQUIRED_ALWAYS:
737 case cmPolicies::NEW:
738 // NEW behavior is to issue an error.
739 this->IssueMessage(cmake::FATAL_ERROR, msg.str().c_str());
740 cmSystemTools::SetFatalErrorOccured();
741 return;
746 void cmMakefile::AddCommand(cmCommand* wg)
748 this->GetCMakeInstance()->AddCommand(wg);
751 // Set the make file
752 void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
754 this->LocalGenerator = lg;
755 // the source groups need to access the global generator
756 // so don't create them until the lg is set
757 #if defined(CMAKE_BUILD_WITH_CMAKE)
758 this->AddSourceGroup("", "^.*$");
759 this->AddSourceGroup
760 ("Source Files",
761 "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|f|f90|for|fpp"
762 "|ftn|m|mm|rc|def|r|odl|idl|hpj|bat)$");
763 this->AddSourceGroup("Header Files",
764 "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
765 this->AddSourceGroup("CMake Rules", "\\.rule$");
766 this->AddSourceGroup("Resources", "\\.plist$");
767 #endif
771 bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
772 unsigned int minor,
773 unsigned int patch)
775 if(this->LocalGenerator)
777 return
778 this->LocalGenerator->NeedBackwardsCompatibility(major, minor, patch);
780 else
782 return false;
786 void cmMakefile::FinalPass()
788 // do all the variable expansions here
789 this->ExpandVariables();
791 // give all the commands a chance to do something
792 // after the file has been parsed before generation
793 for(std::vector<cmCommand*>::iterator i = this->UsedCommands.begin();
794 i != this->UsedCommands.end(); ++i)
796 (*i)->FinalPass();
801 // Generate the output file
802 void cmMakefile::ConfigureFinalPass()
804 this->FinalPass();
805 const char* oldValue
806 = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
807 if (oldValue && atof(oldValue) <= 1.2)
809 cmSystemTools::Error("You have requested backwards compatibility "
810 "with CMake version 1.2 or earlier. This version "
811 "of CMake only supports backwards compatibility "
812 "with CMake 1.4 or later. For compatibility with "
813 "1.2 or earlier please use CMake 2.0");
815 for (cmTargets::iterator l = this->Targets.begin();
816 l != this->Targets.end(); l++)
818 l->second.AnalyzeLibDependencies(*this);
822 //----------------------------------------------------------------------------
823 void
824 cmMakefile::AddCustomCommandToTarget(const char* target,
825 const std::vector<std::string>& depends,
826 const cmCustomCommandLines& commandLines,
827 cmTarget::CustomCommandType type,
828 const char* comment,
829 const char* workingDir,
830 bool escapeOldStyle)
832 // Find the target to which to add the custom command.
833 cmTargets::iterator ti = this->Targets.find(target);
834 if(ti != this->Targets.end())
836 // Add the command to the appropriate build step for the target.
837 std::vector<std::string> no_output;
838 cmCustomCommand cc(no_output, depends, commandLines, comment, workingDir);
839 cc.SetEscapeOldStyle(escapeOldStyle);
840 cc.SetEscapeAllowMakeVars(true);
841 switch(type)
843 case cmTarget::PRE_BUILD:
844 ti->second.GetPreBuildCommands().push_back(cc);
845 break;
846 case cmTarget::PRE_LINK:
847 ti->second.GetPreLinkCommands().push_back(cc);
848 break;
849 case cmTarget::POST_BUILD:
850 ti->second.GetPostBuildCommands().push_back(cc);
851 break;
856 //----------------------------------------------------------------------------
857 void
858 cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
859 const std::vector<std::string>& depends,
860 const char* main_dependency,
861 const cmCustomCommandLines& commandLines,
862 const char* comment,
863 const char* workingDir,
864 bool replace,
865 bool escapeOldStyle)
867 // Make sure there is at least one output.
868 if(outputs.empty())
870 cmSystemTools::Error("Attempt to add a custom rule with no output!");
871 return;
874 // Choose a source file on which to store the custom command.
875 cmSourceFile* file = 0;
876 if(main_dependency && main_dependency[0])
878 // The main dependency was specified. Use it unless a different
879 // custom command already used it.
880 file = this->GetSource(main_dependency);
881 if(file && file->GetCustomCommand() && !replace)
883 // The main dependency already has a custom command.
884 if(commandLines == file->GetCustomCommand()->GetCommandLines())
886 // The existing custom command is identical. Silently ignore
887 // the duplicate.
888 return;
890 else
892 // The existing custom command is different. We need to
893 // generate a rule file for this new command.
894 file = 0;
897 else
899 // The main dependency does not have a custom command or we are
900 // allowed to replace it. Use it to store the command.
901 file = this->GetOrCreateSource(main_dependency);
905 // Generate a rule file if the main dependency is not available.
906 if(!file)
908 // Construct a rule file associated with the first output produced.
909 std::string outName = outputs[0];
910 outName += ".rule";
911 // Check if the rule file already exists.
912 file = this->GetSource(outName.c_str());
913 if(file && file->GetCustomCommand() && !replace)
915 // The rule file already exists.
916 if(commandLines != file->GetCustomCommand()->GetCommandLines())
918 cmSystemTools::Error("Attempt to add a custom rule to output \"",
919 outName.c_str(),
920 "\" which already has a custom rule.");
922 return;
925 // Create a cmSourceFile for the rule file.
926 file = this->GetOrCreateSource(outName.c_str(), true);
929 // Always create the output sources and mark them generated.
930 for(std::vector<std::string>::const_iterator o = outputs.begin();
931 o != outputs.end(); ++o)
933 if(cmSourceFile* out = this->GetOrCreateSource(o->c_str(), true))
935 out->SetProperty("GENERATED", "1");
939 // Construct a complete list of dependencies.
940 std::vector<std::string> depends2(depends);
941 if(main_dependency && main_dependency[0])
943 depends2.push_back(main_dependency);
946 // Attach the custom command to the file.
947 if(file)
949 cmCustomCommand* cc =
950 new cmCustomCommand(outputs, depends2, commandLines,
951 comment, workingDir);
952 cc->SetEscapeOldStyle(escapeOldStyle);
953 cc->SetEscapeAllowMakeVars(true);
954 file->SetCustomCommand(cc);
958 //----------------------------------------------------------------------------
959 void
960 cmMakefile::AddCustomCommandToOutput(const char* output,
961 const std::vector<std::string>& depends,
962 const char* main_dependency,
963 const cmCustomCommandLines& commandLines,
964 const char* comment,
965 const char* workingDir,
966 bool replace,
967 bool escapeOldStyle)
969 std::vector<std::string> outputs;
970 outputs.push_back(output);
971 this->AddCustomCommandToOutput(outputs, depends, main_dependency,
972 commandLines, comment, workingDir,
973 replace, escapeOldStyle);
976 //----------------------------------------------------------------------------
977 void
978 cmMakefile::AddCustomCommandOldStyle(const char* target,
979 const std::vector<std::string>& outputs,
980 const std::vector<std::string>& depends,
981 const char* source,
982 const cmCustomCommandLines& commandLines,
983 const char* comment)
985 // Translate the old-style signature to one of the new-style
986 // signatures.
987 if(strcmp(source, target) == 0)
989 // In the old-style signature if the source and target were the
990 // same then it added a post-build rule to the target. Preserve
991 // this behavior.
992 this->AddCustomCommandToTarget(target, depends, commandLines,
993 cmTarget::POST_BUILD, comment, 0);
994 return;
997 // Each output must get its own copy of this rule.
998 cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|"
999 "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
1000 "hm|hpp|hxx|in|txx|inl)$");
1001 for(std::vector<std::string>::const_iterator oi = outputs.begin();
1002 oi != outputs.end(); ++oi)
1004 // Get the name of this output.
1005 const char* output = oi->c_str();
1007 // Choose whether to use a main dependency.
1008 if(sourceFiles.find(source))
1010 // The source looks like a real file. Use it as the main dependency.
1011 this->AddCustomCommandToOutput(output, depends, source,
1012 commandLines, comment, 0);
1014 else
1016 // The source may not be a real file. Do not use a main dependency.
1017 const char* no_main_dependency = 0;
1018 std::vector<std::string> depends2 = depends;
1019 depends2.push_back(source);
1020 this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
1021 commandLines, comment, 0);
1024 // If the rule was added to the source (and not a .rule file),
1025 // then add the source to the target to make sure the rule is
1026 // included.
1027 std::string sname = output;
1028 sname += ".rule";
1029 if(!this->GetSource(sname.c_str()))
1031 if (this->Targets.find(target) != this->Targets.end())
1033 this->Targets[target].AddSource(source);
1035 else
1037 cmSystemTools::Error("Attempt to add a custom rule to a target "
1038 "that does not exist yet for target ", target);
1039 return;
1045 //----------------------------------------------------------------------------
1046 void cmMakefile::AddUtilityCommand(const char* utilityName,
1047 bool excludeFromAll,
1048 const std::vector<std::string>& depends,
1049 const char* workingDirectory,
1050 const char* command,
1051 const char* arg1,
1052 const char* arg2,
1053 const char* arg3,
1054 const char* arg4)
1056 // Construct the command line for the custom command.
1057 cmCustomCommandLine commandLine;
1058 commandLine.push_back(command);
1059 if(arg1)
1061 commandLine.push_back(arg1);
1063 if(arg2)
1065 commandLine.push_back(arg2);
1067 if(arg3)
1069 commandLine.push_back(arg3);
1071 if(arg4)
1073 commandLine.push_back(arg4);
1075 cmCustomCommandLines commandLines;
1076 commandLines.push_back(commandLine);
1078 // Call the real signature of this method.
1079 this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
1080 depends, commandLines);
1083 //----------------------------------------------------------------------------
1084 cmTarget*
1085 cmMakefile::AddUtilityCommand(const char* utilityName,
1086 bool excludeFromAll,
1087 const char* workingDirectory,
1088 const std::vector<std::string>& depends,
1089 const cmCustomCommandLines& commandLines,
1090 bool escapeOldStyle, const char* comment)
1092 // Create a target instance for this utility.
1093 cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
1094 if (excludeFromAll)
1096 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1098 if(!comment)
1100 // Use an empty comment to avoid generation of default comment.
1101 comment = "";
1104 // Store the custom command in the target.
1105 std::string force = this->GetStartOutputDirectory();
1106 force += cmake::GetCMakeFilesDirectory();
1107 force += "/";
1108 force += utilityName;
1109 const char* no_main_dependency = 0;
1110 bool no_replace = false;
1111 this->AddCustomCommandToOutput(force.c_str(), depends,
1112 no_main_dependency,
1113 commandLines, comment,
1114 workingDirectory, no_replace,
1115 escapeOldStyle);
1116 cmSourceFile* sf = target->AddSource(force.c_str());
1118 // The output is not actually created so mark it symbolic.
1119 if(sf)
1121 sf->SetProperty("SYMBOLIC", "1");
1123 else
1125 cmSystemTools::Error("Could not get source file entry for ",
1126 force.c_str());
1128 return target;
1131 void cmMakefile::AddDefineFlag(const char* flag)
1133 if (!flag)
1135 return;
1138 // Update the string used for the old DEFINITIONS property.
1139 this->AddDefineFlag(flag, this->DefineFlagsOrig);
1141 // If this is really a definition, update COMPILE_DEFINITIONS.
1142 if(this->ParseDefineFlag(flag, false))
1144 return;
1147 // Add this flag that does not look like a definition.
1148 this->AddDefineFlag(flag, this->DefineFlags);
1151 void cmMakefile::AddDefineFlag(const char* flag, std::string& dflags)
1153 // remove any \n\r
1154 std::string ret = flag;
1155 std::string::size_type pos = 0;
1156 while((pos = ret.find('\n', pos)) != std::string::npos)
1158 ret[pos] = ' ';
1159 pos++;
1161 pos = 0;
1162 while((pos = ret.find('\r', pos)) != std::string::npos)
1164 ret[pos] = ' ';
1165 pos++;
1168 dflags += " ";
1169 dflags += ret;
1173 void cmMakefile::RemoveDefineFlag(const char* flag)
1175 // Check the length of the flag to remove.
1176 std::string::size_type len = strlen(flag);
1177 if(len < 1)
1179 return;
1182 // Update the string used for the old DEFINITIONS property.
1183 this->RemoveDefineFlag(flag, len, this->DefineFlagsOrig);
1185 // If this is really a definition, update COMPILE_DEFINITIONS.
1186 if(this->ParseDefineFlag(flag, true))
1188 return;
1191 // Remove this flag that does not look like a definition.
1192 this->RemoveDefineFlag(flag, len, this->DefineFlags);
1195 void cmMakefile::RemoveDefineFlag(const char* flag,
1196 std::string::size_type len,
1197 std::string& dflags)
1199 // Remove all instances of the flag that are surrounded by
1200 // whitespace or the beginning/end of the string.
1201 for(std::string::size_type lpos = dflags.find(flag, 0);
1202 lpos != std::string::npos; lpos = dflags.find(flag, lpos))
1204 std::string::size_type rpos = lpos + len;
1205 if((lpos <= 0 || isspace(dflags[lpos-1])) &&
1206 (rpos >= dflags.size() || isspace(dflags[rpos])))
1208 dflags.erase(lpos, len);
1210 else
1212 ++lpos;
1217 bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
1219 // Create a regular expression to match valid definitions.
1220 static cmsys::RegularExpression
1221 valid("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=.*)?$");
1223 // Make sure the definition matches.
1224 if(!valid.find(def.c_str()))
1226 return false;
1229 // VS6 IDE does not support definition values with spaces in
1230 // combination with '"', '$', or ';'.
1231 if((strcmp(this->LocalGenerator->GetGlobalGenerator()->GetName(),
1232 "Visual Studio 6") == 0) &&
1233 (def.find(" ") != def.npos && def.find_first_of("\"$;") != def.npos))
1235 return false;
1238 // Definitions with non-trivial values require a policy check.
1239 static cmsys::RegularExpression
1240 trivial("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=[A-Za-z0-9_.]+)?$");
1241 if(!trivial.find(def.c_str()))
1243 // This definition has a non-trivial value.
1244 switch(this->GetPolicyStatus(cmPolicies::CMP0005))
1246 case cmPolicies::WARN:
1247 this->IssueMessage(
1248 cmake::AUTHOR_WARNING,
1249 this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0005)
1251 case cmPolicies::OLD:
1252 // OLD behavior is to not escape the value. We should not
1253 // convert the definition to use the property.
1254 return false;
1255 case cmPolicies::REQUIRED_IF_USED:
1256 case cmPolicies::REQUIRED_ALWAYS:
1257 this->IssueMessage(
1258 cmake::FATAL_ERROR,
1259 this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0005)
1261 return false;
1262 case cmPolicies::NEW:
1263 // NEW behavior is to escape the value. Proceed to convert it
1264 // to an entry in the property.
1265 break;
1269 // Get the definition part after the flag.
1270 const char* define = def.c_str() + 2;
1272 if(remove)
1274 if(const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS"))
1276 // Expand the list.
1277 std::vector<std::string> defs;
1278 cmSystemTools::ExpandListArgument(cdefs, defs);
1280 // Recompose the list without the definition.
1281 std::string ndefs;
1282 const char* sep = "";
1283 for(std::vector<std::string>::const_iterator di = defs.begin();
1284 di != defs.end(); ++di)
1286 if(*di != define)
1288 ndefs += sep;
1289 sep = ";";
1290 ndefs += *di;
1294 // Store the new list.
1295 this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
1298 else
1300 // Append the definition to the directory property.
1301 this->AppendProperty("COMPILE_DEFINITIONS", define);
1304 return true;
1307 void cmMakefile::AddLinkLibrary(const char* lib,
1308 cmTarget::LinkLibraryType llt)
1310 cmTarget::LibraryID tmp;
1311 tmp.first = lib;
1312 tmp.second = llt;
1313 this->LinkLibraries.push_back(tmp);
1316 void cmMakefile::AddLinkLibraryForTarget(const char *target,
1317 const char* lib,
1318 cmTarget::LinkLibraryType llt)
1320 cmTargets::iterator i = this->Targets.find(target);
1321 if ( i != this->Targets.end())
1323 cmTarget* tgt =
1324 this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib);
1325 if(tgt)
1327 // CMake versions below 2.4 allowed linking to modules.
1328 bool allowModules = this->NeedBackwardsCompatibility(2,2);
1329 // if it is not a static or shared library then you can not link to it
1330 if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
1331 (tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
1332 tgt->IsExecutableWithExports()))
1334 cmOStringStream e;
1335 e << "Target \"" << lib << "\" of type "
1336 << cmTarget::TargetTypeNames[static_cast<int>(tgt->GetType())]
1337 << " may not be linked into another target. "
1338 << "One may link only to STATIC or SHARED libraries, or "
1339 << "to executables with the ENABLE_EXPORTS property set.";
1340 // in older versions of cmake linking to modules was allowed
1341 if( tgt->GetType() == cmTarget::MODULE_LIBRARY )
1343 e << "\n"
1344 << "If you are developing a new project, re-organize it to avoid "
1345 << "linking to modules. "
1346 << "If you are just trying to build an existing project, "
1347 << "set CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower to allow "
1348 << "linking to modules.";
1350 // if no modules are allowed then this is always an error
1351 if(!allowModules ||
1352 // if we allow modules but the type is not a module then it is
1353 // still an error
1354 (allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY))
1356 this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
1360 i->second.AddLinkLibrary( *this, target, lib, llt );
1362 else
1364 cmOStringStream e;
1365 e << "Attempt to add link library \""
1366 << lib << "\" to target \""
1367 << target << "\" which is not built by this project.";
1368 cmSystemTools::Error(e.str().c_str());
1372 void cmMakefile::AddLinkDirectoryForTarget(const char *target,
1373 const char* d)
1375 cmTargets::iterator i = this->Targets.find(target);
1376 if ( i != this->Targets.end())
1378 i->second.AddLinkDirectory( d );
1380 else
1382 cmSystemTools::Error
1383 ("Attempt to add link directories to non-existant target: ",
1384 target, " for directory ", d);
1388 void cmMakefile::AddLinkLibrary(const char* lib)
1390 this->AddLinkLibrary(lib,cmTarget::GENERAL);
1393 void cmMakefile::AddLinkDirectory(const char* dir)
1395 // Don't add a link directory that is already present. Yes, this
1396 // linear search results in n^2 behavior, but n won't be getting
1397 // much bigger than 20. We cannot use a set because of order
1398 // dependency of the link search path.
1400 if(!dir)
1402 return;
1404 // remove trailing slashes
1405 if(dir[strlen(dir)-1] == '/')
1407 std::string newdir = dir;
1408 newdir = newdir.substr(0, newdir.size()-1);
1409 if(std::find(this->LinkDirectories.begin(),
1410 this->LinkDirectories.end(),
1411 newdir.c_str()) == this->LinkDirectories.end())
1413 this->LinkDirectories.push_back(newdir);
1416 else
1418 if(std::find(this->LinkDirectories.begin(),
1419 this->LinkDirectories.end(), dir)
1420 == this->LinkDirectories.end())
1422 this->LinkDirectories.push_back(dir);
1427 void cmMakefile::InitializeFromParent()
1429 cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
1431 // copy the definitions
1432 this->Internal->VarStack.top().Reset(&parent->Internal->VarStack.top());
1434 // copy include paths
1435 this->IncludeDirectories = parent->IncludeDirectories;
1436 this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
1438 // define flags
1439 this->DefineFlags = parent->DefineFlags;
1440 this->DefineFlagsOrig = parent->DefineFlagsOrig;
1442 // Include transform property. There is no per-config version.
1444 const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM";
1445 this->SetProperty(prop, parent->GetProperty(prop));
1448 // compile definitions property and per-config versions
1450 this->SetProperty("COMPILE_DEFINITIONS",
1451 parent->GetProperty("COMPILE_DEFINITIONS"));
1452 std::vector<std::string> configs;
1453 if(const char* configTypes =
1454 this->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
1456 cmSystemTools::ExpandListArgument(configTypes, configs);
1458 else if(const char* buildType =
1459 this->GetDefinition("CMAKE_BUILD_TYPE"))
1461 configs.push_back(buildType);
1463 for(std::vector<std::string>::const_iterator ci = configs.begin();
1464 ci != configs.end(); ++ci)
1466 std::string defPropName = "COMPILE_DEFINITIONS_";
1467 defPropName += cmSystemTools::UpperCase(*ci);
1468 this->SetProperty(defPropName.c_str(),
1469 parent->GetProperty(defPropName.c_str()));
1473 // link libraries
1474 this->LinkLibraries = parent->LinkLibraries;
1476 // link directories
1477 this->LinkDirectories = parent->LinkDirectories;
1479 // the initial project name
1480 this->ProjectName = parent->ProjectName;
1482 // Copy include regular expressions.
1483 this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
1484 this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
1486 // Imported targets.
1487 this->ImportedTargets = parent->ImportedTargets;
1490 void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
1492 // copy our variables from the child makefile
1493 lg2->GetMakefile()->InitializeFromParent();
1494 lg2->GetMakefile()->MakeStartDirectoriesCurrent();
1495 if (this->GetCMakeInstance()->GetDebugOutput())
1497 std::string msg=" Entering ";
1498 msg += lg2->GetMakefile()->GetCurrentDirectory();
1499 cmSystemTools::Message(msg.c_str());
1501 // finally configure the subdir
1502 lg2->Configure();
1503 if (this->GetCMakeInstance()->GetDebugOutput())
1505 std::string msg=" Returning to ";
1506 msg += this->GetCurrentDirectory();
1507 cmSystemTools::Message(msg.c_str());
1511 void cmMakefile::AddSubDirectory(const char* sub,
1512 bool excludeFromAll, bool preorder)
1514 // the source path must be made full if it isn't already
1515 std::string srcPath = sub;
1516 if (!cmSystemTools::FileIsFullPath(srcPath.c_str()))
1518 srcPath = this->GetCurrentDirectory();
1519 srcPath += "/";
1520 srcPath += sub;
1523 // binary path must be made full if it isn't already
1524 std::string binPath = sub;
1525 if (!cmSystemTools::FileIsFullPath(binPath.c_str()))
1527 binPath = this->GetCurrentOutputDirectory();
1528 binPath += "/";
1529 binPath += sub;
1533 this->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
1534 excludeFromAll, preorder, false);
1538 void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
1539 bool excludeFromAll, bool preorder,
1540 bool immediate)
1542 std::vector<cmLocalGenerator *>& children =
1543 this->LocalGenerator->GetChildren();
1544 // has this directory already been added? If so error
1545 unsigned int i;
1546 for (i = 0; i < children.size(); ++i)
1548 if (srcPath == children[i]->GetMakefile()->GetStartDirectory())
1550 cmSystemTools::Error
1551 ("Attempt to add subdirectory multiple times for directory.\n",
1552 srcPath);
1553 return;
1557 // Make sure the binary directory is unique.
1558 if(!this->EnforceUniqueDir(srcPath, binPath))
1560 return;
1563 // create a new local generator and set its parent
1564 cmLocalGenerator *lg2 =
1565 this->LocalGenerator->GetGlobalGenerator()->CreateLocalGenerator();
1566 lg2->SetParent(this->LocalGenerator);
1567 this->LocalGenerator->GetGlobalGenerator()->AddLocalGenerator(lg2);
1569 // set the subdirs start dirs
1570 lg2->GetMakefile()->SetStartDirectory(srcPath);
1571 lg2->GetMakefile()->SetStartOutputDirectory(binPath);
1572 if(excludeFromAll)
1574 lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1576 lg2->GetMakefile()->SetPreOrder(preorder);
1578 if (immediate)
1580 this->ConfigureSubDirectory(lg2);
1584 void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
1586 // if there is a newline then break it into multiple arguments
1587 if (!inc)
1589 return;
1592 // Don't add an include directory that is already present. Yes,
1593 // this linear search results in n^2 behavior, but n won't be
1594 // getting much bigger than 20. We cannot use a set because of
1595 // order dependency of the include path.
1596 std::vector<std::string>::iterator i =
1597 std::find(this->IncludeDirectories.begin(),
1598 this->IncludeDirectories.end(), inc);
1599 if(i == this->IncludeDirectories.end())
1601 if (before)
1603 // WARNING: this *is* expensive (linear time) since it's a vector
1604 this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
1606 else
1608 this->IncludeDirectories.push_back(inc);
1611 else
1613 if(before)
1615 // if this before and already in the path then remove it
1616 this->IncludeDirectories.erase(i);
1617 // WARNING: this *is* expensive (linear time) since it's a vector
1618 this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
1623 //----------------------------------------------------------------------------
1624 void cmMakefile::AddSystemIncludeDirectory(const char* dir)
1626 this->SystemIncludeDirectories.insert(dir);
1629 //----------------------------------------------------------------------------
1630 bool cmMakefile::IsSystemIncludeDirectory(const char* dir)
1632 return (this->SystemIncludeDirectories.find(dir) !=
1633 this->SystemIncludeDirectories.end());
1636 void cmMakefile::AddDefinition(const char* name, const char* value)
1638 if (!value )
1640 return;
1643 #ifdef CMAKE_STRICT
1644 if (this->GetCMakeInstance())
1646 this->GetCMakeInstance()->
1647 RecordPropertyAccess(name,cmProperty::VARIABLE);
1649 #endif
1651 this->Internal->VarStack.top().Set(name, value);
1653 #ifdef CMAKE_BUILD_WITH_CMAKE
1654 cmVariableWatch* vv = this->GetVariableWatch();
1655 if ( vv )
1657 vv->VariableAccessed(name,
1658 cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1659 value,
1660 this);
1662 #endif
1666 void cmMakefile::AddCacheDefinition(const char* name, const char* value,
1667 const char* doc,
1668 cmCacheManager::CacheEntryType type,
1669 bool force)
1671 const char* val = value;
1672 cmCacheManager::CacheIterator it =
1673 this->GetCacheManager()->GetCacheIterator(name);
1674 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1675 it.Initialized())
1677 // if this is not a force, then use the value from the cache
1678 // if it is a force, then use the value being passed in
1679 if(!force)
1681 val = it.GetValue();
1683 if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH )
1685 std::vector<std::string>::size_type cc;
1686 std::vector<std::string> files;
1687 std::string nvalue = "";
1688 cmSystemTools::ExpandListArgument(val, files);
1689 for ( cc = 0; cc < files.size(); cc ++ )
1691 files[cc] = cmSystemTools::CollapseFullPath(files[cc].c_str());
1692 if ( cc > 0 )
1694 nvalue += ";";
1696 nvalue += files[cc];
1699 this->GetCacheManager()->AddCacheEntry(name, nvalue.c_str(), doc, type);
1700 val = it.GetValue();
1704 this->GetCacheManager()->AddCacheEntry(name, val, doc, type);
1705 // if there was a definition then remove it
1706 this->Internal->VarStack.top().Set(name, 0);
1710 void cmMakefile::AddDefinition(const char* name, bool value)
1712 this->Internal->VarStack.top().Set(name, value? "ON" : "OFF");
1713 #ifdef CMAKE_BUILD_WITH_CMAKE
1714 cmVariableWatch* vv = this->GetVariableWatch();
1715 if ( vv )
1717 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1718 value?"ON":"OFF", this);
1720 #endif
1724 void cmMakefile::AddCacheDefinition(const char* name,
1725 bool value,
1726 const char* doc)
1728 bool val = value;
1729 cmCacheManager::CacheIterator it =
1730 this->GetCacheManager()->GetCacheIterator(name);
1731 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1732 it.Initialized())
1734 val = it.GetValueAsBool();
1736 this->GetCacheManager()->AddCacheEntry(name, val, doc);
1737 this->AddDefinition(name, val);
1740 void cmMakefile::RemoveDefinition(const char* name)
1742 this->Internal->VarStack.top().Set(name, 0);
1743 #ifdef CMAKE_BUILD_WITH_CMAKE
1744 cmVariableWatch* vv = this->GetVariableWatch();
1745 if ( vv )
1747 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
1748 0, this);
1750 #endif
1753 void cmMakefile::RemoveCacheDefinition(const char* name)
1755 this->GetCacheManager()->RemoveCacheEntry(name);
1758 void cmMakefile::SetProjectName(const char* p)
1760 this->ProjectName = p;
1764 void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
1766 // for these targets do not add anything
1767 switch(target.GetType())
1769 case cmTarget::UTILITY:
1770 case cmTarget::GLOBAL_TARGET:
1771 return;
1772 default:;
1774 std::vector<std::string>::iterator j;
1775 for(j = this->LinkDirectories.begin();
1776 j != this->LinkDirectories.end(); ++j)
1778 target.AddLinkDirectory(j->c_str());
1780 target.MergeLinkLibraries( *this, name, this->LinkLibraries );
1784 void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
1785 const std::vector<std::string> &srcs,
1786 bool excludeFromAll)
1788 // wrong type ? default to STATIC
1789 if ( (type != cmTarget::STATIC_LIBRARY)
1790 && (type != cmTarget::SHARED_LIBRARY)
1791 && (type != cmTarget::MODULE_LIBRARY))
1793 type = cmTarget::STATIC_LIBRARY;
1796 cmTarget* target = this->AddNewTarget(type, lname);
1797 // Clear its dependencies. Otherwise, dependencies might persist
1798 // over changes in CMakeLists.txt, making the information stale and
1799 // hence useless.
1800 target->ClearDependencyInformation( *this, lname );
1801 if(excludeFromAll)
1803 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1805 target->AddSources(srcs);
1806 this->AddGlobalLinkInformation(lname, *target);
1809 cmTarget* cmMakefile::AddExecutable(const char *exeName,
1810 const std::vector<std::string> &srcs,
1811 bool excludeFromAll)
1813 cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName);
1814 if(excludeFromAll)
1816 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1818 target->AddSources(srcs);
1819 this->AddGlobalLinkInformation(exeName, *target);
1820 return target;
1823 //----------------------------------------------------------------------------
1824 cmTarget*
1825 cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name)
1827 cmTargets::iterator it =
1828 this->Targets.insert(cmTargets::value_type(name, cmTarget())).first;
1829 cmTarget& target = it->second;
1830 target.SetType(type, name);
1831 target.SetMakefile(this);
1832 this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it);
1833 return &it->second;
1836 cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
1838 std::string name = cname;
1839 std::string out;
1841 // look through all the source files that have custom commands
1842 // and see if the custom command has the passed source file as an output
1843 // keep in mind the possible .rule extension that may be tacked on
1844 for(std::vector<cmSourceFile*>::const_iterator i =
1845 this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
1847 // does this source file have a custom command?
1848 if ((*i)->GetCustomCommand())
1850 // is the output of the custom command match the source files name
1851 const std::vector<std::string>& outputs =
1852 (*i)->GetCustomCommand()->GetOutputs();
1853 for(std::vector<std::string>::const_iterator o = outputs.begin();
1854 o != outputs.end(); ++o)
1856 out = *o;
1857 std::string::size_type pos = out.rfind(name);
1858 // If the output matches exactly
1859 if (pos != out.npos &&
1860 pos == out.size() - name.size() &&
1861 (pos ==0 || out[pos-1] == '/'))
1863 return *i;
1869 // otherwise return NULL
1870 return 0;
1873 #if defined(CMAKE_BUILD_WITH_CMAKE)
1874 cmSourceGroup* cmMakefile::GetSourceGroup(const std::vector<std::string>&name)
1876 cmSourceGroup* sg = 0;
1878 // first look for source group starting with the same as the one we wants
1879 for (std::vector<cmSourceGroup>::iterator sgIt = this->SourceGroups.begin();
1880 sgIt != this->SourceGroups.end(); ++sgIt)
1883 std::string sgName = sgIt->GetName();
1884 if(sgName == name[0])
1886 sg = &(*sgIt);
1887 break;
1891 if(sg != 0)
1893 // iterate through its children to find match source group
1894 for(unsigned int i=1; i<name.size(); ++i)
1896 sg = sg->lookupChild(name[i].c_str());
1897 if(sg == 0)
1899 break;
1903 return sg;
1906 void cmMakefile::AddSourceGroup(const char* name,
1907 const char* regex)
1909 if (name)
1911 std::vector<std::string> nameVector;
1912 nameVector.push_back(name);
1913 AddSourceGroup(nameVector, regex);
1917 void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
1918 const char* regex)
1920 cmSourceGroup* sg = 0;
1921 std::vector<std::string> currentName;
1922 int i = 0;
1923 const int lastElement = static_cast<int>(name.size()-1);
1924 for(i=lastElement; i>=0; --i)
1926 currentName.assign(name.begin(), name.begin()+i+1);
1927 sg = this->GetSourceGroup(currentName);
1928 if(sg != 0)
1930 break;
1934 // i now contains the index of the last found component
1935 if(i==lastElement)
1937 // group already exists, replace its regular expression
1938 if ( regex )
1940 // We only want to set the regular expression. If there are already
1941 // source files in the group, we don't want to remove them.
1942 sg->SetGroupRegex(regex);
1944 return;
1946 else if(i==-1)
1948 // group does not exists nor belong to any existing group
1949 // add its first component
1950 this->SourceGroups.push_back(cmSourceGroup(name[0].c_str(), regex));
1951 sg = this->GetSourceGroup(currentName);
1952 i = 0; // last component found
1955 // build the whole source group path
1956 const char* fullname = sg->GetFullName();
1957 cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
1958 if(strlen(fullname))
1960 std::string guidName = "SG_Filter_";
1961 guidName += fullname;
1962 gg->CreateGUID(guidName.c_str());
1964 for(++i; i<=lastElement; ++i)
1966 sg->AddChild(cmSourceGroup(name[i].c_str(), 0, sg->GetFullName()));
1967 sg = sg->lookupChild(name[i].c_str());
1968 fullname = sg->GetFullName();
1969 if(strlen(fullname))
1971 std::string guidName = "SG_Filter_";
1972 guidName += fullname;
1973 gg->CreateGUID(guidName.c_str());
1977 sg->SetGroupRegex(regex);
1980 #endif
1982 void cmMakefile::AddExtraDirectory(const char* dir)
1984 this->AuxSourceDirectories.push_back(dir);
1988 // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
1989 // include and library directories.
1991 void cmMakefile::ExpandVariables()
1993 // Now expand variables in the include and link strings
1994 for(std::vector<std::string>::iterator d = this->IncludeDirectories.begin();
1995 d != this->IncludeDirectories.end(); ++d)
1997 this->ExpandVariablesInString(*d, true, true);
1999 for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
2000 d != this->LinkDirectories.end(); ++d)
2002 this->ExpandVariablesInString(*d, true, true);
2004 for(cmTarget::LinkLibraryVectorType::iterator l =
2005 this->LinkLibraries.begin();
2006 l != this->LinkLibraries.end(); ++l)
2008 this->ExpandVariablesInString(l->first, true, true);
2012 bool cmMakefile::IsOn(const char* name) const
2014 const char* value = this->GetDefinition(name);
2015 return cmSystemTools::IsOn(value);
2018 bool cmMakefile::IsSet(const char* name) const
2020 const char* value = this->GetDefinition(name);
2021 if ( !value )
2023 return false;
2026 if ( ! *value )
2028 return false;
2031 if ( cmSystemTools::IsNOTFOUND(value) )
2033 return false;
2036 return true;
2039 bool cmMakefile::CanIWriteThisFile(const char* fileName)
2041 if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
2043 return true;
2045 // If we are doing an in-source build, than the test will always fail
2046 if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
2047 this->GetHomeOutputDirectory()) )
2049 if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
2051 return false;
2053 return true;
2056 // Check if this is subdirectory of the source tree but not a
2057 // subdirectory of a build tree
2058 if ( cmSystemTools::IsSubDirectory(fileName,
2059 this->GetHomeDirectory()) &&
2060 !cmSystemTools::IsSubDirectory(fileName,
2061 this->GetHomeOutputDirectory()) )
2063 return false;
2065 return true;
2068 const char* cmMakefile::GetRequiredDefinition(const char* name) const
2070 const char* ret = this->GetDefinition(name);
2071 if(!ret)
2073 cmSystemTools::Error("Error required internal CMake variable not "
2074 "set, cmake may be not be built correctly.\n",
2075 "Missing variable is:\n",
2076 name);
2077 return "";
2079 return ret;
2082 bool cmMakefile::IsDefinitionSet(const char* name) const
2084 const char* def = this->Internal->VarStack.top().Get(name);
2085 if(!def)
2087 def = this->GetCacheManager()->GetCacheValue(name);
2089 #ifdef CMAKE_BUILD_WITH_CMAKE
2090 if(cmVariableWatch* vv = this->GetVariableWatch())
2092 if(!def)
2094 vv->VariableAccessed
2095 (name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS,
2096 def, this);
2099 #endif
2100 return def?true:false;
2103 const char* cmMakefile::GetDefinition(const char* name) const
2105 #ifdef CMAKE_STRICT
2106 if (this->GetCMakeInstance())
2108 this->GetCMakeInstance()->
2109 RecordPropertyAccess(name,cmProperty::VARIABLE);
2111 #endif
2112 const char* def = this->Internal->VarStack.top().Get(name);
2113 if(!def)
2115 def = this->GetCacheManager()->GetCacheValue(name);
2117 #ifdef CMAKE_BUILD_WITH_CMAKE
2118 cmVariableWatch* vv = this->GetVariableWatch();
2119 if ( vv )
2121 if ( def )
2123 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
2124 def, this);
2126 else
2128 // are unknown access allowed
2129 const char* allow = this->Internal->VarStack.top()
2130 .Get("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
2131 if(cmSystemTools::IsOn(allow))
2133 vv->VariableAccessed(name,
2134 cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, def, this);
2136 else
2138 vv->VariableAccessed(name,
2139 cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
2143 #endif
2144 return def;
2147 const char* cmMakefile::GetSafeDefinition(const char* def) const
2149 const char* ret = this->GetDefinition(def);
2150 if(!ret)
2152 return "";
2154 return ret;
2157 std::vector<std::string> cmMakefile
2158 ::GetDefinitions(int cacheonly /* = 0 */) const
2160 std::set<cmStdString> definitions;
2161 if ( !cacheonly )
2163 definitions = this->Internal->VarStack.top().ClosureKeys();
2165 cmCacheManager::CacheIterator cit =
2166 this->GetCacheManager()->GetCacheIterator();
2167 for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
2169 definitions.insert(cit.GetName());
2172 std::vector<std::string> res;
2174 std::set<cmStdString>::iterator fit;
2175 for ( fit = definitions.begin(); fit != definitions.end(); fit ++ )
2177 res.push_back(*fit);
2179 return res;
2183 const char *cmMakefile::ExpandVariablesInString(std::string& source)
2185 return this->ExpandVariablesInString(source, false, false);
2188 const char *cmMakefile::ExpandVariablesInString(std::string& source,
2189 bool escapeQuotes,
2190 bool noEscapes,
2191 bool atOnly,
2192 const char* filename,
2193 long line,
2194 bool removeEmpty,
2195 bool replaceAt)
2197 if ( source.empty() || source.find_first_of("$@\\") == source.npos)
2199 return source.c_str();
2202 // Special-case the @ONLY mode.
2203 if(atOnly)
2205 if(!noEscapes || !removeEmpty || !replaceAt)
2207 // This case should never be called. At-only is for
2208 // configure-file/string which always does no escapes.
2209 this->IssueMessage(cmake::INTERNAL_ERROR,
2210 "ExpandVariablesInString @ONLY called "
2211 "on something with escapes.");
2214 // Store an original copy of the input.
2215 std::string input = source;
2217 // Start with empty output.
2218 source = "";
2220 // Look for one @VAR@ at a time.
2221 const char* in = input.c_str();
2222 while(this->cmAtVarRegex.find(in))
2224 // Get the range of the string to replace.
2225 const char* first = in + this->cmAtVarRegex.start();
2226 const char* last = in + this->cmAtVarRegex.end();
2228 // Store the unchanged part of the string now.
2229 source.append(in, first-in);
2231 // Lookup the definition of VAR.
2232 std::string var(first+1, last-first-2);
2233 if(const char* val = this->GetDefinition(var.c_str()))
2235 // Store the value in the output escaping as requested.
2236 if(escapeQuotes)
2238 source.append(cmSystemTools::EscapeQuotes(val));
2240 else
2242 source.append(val);
2246 // Continue looking for @VAR@ further along the string.
2247 in = last;
2250 // Append the rest of the unchanged part of the string.
2251 source.append(in);
2253 return source.c_str();
2256 // This method replaces ${VAR} and @VAR@ where VAR is looked up
2257 // with GetDefinition(), if not found in the map, nothing is expanded.
2258 // It also supports the $ENV{VAR} syntax where VAR is looked up in
2259 // the current environment variables.
2261 cmCommandArgumentParserHelper parser;
2262 parser.SetMakefile(this);
2263 parser.SetLineFile(line, filename);
2264 parser.SetEscapeQuotes(escapeQuotes);
2265 parser.SetNoEscapeMode(noEscapes);
2266 parser.SetReplaceAtSyntax(replaceAt);
2267 parser.SetRemoveEmpty(removeEmpty);
2268 int res = parser.ParseString(source.c_str(), 0);
2269 const char* emsg = parser.GetError();
2270 if ( res && !emsg[0] )
2272 source = parser.GetResult();
2274 else
2276 // Construct the main error message.
2277 cmOStringStream error;
2278 error << "Syntax error in cmake code ";
2279 if(filename && line > 0)
2281 // This filename and line number may be more specific than the
2282 // command context because one command invocation can have
2283 // arguments on multiple lines.
2284 error << "at\n"
2285 << " " << filename << ":" << line << "\n";
2287 error << "when parsing string\n"
2288 << " " << source.c_str() << "\n";
2289 error << emsg;
2291 // If the parser failed ("res" is false) then this is a real
2292 // argument parsing error, so the policy applies. Otherwise the
2293 // parser reported an error message without failing because the
2294 // helper implementation is unhappy, which has always reported an
2295 // error.
2296 cmake::MessageType mtype = cmake::FATAL_ERROR;
2297 if(!res)
2299 // This is a real argument parsing error. Use policy CMP0010 to
2300 // decide whether it is an error.
2301 switch(this->GetPolicyStatus(cmPolicies::CMP0010))
2303 case cmPolicies::WARN:
2304 error << "\n"
2305 << (this->GetPolicies()
2306 ->GetPolicyWarning(cmPolicies::CMP0010));
2307 case cmPolicies::OLD:
2308 // OLD behavior is to just warn and continue.
2309 mtype = cmake::AUTHOR_WARNING;
2310 break;
2311 case cmPolicies::REQUIRED_IF_USED:
2312 case cmPolicies::REQUIRED_ALWAYS:
2313 error << "\n"
2314 << (this->GetPolicies()
2315 ->GetRequiredPolicyError(cmPolicies::CMP0010));
2316 case cmPolicies::NEW:
2317 // NEW behavior is to report the error.
2318 cmSystemTools::SetFatalErrorOccured();
2319 break;
2322 this->IssueMessage(mtype, error.str());
2324 return source.c_str();
2327 void cmMakefile::RemoveVariablesInString(std::string& source,
2328 bool atOnly) const
2330 if(!atOnly)
2332 cmsys::RegularExpression var("(\\${[A-Za-z_0-9]*})");
2333 while (var.find(source))
2335 source.erase(var.start(),var.end() - var.start());
2339 if(!atOnly)
2341 cmsys::RegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
2342 while (varb.find(source))
2344 source.erase(varb.start(),varb.end() - varb.start());
2347 cmsys::RegularExpression var2("(@[A-Za-z_0-9]*@)");
2348 while (var2.find(source))
2350 source.erase(var2.start(),var2.end() - var2.start());
2355 * Add the default definitions to the makefile. These values must not
2356 * be dependent on anything that isn't known when this cmMakefile instance
2357 * is constructed.
2359 void cmMakefile::AddDefaultDefinitions()
2361 /* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set.
2362 With CMake must separate between target and host platform. In most cases
2363 the tests for WIN32, UNIX and APPLE will be for the target system, so an
2364 additional set of variables for the host system is required ->
2365 CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE.
2366 WIN32, UNIX and APPLE are now set in the platform files in
2367 Modules/Platforms/.
2368 To keep cmake scripts (-P) and custom language and compiler modules
2369 working, these variables are still also set here in this place, but they
2370 will be reset in CMakeSystemSpecificInformation.cmake before the platform
2371 files are executed. */
2372 #if defined(_WIN32) || defined(__CYGWIN__)
2373 this->AddDefinition("WIN32", "1");
2374 this->AddDefinition("CMAKE_HOST_WIN32", "1");
2375 #else
2376 this->AddDefinition("UNIX", "1");
2377 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2378 #endif
2379 // Cygwin is more like unix so enable the unix commands
2380 #if defined(__CYGWIN__)
2381 this->AddDefinition("UNIX", "1");
2382 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2383 #endif
2384 #if defined(__APPLE__)
2385 this->AddDefinition("APPLE", "1");
2386 this->AddDefinition("CMAKE_HOST_APPLE", "1");
2387 #endif
2389 char temp[1024];
2390 sprintf(temp, "%d", cmVersion::GetMinorVersion());
2391 this->AddDefinition("CMAKE_MINOR_VERSION", temp);
2392 sprintf(temp, "%d", cmVersion::GetMajorVersion());
2393 this->AddDefinition("CMAKE_MAJOR_VERSION", temp);
2394 sprintf(temp, "%d", cmVersion::GetPatchVersion());
2395 this->AddDefinition("CMAKE_PATCH_VERSION", temp);
2396 sprintf(temp, "%u.%u.%u",
2397 cmVersion::GetMajorVersion(),
2398 cmVersion::GetMinorVersion(),
2399 cmVersion::GetPatchVersion());
2400 this->AddDefinition("CMAKE_VERSION", temp);
2402 this->AddDefinition("CMAKE_FILES_DIRECTORY",
2403 cmake::GetCMakeFilesDirectory());
2406 #if defined(CMAKE_BUILD_WITH_CMAKE)
2408 * Find a source group whose regular expression matches the filename
2409 * part of the given source name. Search backward through the list of
2410 * source groups, and take the first matching group found. This way
2411 * non-inherited SOURCE_GROUP commands will have precedence over
2412 * inherited ones.
2414 cmSourceGroup&
2415 cmMakefile::FindSourceGroup(const char* source,
2416 std::vector<cmSourceGroup> &groups)
2418 // First search for a group that lists the file explicitly.
2419 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2420 sg != groups.rend(); ++sg)
2422 cmSourceGroup *result = sg->MatchChildrenFiles(source);
2423 if(result)
2425 return *result;
2429 // Now search for a group whose regex matches the file.
2430 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2431 sg != groups.rend(); ++sg)
2433 cmSourceGroup *result = sg->MatchChildrenRegex(source);
2434 if(result)
2436 return *result;
2441 // Shouldn't get here, but just in case, return the default group.
2442 return groups.front();
2444 #endif
2446 bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
2447 cmExecutionStatus &status)
2449 // if there are no blockers get out of here
2450 if (this->FunctionBlockers.begin() == this->FunctionBlockers.end())
2452 return false;
2455 // loop over all function blockers to see if any block this command
2456 // evaluate in reverse, this is critical for balanced IF statements etc
2457 std::vector<cmFunctionBlocker*>::reverse_iterator pos;
2458 for (pos = this->FunctionBlockers.rbegin();
2459 pos != this->FunctionBlockers.rend(); ++pos)
2461 if((*pos)->IsFunctionBlocked(lff, *this, status))
2463 return true;
2467 return false;
2470 //----------------------------------------------------------------------------
2471 void cmMakefile::PushFunctionBlockerBarrier()
2473 this->FunctionBlockerBarriers.push_back(this->FunctionBlockers.size());
2476 //----------------------------------------------------------------------------
2477 void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
2479 // Remove any extra entries pushed on the barrier.
2480 FunctionBlockersType::size_type barrier =
2481 this->FunctionBlockerBarriers.back();
2482 while(this->FunctionBlockers.size() > barrier)
2484 cmsys::auto_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back());
2485 this->FunctionBlockers.pop_back();
2486 if(reportError)
2488 // Report the context in which the unclosed block was opened.
2489 cmListFileContext const& lfc = fb->GetStartingContext();
2490 cmOStringStream e;
2491 e << "A logical block opening on the line\n"
2492 << " " << lfc << "\n"
2493 << "is not closed.";
2494 this->IssueMessage(cmake::FATAL_ERROR, e.str());
2495 reportError = false;
2499 // Remove the barrier.
2500 this->FunctionBlockerBarriers.pop_back();
2503 bool cmMakefile::ExpandArguments(
2504 std::vector<cmListFileArgument> const& inArgs,
2505 std::vector<std::string>& outArgs)
2507 std::vector<cmListFileArgument>::const_iterator i;
2508 std::string value;
2509 outArgs.reserve(inArgs.size());
2510 for(i = inArgs.begin(); i != inArgs.end(); ++i)
2512 // Expand the variables in the argument.
2513 value = i->Value;
2514 this->ExpandVariablesInString(value, false, false, false,
2515 i->FilePath, i->Line,
2516 false, true);
2518 // If the argument is quoted, it should be one argument.
2519 // Otherwise, it may be a list of arguments.
2520 if(i->Quoted)
2522 outArgs.push_back(value);
2524 else
2526 cmSystemTools::ExpandListArgument(value, outArgs);
2529 return !cmSystemTools::GetFatalErrorOccured();
2532 //----------------------------------------------------------------------------
2533 void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
2535 if(!this->CallStack.empty())
2537 // Record the context in which the blocker is created.
2538 fb->SetStartingContext(*(this->CallStack.back().Context));
2541 this->FunctionBlockers.push_back(fb);
2544 cmsys::auto_ptr<cmFunctionBlocker>
2545 cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb,
2546 const cmListFileFunction& lff)
2548 // Find the function blocker stack barrier for the current scope.
2549 // We only remove a blocker whose index is not less than the barrier.
2550 FunctionBlockersType::size_type barrier = 0;
2551 if(!this->FunctionBlockerBarriers.empty())
2553 barrier = this->FunctionBlockerBarriers.back();
2556 // Search for the function blocker whose scope this command ends.
2557 for(FunctionBlockersType::size_type
2558 i = this->FunctionBlockers.size(); i > barrier; --i)
2560 std::vector<cmFunctionBlocker*>::iterator pos =
2561 this->FunctionBlockers.begin() + (i - 1);
2562 if (*pos == fb)
2564 // Warn if the arguments do not match, but always remove.
2565 if(!(*pos)->ShouldRemove(lff, *this))
2567 cmListFileContext const& lfc = fb->GetStartingContext();
2568 cmOStringStream e;
2569 e << "A logical block opening on the line\n"
2570 << " " << lfc << "\n"
2571 << "closes on the line\n"
2572 << " " << lff << "\n"
2573 << "with mis-matching arguments.";
2574 this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
2576 cmFunctionBlocker* b = *pos;
2577 this->FunctionBlockers.erase(pos);
2578 return cmsys::auto_ptr<cmFunctionBlocker>(b);
2582 return cmsys::auto_ptr<cmFunctionBlocker>();
2585 //----------------------------------------------------------------------------
2586 cmMakefile::LexicalPushPop::LexicalPushPop(cmMakefile* mf):
2587 Makefile(mf), ReportError(true)
2589 this->Makefile->PushFunctionBlockerBarrier();
2592 //----------------------------------------------------------------------------
2593 cmMakefile::LexicalPushPop::~LexicalPushPop()
2595 this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
2598 void cmMakefile::SetHomeDirectory(const char* dir)
2600 this->cmHomeDirectory = dir;
2601 cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
2602 this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
2603 if ( !this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR") )
2605 this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", this->GetHomeDirectory());
2609 void cmMakefile::SetHomeOutputDirectory(const char* lib)
2611 this->HomeOutputDirectory = lib;
2612 cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
2613 this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
2614 if ( !this->GetDefinition("CMAKE_CURRENT_BINARY_DIR") )
2616 this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
2617 this->GetHomeOutputDirectory());
2623 * Register the given cmData instance with its own name.
2625 void cmMakefile::RegisterData(cmData* data)
2627 std::string name = data->GetName();
2628 DataMapType::const_iterator d = this->DataMap.find(name);
2629 if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
2631 delete d->second;
2633 this->DataMap[name] = data;
2638 * Register the given cmData instance with the given name. This can be used
2639 * to register a NULL pointer.
2641 void cmMakefile::RegisterData(const char* name, cmData* data)
2643 DataMapType::const_iterator d = this->DataMap.find(name);
2644 if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
2646 delete d->second;
2648 this->DataMap[name] = data;
2653 * Lookup a cmData instance previously registered with the given name. If
2654 * the instance cannot be found, return NULL.
2656 cmData* cmMakefile::LookupData(const char* name) const
2658 DataMapType::const_iterator d = this->DataMap.find(name);
2659 if(d != this->DataMap.end())
2661 return d->second;
2663 else
2665 return 0;
2669 //----------------------------------------------------------------------------
2670 cmSourceFile* cmMakefile::GetSource(const char* sourceName)
2672 cmSourceFileLocation sfl(this, sourceName);
2673 for(std::vector<cmSourceFile*>::const_iterator
2674 sfi = this->SourceFiles.begin();
2675 sfi != this->SourceFiles.end(); ++sfi)
2677 cmSourceFile* sf = *sfi;
2678 if(sf->Matches(sfl))
2680 return sf;
2683 return 0;
2686 //----------------------------------------------------------------------------
2687 cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
2688 bool generated)
2690 if(cmSourceFile* esf = this->GetSource(sourceName))
2692 return esf;
2694 else
2696 cmSourceFile* sf = new cmSourceFile(this, sourceName);
2697 if(generated)
2699 sf->SetProperty("GENERATED", "1");
2701 this->SourceFiles.push_back(sf);
2702 return sf;
2706 void cmMakefile::EnableLanguage(std::vector<std::string> const & lang,
2707 bool optional)
2709 this->AddDefinition("CMAKE_CFG_INTDIR",
2710 this->LocalGenerator->GetGlobalGenerator()
2711 ->GetCMakeCFGInitDirectory());
2712 this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this,
2713 optional);
2716 void cmMakefile::ExpandSourceListArguments(
2717 std::vector<std::string> const& arguments,
2718 std::vector<std::string>& newargs, unsigned int /* start */)
2720 // now expand the args
2721 unsigned int i;
2722 for(i = 0; i < arguments.size(); ++i)
2724 // List expansion will have been done already.
2725 newargs.push_back(arguments[i]);
2729 int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
2730 const char *projectName, const char *targetName,
2731 bool fast,
2732 const std::vector<std::string> *cmakeArgs,
2733 std::string *output)
2735 // does the binary directory exist ? If not create it...
2736 if (!cmSystemTools::FileIsDirectory(bindir))
2738 cmSystemTools::MakeDirectory(bindir);
2741 // change to the tests directory and run cmake
2742 // use the cmake object instead of calling cmake
2743 std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
2744 cmSystemTools::ChangeDirectory(bindir);
2746 // make sure the same generator is used
2747 // use this program as the cmake to be run, it should not
2748 // be run that way but the cmake object requires a vailid path
2749 std::string cmakeCommand = this->GetDefinition("CMAKE_COMMAND");
2750 cmake cm;
2751 cm.SetIsInTryCompile(true);
2752 cmGlobalGenerator *gg = cm.CreateGlobalGenerator
2753 (this->LocalGenerator->GetGlobalGenerator()->GetName());
2754 if (!gg)
2756 cmSystemTools::Error(
2757 "Internal CMake error, TryCompile bad GlobalGenerator");
2758 // return to the original directory
2759 cmSystemTools::ChangeDirectory(cwd.c_str());
2760 return 1;
2762 cm.SetGlobalGenerator(gg);
2764 // do a configure
2765 cm.SetHomeDirectory(srcdir);
2766 cm.SetHomeOutputDirectory(bindir);
2767 cm.SetStartDirectory(srcdir);
2768 cm.SetStartOutputDirectory(bindir);
2769 cm.SetCMakeCommand(cmakeCommand.c_str());
2770 cm.LoadCache();
2771 // if cmake args were provided then pass them in
2772 if (cmakeArgs)
2774 cm.SetCacheArgs(*cmakeArgs);
2776 // to save time we pass the EnableLanguage info directly
2777 gg->EnableLanguagesFromGenerator
2778 (this->LocalGenerator->GetGlobalGenerator());
2779 if(this->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"))
2781 cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
2782 "TRUE", "", cmCacheManager::INTERNAL);
2784 else
2786 cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
2787 "FALSE", "", cmCacheManager::INTERNAL);
2789 if (cm.Configure() != 0)
2791 cmSystemTools::Error(
2792 "Internal CMake error, TryCompile configure of cmake failed");
2793 // return to the original directory
2794 cmSystemTools::ChangeDirectory(cwd.c_str());
2795 return 1;
2798 if (cm.Generate() != 0)
2800 cmSystemTools::Error(
2801 "Internal CMake error, TryCompile generation of cmake failed");
2802 // return to the original directory
2803 cmSystemTools::ChangeDirectory(cwd.c_str());
2804 return 1;
2807 // finally call the generator to actually build the resulting project
2808 int ret =
2809 this->LocalGenerator->GetGlobalGenerator()->TryCompile(srcdir,bindir,
2810 projectName,
2811 targetName,
2812 fast,
2813 output,
2814 this);
2816 cmSystemTools::ChangeDirectory(cwd.c_str());
2817 return ret;
2820 cmake *cmMakefile::GetCMakeInstance() const
2822 if ( this->LocalGenerator && this->LocalGenerator->GetGlobalGenerator() )
2824 return this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
2826 return 0;
2829 #ifdef CMAKE_BUILD_WITH_CMAKE
2830 cmVariableWatch *cmMakefile::GetVariableWatch() const
2832 if ( this->GetCMakeInstance() &&
2833 this->GetCMakeInstance()->GetVariableWatch() )
2835 return this->GetCMakeInstance()->GetVariableWatch();
2837 return 0;
2839 #endif
2841 void cmMakefile::AddMacro(const char* name, const char* signature)
2843 if ( !name || !signature )
2845 return;
2847 this->MacrosMap[name] = signature;
2850 void cmMakefile::GetListOfMacros(std::string& macros)
2852 StringStringMap::iterator it;
2853 macros = "";
2854 int cc = 0;
2855 for ( it = this->MacrosMap.begin(); it != this->MacrosMap.end(); ++it )
2857 if ( cc > 0 )
2859 macros += ";";
2861 macros += it->first;
2862 cc ++;
2866 cmCacheManager *cmMakefile::GetCacheManager() const
2868 return this->GetCMakeInstance()->GetCacheManager();
2871 void cmMakefile::DisplayStatus(const char* message, float s)
2873 this->GetLocalGenerator()->GetGlobalGenerator()
2874 ->GetCMakeInstance()->UpdateProgress(message, s);
2877 std::string cmMakefile::GetModulesFile(const char* filename)
2879 std::vector<std::string> modulePath;
2880 const char* def = this->GetDefinition("CMAKE_MODULE_PATH");
2881 if(def)
2883 cmSystemTools::ExpandListArgument(def, modulePath);
2886 // Also search in the standard modules location.
2887 def = this->GetDefinition("CMAKE_ROOT");
2888 if(def)
2890 std::string rootModules = def;
2891 rootModules += "/Modules";
2892 modulePath.push_back(rootModules);
2894 //std::string Look through the possible module directories.
2895 for(std::vector<std::string>::iterator i = modulePath.begin();
2896 i != modulePath.end(); ++i)
2898 std::string itempl = *i;
2899 cmSystemTools::ConvertToUnixSlashes(itempl);
2900 itempl += "/";
2901 itempl += filename;
2902 if(cmSystemTools::FileExists(itempl.c_str()))
2904 return itempl;
2907 return "";
2910 void cmMakefile::ConfigureString(const std::string& input,
2911 std::string& output, bool atOnly,
2912 bool escapeQuotes)
2914 // Split input to handle one line at a time.
2915 std::string::const_iterator lineStart = input.begin();
2916 while(lineStart != input.end())
2918 // Find the end of this line.
2919 std::string::const_iterator lineEnd = lineStart;
2920 while(lineEnd != input.end() && *lineEnd != '\n')
2922 ++lineEnd;
2925 // Copy the line.
2926 std::string line(lineStart, lineEnd);
2928 // Skip the newline character.
2929 bool haveNewline = (lineEnd != input.end());
2930 if(haveNewline)
2932 ++lineEnd;
2935 // Replace #cmakedefine instances.
2936 if(this->cmDefineRegex.find(line))
2938 const char* def =
2939 this->GetDefinition(this->cmDefineRegex.match(1).c_str());
2940 if(!cmSystemTools::IsOff(def))
2942 cmSystemTools::ReplaceString(line, "#cmakedefine", "#define");
2943 output += line;
2945 else
2947 output += "/* #undef ";
2948 output += this->cmDefineRegex.match(1);
2949 output += " */";
2952 else if(this->cmDefine01Regex.find(line))
2954 const char* def =
2955 this->GetDefinition(this->cmDefine01Regex.match(1).c_str());
2956 cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define");
2957 output += line;
2958 if(!cmSystemTools::IsOff(def))
2960 output += " 1";
2962 else
2964 output += " 0";
2967 else
2969 output += line;
2972 if(haveNewline)
2974 output += "\n";
2977 // Move to the next line.
2978 lineStart = lineEnd;
2981 // Perform variable replacements.
2982 this->ExpandVariablesInString(output, escapeQuotes, true,
2983 atOnly, 0, -1, true);
2986 int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
2987 bool copyonly, bool atOnly, bool escapeQuotes)
2989 int res = 1;
2990 if ( !this->CanIWriteThisFile(outfile) )
2992 cmSystemTools::Error("Attempt to write file: ",
2993 outfile, " into a source directory.");
2994 return 0;
2996 if ( !cmSystemTools::FileExists(infile) )
2998 cmSystemTools::Error("File ", infile, " does not exist.");
2999 return 0;
3001 std::string soutfile = outfile;
3002 std::string sinfile = infile;
3003 this->AddCMakeDependFile(infile);
3004 cmSystemTools::ConvertToUnixSlashes(soutfile);
3005 mode_t perm = 0;
3006 cmSystemTools::GetPermissions(sinfile.c_str(), perm);
3007 std::string::size_type pos = soutfile.rfind('/');
3008 if(pos != std::string::npos)
3010 std::string path = soutfile.substr(0, pos);
3011 cmSystemTools::MakeDirectory(path.c_str());
3014 if(copyonly)
3016 if ( !cmSystemTools::CopyFileIfDifferent(sinfile.c_str(),
3017 soutfile.c_str()))
3019 return 0;
3022 else
3024 std::string tempOutputFile = soutfile;
3025 tempOutputFile += ".tmp";
3026 std::ofstream fout(tempOutputFile.c_str());
3027 if(!fout)
3029 cmSystemTools::Error(
3030 "Could not open file for write in copy operation ",
3031 tempOutputFile.c_str());
3032 cmSystemTools::ReportLastSystemError("");
3033 return 0;
3035 std::ifstream fin(sinfile.c_str());
3036 if(!fin)
3038 cmSystemTools::Error("Could not open file for read in copy operation ",
3039 sinfile.c_str());
3040 return 0;
3043 // now copy input to output and expand variables in the
3044 // input file at the same time
3045 std::string inLine;
3046 std::string outLine;
3047 while( cmSystemTools::GetLineFromStream(fin, inLine) )
3049 outLine = "";
3050 this->ConfigureString(inLine, outLine, atOnly, escapeQuotes);
3051 fout << outLine.c_str() << "\n";
3053 // close the files before attempting to copy
3054 fin.close();
3055 fout.close();
3056 if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
3057 soutfile.c_str()) )
3059 res = 0;
3061 else
3063 cmSystemTools::SetPermissions(soutfile.c_str(), perm);
3065 cmSystemTools::RemoveFile(tempOutputFile.c_str());
3067 return res;
3070 void cmMakefile::SetProperty(const char* prop, const char* value)
3072 if (!prop)
3074 return;
3077 // handle special props
3078 std::string propname = prop;
3079 if ( propname == "INCLUDE_DIRECTORIES" )
3081 std::vector<std::string> varArgsExpanded;
3082 if(value)
3084 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
3086 this->SetIncludeDirectories(varArgsExpanded);
3087 return;
3090 if ( propname == "LINK_DIRECTORIES" )
3092 std::vector<std::string> varArgsExpanded;
3093 if(value)
3095 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
3097 this->SetLinkDirectories(varArgsExpanded);
3098 return;
3101 if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
3103 this->SetIncludeRegularExpression(value);
3104 return;
3107 if ( propname == "ADDITIONAL_MAKE_CLEAN_FILES" )
3109 // This property is not inherrited
3110 if ( strcmp(this->GetCurrentDirectory(),
3111 this->GetStartDirectory()) != 0 )
3113 return;
3117 this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
3120 void cmMakefile::AppendProperty(const char* prop, const char* value)
3122 if (!prop)
3124 return;
3127 // handle special props
3128 std::string propname = prop;
3129 if ( propname == "INCLUDE_DIRECTORIES" )
3131 std::vector<std::string> varArgsExpanded;
3132 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
3133 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
3134 vi != varArgsExpanded.end(); ++vi)
3136 this->AddIncludeDirectory(vi->c_str());
3138 return;
3141 if ( propname == "LINK_DIRECTORIES" )
3143 std::vector<std::string> varArgsExpanded;
3144 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
3145 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
3146 vi != varArgsExpanded.end(); ++vi)
3148 this->AddLinkDirectory(vi->c_str());
3150 return;
3153 this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY);
3156 const char *cmMakefile::GetPropertyOrDefinition(const char* prop)
3158 const char *ret = this->GetProperty(prop, cmProperty::DIRECTORY);
3159 if (!ret)
3161 ret = this->GetDefinition(prop);
3163 return ret;
3166 const char *cmMakefile::GetProperty(const char* prop)
3168 return this->GetProperty(prop, cmProperty::DIRECTORY);
3171 const char *cmMakefile::GetProperty(const char* prop,
3172 cmProperty::ScopeType scope)
3174 if(!prop)
3176 return 0;
3178 // watch for specific properties
3179 static std::string output;
3180 output = "";
3181 if (!strcmp("PARENT_DIRECTORY",prop))
3183 if(cmLocalGenerator* plg = this->LocalGenerator->GetParent())
3185 output = plg->GetMakefile()->GetStartDirectory();
3187 return output.c_str();
3189 else if (!strcmp("INCLUDE_REGULAR_EXPRESSION",prop) )
3191 output = this->GetIncludeRegularExpression();
3192 return output.c_str();
3194 else if (!strcmp("LISTFILE_STACK",prop))
3196 for (std::deque<cmStdString>::iterator i = this->ListFileStack.begin();
3197 i != this->ListFileStack.end(); ++i)
3199 if (i != this->ListFileStack.begin())
3201 output += ";";
3203 output += *i;
3205 return output.c_str();
3207 else if (!strcmp("VARIABLES",prop) || !strcmp("CACHE_VARIABLES",prop))
3209 int cacheonly = 0;
3210 if ( !strcmp("CACHE_VARIABLES",prop) )
3212 cacheonly = 1;
3214 std::vector<std::string> vars = this->GetDefinitions(cacheonly);
3215 for (unsigned int cc = 0; cc < vars.size(); cc ++ )
3217 if ( cc > 0 )
3219 output += ";";
3221 output += vars[cc];
3223 return output.c_str();
3225 else if (!strcmp("MACROS",prop))
3227 this->GetListOfMacros(output);
3228 return output.c_str();
3230 else if (!strcmp("DEFINITIONS",prop))
3232 output += this->DefineFlagsOrig;
3233 return output.c_str();
3235 else if (!strcmp("INCLUDE_DIRECTORIES",prop) )
3237 cmOStringStream str;
3238 for (std::vector<std::string>::const_iterator
3239 it = this->GetIncludeDirectories().begin();
3240 it != this->GetIncludeDirectories().end();
3241 ++ it )
3243 if ( it != this->GetIncludeDirectories().begin())
3245 str << ";";
3247 str << it->c_str();
3249 output = str.str();
3250 return output.c_str();
3252 else if (!strcmp("LINK_DIRECTORIES",prop))
3254 cmOStringStream str;
3255 for (std::vector<std::string>::const_iterator
3256 it = this->GetLinkDirectories().begin();
3257 it != this->GetLinkDirectories().end();
3258 ++ it )
3260 if ( it != this->GetLinkDirectories().begin())
3262 str << ";";
3264 str << it->c_str();
3266 output = str.str();
3267 return output.c_str();
3270 bool chain = false;
3271 const char *retVal =
3272 this->Properties.GetPropertyValue(prop, scope, chain);
3273 if (chain)
3275 if(this->LocalGenerator->GetParent())
3277 return this->LocalGenerator->GetParent()->GetMakefile()->
3278 GetProperty(prop, scope);
3280 return this->GetCMakeInstance()->GetProperty(prop,scope);
3283 return retVal;
3286 bool cmMakefile::GetPropertyAsBool(const char* prop)
3288 return cmSystemTools::IsOn(this->GetProperty(prop));
3292 cmTarget* cmMakefile::FindTarget(const char* name)
3294 cmTargets& tgts = this->GetTargets();
3296 cmTargets::iterator i = tgts.find ( name );
3297 if ( i != tgts.end() )
3299 return &i->second;
3302 return 0;
3305 //----------------------------------------------------------------------------
3306 cmTest* cmMakefile::CreateTest(const char* testName)
3308 if ( !testName )
3310 return 0;
3312 cmTest* test = this->GetTest(testName);
3313 if ( test )
3315 return test;
3317 test = new cmTest(this);
3318 test->SetName(testName);
3319 this->Tests[testName] = test;
3320 return test;
3323 //----------------------------------------------------------------------------
3324 cmTest* cmMakefile::GetTest(const char* testName) const
3326 if(testName)
3328 std::map<cmStdString, cmTest*>::const_iterator
3329 mi = this->Tests.find(testName);
3330 if(mi != this->Tests.end())
3332 return mi->second;
3335 return 0;
3338 std::string cmMakefile::GetListFileStack()
3340 cmOStringStream tmp;
3341 size_t depth = this->ListFileStack.size();
3342 if (depth > 0)
3344 std::deque<cmStdString>::iterator it = this->ListFileStack.end();
3347 if (depth != this->ListFileStack.size())
3349 tmp << "\n ";
3351 --it;
3352 tmp << "[";
3353 tmp << depth;
3354 tmp << "]\t";
3355 tmp << *it;
3356 depth--;
3358 while (it != this->ListFileStack.begin());
3360 return tmp.str();
3364 void cmMakefile::PushScope()
3366 cmDefinitions* parent = &this->Internal->VarStack.top();
3367 this->Internal->VarStack.push(cmDefinitions(parent));
3370 void cmMakefile::PopScope()
3372 this->Internal->VarStack.pop();
3375 void cmMakefile::RaiseScope(const char *var, const char *varDef)
3377 if (!var || !strlen(var))
3379 return;
3382 cmDefinitions& cur = this->Internal->VarStack.top();
3383 if(cmDefinitions* up = cur.GetParent())
3385 // First localize the definition in the current scope.
3386 cur.Get(var);
3388 // Now update the definition in the parent scope.
3389 up->Set(var, varDef);
3394 // define properties
3395 void cmMakefile::DefineProperties(cmake *cm)
3397 cm->DefineProperty
3398 ("ADDITIONAL_MAKE_CLEAN_FILES", cmProperty::DIRECTORY,
3399 "Additional files to clean during the make clean stage.",
3400 "A list of files that will be cleaned as a part of the "
3401 "\"make clean\" stage. ");
3403 cm->DefineProperty
3404 ("CLEAN_NO_CUSTOM", cmProperty::DIRECTORY,
3405 "Should the output of custom commands be left.",
3406 "If this is true then the outputs of custom commands for this "
3407 "directory will not be removed during the \"make clean\" stage. ");
3409 cm->DefineProperty
3410 ("LISTFILE_STACK", cmProperty::DIRECTORY,
3411 "The current stack of listfiles being processed.",
3412 "This property is mainly useful when trying to debug errors "
3413 "in your CMake scripts. It returns a list of what list files "
3414 "are currently being processed, in order. So if one listfile "
3415 "does an INCLUDE command then that is effectively pushing "
3416 "the included listfile onto the stack.", false);
3418 cm->DefineProperty
3419 ("TEST_INCLUDE_FILE", cmProperty::DIRECTORY,
3420 "A cmake file that will be included when ctest is run.",
3421 "If you specify TEST_INCLUDE_FILE, that file will be "
3422 "included and processed when ctest is run on the directory.");
3424 cm->DefineProperty
3425 ("COMPILE_DEFINITIONS", cmProperty::DIRECTORY,
3426 "Preprocessor definitions for compiling a directory's sources.",
3427 "The COMPILE_DEFINITIONS property may be set to a "
3428 "semicolon-separated list of preprocessor "
3429 "definitions using the syntax VAR or VAR=value. Function-style "
3430 "definitions are not supported. CMake will automatically escape "
3431 "the value correctly for the native build system (note that CMake "
3432 "language syntax may require escapes to specify some values). "
3433 "This property may be set on a per-configuration basis using the name "
3434 "COMPILE_DEFINITIONS_<CONFIG> where <CONFIG> is an upper-case name "
3435 "(ex. \"COMPILE_DEFINITIONS_DEBUG\"). "
3436 "This property will be initialized in each directory by its value "
3437 "in the directory's parent.\n"
3438 "CMake will automatically drop some definitions that "
3439 "are not supported by the native build tool. "
3440 "The VS6 IDE does not support definition values with spaces "
3441 "(but NMake does).\n"
3442 "Dislaimer: Most native build tools have poor support for escaping "
3443 "certain values. CMake has work-arounds for many cases but some "
3444 "values may just not be possible to pass correctly. If a value "
3445 "does not seem to be escaped correctly, do not attempt to "
3446 "work-around the problem by adding escape sequences to the value. "
3447 "Your work-around may break in a future version of CMake that "
3448 "has improved escape support. Instead consider defining the macro "
3449 "in a (configured) header file. Then report the limitation.");
3451 cm->DefineProperty
3452 ("COMPILE_DEFINITIONS_<CONFIG>", cmProperty::DIRECTORY,
3453 "Per-configuration preprocessor definitions in a directory.",
3454 "This is the configuration-specific version of COMPILE_DEFINITIONS. "
3455 "This property will be initialized in each directory by its value "
3456 "in the directory's parent.\n");
3458 cm->DefineProperty
3459 ("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM", cmProperty::DIRECTORY,
3460 "Specify #include line transforms for dependencies in a directory.",
3461 "This property specifies rules to transform macro-like #include lines "
3462 "during implicit dependency scanning of C and C++ source files. "
3463 "The list of rules must be semicolon-separated with each entry of "
3464 "the form \"A_MACRO(%)=value-with-%\" (the % must be literal). "
3465 "During dependency scanning occurrences of A_MACRO(...) on #include "
3466 "lines will be replaced by the value given with the macro argument "
3467 "substituted for '%'. For example, the entry\n"
3468 " MYDIR(%)=<mydir/%>\n"
3469 "will convert lines of the form\n"
3470 " #include MYDIR(myheader.h)\n"
3471 "to\n"
3472 " #include <mydir/myheader.h>\n"
3473 "allowing the dependency to be followed.\n"
3474 "This property applies to sources in all targets within a directory. "
3475 "The property value is initialized in each directory by its value "
3476 "in the directory's parent.");
3478 cm->DefineProperty
3479 ("EXCLUDE_FROM_ALL", cmProperty::DIRECTORY,
3480 "Exclude the directory from the all target of its parent.",
3481 "A property on a directory that indicates if its targets are excluded "
3482 "from the default build target. If it is not, then with a Makefile "
3483 "for example typing make will cause the targets to be built. "
3484 "The same concept applies to the default build of other generators.",
3485 false);
3487 cm->DefineProperty
3488 ("PARENT_DIRECTORY", cmProperty::DIRECTORY,
3489 "Source directory that added current subdirectory.",
3490 "This read-only property specifies the source directory that "
3491 "added the current source directory as a subdirectory of the build. "
3492 "In the top-level directory the value is the empty-string.", false);
3494 cm->DefineProperty
3495 ("INCLUDE_REGULAR_EXPRESSION", cmProperty::DIRECTORY,
3496 "Include file scanning regular expression.",
3497 "This read-only property specifies the regular expression used "
3498 "during dependency scanning to match include files that should "
3499 "be followed. See the include_regular_expression command.", false);
3501 cm->DefineProperty
3502 ("VARIABLES", cmProperty::DIRECTORY,
3503 "List of variables defined in the current directory.",
3504 "This read-only property specifies the list of CMake variables "
3505 "currently defined. "
3506 "It is intended for debugging purposes.", false);
3508 cm->DefineProperty
3509 ("CACHE_VARIABLES", cmProperty::DIRECTORY,
3510 "List of cache variables available in the current directory.",
3511 "This read-only property specifies the list of CMake cache "
3512 "variables currently defined. "
3513 "It is intended for debugging purposes.", false);
3515 cm->DefineProperty
3516 ("MACROS", cmProperty::DIRECTORY,
3517 "List of macro commands available in the current directory.",
3518 "This read-only property specifies the list of CMake macros "
3519 "currently defined. "
3520 "It is intended for debugging purposes. "
3521 "See the macro command.", false);
3523 cm->DefineProperty
3524 ("DEFINITIONS", cmProperty::DIRECTORY,
3525 "For CMake 2.4 compatibility only. Use COMPILE_DEFINITIONS instead.",
3526 "This read-only property specifies the list of flags given so far "
3527 "to the add_definitions command. "
3528 "It is intended for debugging purposes. "
3529 "Use the COMPILE_DEFINITIONS instead.", false);
3531 cm->DefineProperty
3532 ("INCLUDE_DIRECTORIES", cmProperty::DIRECTORY,
3533 "List of preprocessor include file search directories.",
3534 "This read-only property specifies the list of directories given "
3535 "so far to the include_directories command. "
3536 "It is intended for debugging purposes.", false);
3538 cm->DefineProperty
3539 ("LINK_DIRECTORIES", cmProperty::DIRECTORY,
3540 "List of linker search directories.",
3541 "This read-only property specifies the list of directories given "
3542 "so far to the link_directories command. "
3543 "It is intended for debugging purposes.", false);
3545 cm->DefineProperty
3546 ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
3547 "Specify a launcher for compile rules.",
3548 "See the global property of the same name for details. "
3549 "This overrides the global property for a directory.",
3550 true);
3551 cm->DefineProperty
3552 ("RULE_LAUNCH_LINK", cmProperty::DIRECTORY,
3553 "Specify a launcher for link rules.",
3554 "See the global property of the same name for details. "
3555 "This overrides the global property for a directory.",
3556 true);
3557 cm->DefineProperty
3558 ("RULE_LAUNCH_CUSTOM", cmProperty::DIRECTORY,
3559 "Specify a launcher for custom rules.",
3560 "See the global property of the same name for details. "
3561 "This overrides the global property for a directory.",
3562 true);
3565 //----------------------------------------------------------------------------
3566 cmTarget*
3567 cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type)
3569 // Create the target.
3570 cmsys::auto_ptr<cmTarget> target(new cmTarget);
3571 target->SetType(type, name);
3572 target->SetMakefile(this);
3573 target->MarkAsImported();
3575 // Add to the set of available imported targets.
3576 this->ImportedTargets[name] = target.get();
3578 // Transfer ownership to this cmMakefile object.
3579 this->ImportedTargetsOwned.push_back(target.get());
3580 return target.release();
3583 //----------------------------------------------------------------------------
3584 cmTarget* cmMakefile::FindTargetToUse(const char* name)
3586 // Look for an imported target. These take priority because they
3587 // are more local in scope and do not have to be globally unique.
3588 std::map<cmStdString, cmTarget*>::const_iterator
3589 imported = this->ImportedTargets.find(name);
3590 if(imported != this->ImportedTargets.end())
3592 return imported->second;
3595 // Look for a target built in this project.
3596 return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name);
3599 //----------------------------------------------------------------------------
3600 bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
3601 bool isCustom)
3603 if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
3605 // The name given conflicts with an existing target. Produce an
3606 // error in a compatible way.
3607 if(existing->IsImported())
3609 // Imported targets were not supported in previous versions.
3610 // This is new code, so we can make it an error.
3611 cmOStringStream e;
3612 e << "cannot create target \"" << name
3613 << "\" because an imported target with the same name already exists.";
3614 msg = e.str();
3615 return false;
3617 else
3619 // target names must be globally unique
3620 switch (this->GetPolicyStatus(cmPolicies::CMP0002))
3622 case cmPolicies::WARN:
3623 this->IssueMessage(cmake::AUTHOR_WARNING, this->GetPolicies()->
3624 GetPolicyWarning(cmPolicies::CMP0002));
3625 case cmPolicies::OLD:
3626 return true;
3627 case cmPolicies::REQUIRED_IF_USED:
3628 case cmPolicies::REQUIRED_ALWAYS:
3629 this->IssueMessage(cmake::FATAL_ERROR,
3630 this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0002)
3632 return true;
3633 case cmPolicies::NEW:
3634 break;
3637 // The conflict is with a non-imported target.
3638 // Allow this if the user has requested support.
3639 cmake* cm =
3640 this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
3641 if(isCustom && existing->GetType() == cmTarget::UTILITY &&
3642 this != existing->GetMakefile() &&
3643 cm->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
3645 return true;
3648 // Produce an error that tells the user how to work around the
3649 // problem.
3650 cmOStringStream e;
3651 e << "cannot create target \"" << name
3652 << "\" because another target with the same name already exists. "
3653 << "The existing target is ";
3654 switch(existing->GetType())
3656 case cmTarget::EXECUTABLE:
3657 e << "an executable ";
3658 break;
3659 case cmTarget::STATIC_LIBRARY:
3660 e << "a static library ";
3661 break;
3662 case cmTarget::SHARED_LIBRARY:
3663 e << "a shared library ";
3664 break;
3665 case cmTarget::MODULE_LIBRARY:
3666 e << "a module library ";
3667 break;
3668 case cmTarget::UTILITY:
3669 e << "a custom target ";
3670 break;
3671 default: break;
3673 e << "created in source directory \""
3674 << existing->GetMakefile()->GetCurrentDirectory() << "\". "
3675 << "See documentation for policy CMP0002 for more details.";
3676 msg = e.str();
3677 return false;
3680 return true;
3683 //----------------------------------------------------------------------------
3684 bool cmMakefile::EnforceUniqueDir(const char* srcPath, const char* binPath)
3686 // Make sure the binary directory is unique.
3687 cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
3688 if(gg->BinaryDirectoryIsNew(binPath))
3690 return true;
3692 cmOStringStream e;
3693 switch (this->GetPolicyStatus(cmPolicies::CMP0013))
3695 case cmPolicies::WARN:
3696 // Print the warning.
3697 e << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0013)
3698 << "\n"
3699 << "The binary directory\n"
3700 << " " << binPath << "\n"
3701 << "is already used to build a source directory. "
3702 << "This command uses it to build source directory\n"
3703 << " " << srcPath << "\n"
3704 << "which can generate conflicting build files. "
3705 << "CMake does not support this use case but it used "
3706 << "to work accidentally and is being allowed for "
3707 << "compatibility.";
3708 this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
3709 case cmPolicies::OLD:
3710 // OLD behavior does not warn.
3711 return true;
3712 case cmPolicies::REQUIRED_IF_USED:
3713 case cmPolicies::REQUIRED_ALWAYS:
3714 e << this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0013)
3715 << "\n";
3716 case cmPolicies::NEW:
3717 // NEW behavior prints the error.
3718 e << "The binary directory\n"
3719 << " " << binPath << "\n"
3720 << "is already used to build a source directory. "
3721 << "It cannot be used to build source directory\n"
3722 << " " << srcPath << "\n"
3723 << "Specify a unique binary directory name.";
3724 this->IssueMessage(cmake::FATAL_ERROR, e.str());
3725 break;
3728 return false;
3731 //----------------------------------------------------------------------------
3732 cmPolicies::PolicyStatus
3733 cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id)
3735 // Get the current setting of the policy.
3736 cmPolicies::PolicyStatus cur = this->GetPolicyStatusInternal(id);
3738 // If the policy is required to be set to NEW but is not, ignore the
3739 // current setting and tell the caller.
3740 if(cur != cmPolicies::NEW)
3742 if(cur == cmPolicies::REQUIRED_ALWAYS ||
3743 cur == cmPolicies::REQUIRED_IF_USED)
3745 return cur;
3747 cmPolicies::PolicyStatus def = this->GetPolicies()->GetPolicyStatus(id);
3748 if(def == cmPolicies::REQUIRED_ALWAYS ||
3749 def == cmPolicies::REQUIRED_IF_USED)
3751 return def;
3755 // The current setting is okay.
3756 return cur;
3759 //----------------------------------------------------------------------------
3760 cmPolicies::PolicyStatus
3761 cmMakefile::GetPolicyStatusInternal(cmPolicies::PolicyID id)
3763 // Is the policy set in our stack?
3764 for(PolicyStackType::reverse_iterator psi = this->PolicyStack.rbegin();
3765 psi != this->PolicyStack.rend(); ++psi)
3767 PolicyStackEntry::const_iterator pse = psi->find(id);
3768 if(pse != psi->end())
3770 return pse->second;
3774 // If we have a parent directory, recurse up to it.
3775 if(this->LocalGenerator->GetParent())
3777 cmMakefile* parent = this->LocalGenerator->GetParent()->GetMakefile();
3778 return parent->GetPolicyStatusInternal(id);
3781 // The policy is not set. Use the default for this CMake version.
3782 return this->GetPolicies()->GetPolicyStatus(id);
3785 bool cmMakefile::SetPolicy(const char *id,
3786 cmPolicies::PolicyStatus status)
3788 cmPolicies::PolicyID pid;
3789 if (!this->GetPolicies()->GetPolicyID(id, /* out */ pid))
3791 cmOStringStream e;
3792 e << "Policy \"" << id << "\" is not known to this version of CMake.";
3793 this->IssueMessage(cmake::FATAL_ERROR, e.str());
3794 return false;
3796 return this->SetPolicy(pid,status);
3799 //----------------------------------------------------------------------------
3800 bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
3801 cmPolicies::PolicyStatus status)
3803 // A REQUIRED_ALWAYS policy may be set only to NEW.
3804 if(status != cmPolicies::NEW &&
3805 this->GetPolicies()->GetPolicyStatus(id) ==
3806 cmPolicies::REQUIRED_ALWAYS)
3808 std::string msg =
3809 this->GetPolicies()->GetRequiredAlwaysPolicyError(id);
3810 this->IssueMessage(cmake::FATAL_ERROR, msg.c_str());
3811 return false;
3814 // Update the policy stack from the top to the top-most strong entry.
3815 bool previous_was_weak = true;
3816 for(PolicyStackType::reverse_iterator psi = this->PolicyStack.rbegin();
3817 previous_was_weak && psi != this->PolicyStack.rend(); ++psi)
3819 (*psi)[id] = status;
3820 previous_was_weak = psi->Weak;
3823 // Special hook for presenting compatibility variable as soon as
3824 // the user requests it.
3825 if(id == cmPolicies::CMP0001 &&
3826 (status == cmPolicies::WARN || status == cmPolicies::OLD))
3828 if(!(this->GetCacheManager()
3829 ->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
3831 // Set it to 2.4 because that is the last version where the
3832 // variable had meaning.
3833 this->AddCacheDefinition
3834 ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
3835 "For backwards compatibility, what version of CMake "
3836 "commands and "
3837 "syntax should this version of CMake try to support.",
3838 cmCacheManager::STRING);
3842 return true;
3845 //----------------------------------------------------------------------------
3846 cmMakefile::PolicyPushPop::PolicyPushPop(cmMakefile* m, bool weak,
3847 cmPolicies::PolicyMap const& pm):
3848 Makefile(m), ReportError(true)
3850 this->Makefile->PushPolicy(weak, pm);
3851 this->Makefile->PushPolicyBarrier();
3854 //----------------------------------------------------------------------------
3855 cmMakefile::PolicyPushPop::~PolicyPushPop()
3857 this->Makefile->PopPolicyBarrier(this->ReportError);
3858 this->Makefile->PopPolicy();
3861 //----------------------------------------------------------------------------
3862 void cmMakefile::PushPolicy(bool weak, cmPolicies::PolicyMap const& pm)
3864 // Allocate a new stack entry.
3865 this->PolicyStack.push_back(PolicyStackEntry(pm, weak));
3868 //----------------------------------------------------------------------------
3869 void cmMakefile::PopPolicy()
3871 if(this->PolicyStack.size() > this->PolicyBarriers.back())
3873 this->PolicyStack.pop_back();
3875 else
3877 this->IssueMessage(cmake::FATAL_ERROR,
3878 "cmake_policy POP without matching PUSH");
3882 //----------------------------------------------------------------------------
3883 void cmMakefile::PushPolicyBarrier()
3885 this->PolicyBarriers.push_back(this->PolicyStack.size());
3888 //----------------------------------------------------------------------------
3889 void cmMakefile::PopPolicyBarrier(bool reportError)
3891 // Remove any extra entries pushed on the barrier.
3892 PolicyStackType::size_type barrier = this->PolicyBarriers.back();
3893 while(this->PolicyStack.size() > barrier)
3895 if(reportError)
3897 this->IssueMessage(cmake::FATAL_ERROR,
3898 "cmake_policy PUSH without matching POP");
3899 reportError = false;
3901 this->PopPolicy();
3904 // Remove the barrier.
3905 this->PolicyBarriers.pop_back();
3908 bool cmMakefile::SetPolicyVersion(const char *version)
3910 return this->GetCMakeInstance()->GetPolicies()->
3911 ApplyPolicyVersion(this,version);
3914 cmPolicies *cmMakefile::GetPolicies()
3916 if (!this->GetCMakeInstance())
3918 return 0;
3920 return this->GetCMakeInstance()->GetPolicies();
3923 //----------------------------------------------------------------------------
3924 void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
3926 /* Record the setting of every policy. */
3927 typedef cmPolicies::PolicyID PolicyID;
3928 for(PolicyID pid = cmPolicies::CMP0000;
3929 pid != cmPolicies::CMPCOUNT; pid = PolicyID(pid+1))
3931 pm[pid] = this->GetPolicyStatus(pid);