Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmMakefile.cxx
blobae575ebe4a2dd2e909c5c4bf2bb9132b1d74d015
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmMakefile.cxx,v $
5 Language: C++
6 Date: $Date: 2008-03-31 17:33:09 $
7 Version: $Revision: 1.466 $
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 "cmake.h"
36 #include <stdlib.h> // required for atoi
38 #include <cmsys/RegularExpression.hxx>
40 #include <cmsys/auto_ptr.hxx>
42 #include <ctype.h> // for isspace
44 // default is not to be building executables
45 cmMakefile::cmMakefile()
47 this->DefinitionStack.push_back(DefinitionMap());
49 // Setup the default include file regular expression (match everything).
50 this->IncludeFileRegularExpression = "^.*$";
51 // Setup the default include complaint regular expression (match nothing).
52 this->ComplainFileRegularExpression = "^$";
53 // Source and header file extensions that we can handle
55 // Set up a list of source and header extensions
56 // these are used to find files when the extension
57 // is not given
58 // The "c" extension MUST precede the "C" extension.
59 this->SourceFileExtensions.push_back( "c" );
60 this->SourceFileExtensions.push_back( "C" );
62 this->SourceFileExtensions.push_back( "c++" );
63 this->SourceFileExtensions.push_back( "cc" );
64 this->SourceFileExtensions.push_back( "cpp" );
65 this->SourceFileExtensions.push_back( "cxx" );
66 this->SourceFileExtensions.push_back( "m" );
67 this->SourceFileExtensions.push_back( "M" );
68 this->SourceFileExtensions.push_back( "mm" );
70 this->HeaderFileExtensions.push_back( "h" );
71 this->HeaderFileExtensions.push_back( "hh" );
72 this->HeaderFileExtensions.push_back( "h++" );
73 this->HeaderFileExtensions.push_back( "hm" );
74 this->HeaderFileExtensions.push_back( "hpp" );
75 this->HeaderFileExtensions.push_back( "hxx" );
76 this->HeaderFileExtensions.push_back( "in" );
77 this->HeaderFileExtensions.push_back( "txx" );
79 this->DefineFlags = " ";
80 this->LocalGenerator = 0;
82 #if defined(CMAKE_BUILD_WITH_CMAKE)
83 this->AddSourceGroup("", "^.*$");
84 this->AddSourceGroup
85 ("Source Files",
86 "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat)$");
87 this->AddSourceGroup("Header Files",
88 "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
89 this->AddSourceGroup("CMake Rules", "\\.rule$");
90 this->AddSourceGroup("Resources", "\\.plist$");
91 #endif
92 this->AddDefaultDefinitions();
93 this->Initialize();
94 this->PreOrder = false;
97 cmMakefile::cmMakefile(const cmMakefile& mf)
99 this->Prefix = mf.Prefix;
100 this->AuxSourceDirectories = mf.AuxSourceDirectories;
101 this->cmStartDirectory = mf.cmStartDirectory;
102 this->StartOutputDirectory = mf.StartOutputDirectory;
103 this->cmHomeDirectory = mf.cmHomeDirectory;
104 this->HomeOutputDirectory = mf.HomeOutputDirectory;
105 this->cmCurrentListFile = mf.cmCurrentListFile;
106 this->ProjectName = mf.ProjectName;
107 this->Targets = mf.Targets;
108 this->SourceFiles = mf.SourceFiles;
109 this->Tests = mf.Tests;
110 this->IncludeDirectories = mf.IncludeDirectories;
111 this->LinkDirectories = mf.LinkDirectories;
112 this->SystemIncludeDirectories = mf.SystemIncludeDirectories;
113 this->ListFiles = mf.ListFiles;
114 this->OutputFiles = mf.OutputFiles;
115 this->LinkLibraries = mf.LinkLibraries;
116 this->InstallGenerators = mf.InstallGenerators;
117 this->IncludeFileRegularExpression = mf.IncludeFileRegularExpression;
118 this->ComplainFileRegularExpression = mf.ComplainFileRegularExpression;
119 this->SourceFileExtensions = mf.SourceFileExtensions;
120 this->HeaderFileExtensions = mf.HeaderFileExtensions;
121 this->DefineFlags = mf.DefineFlags;
123 #if defined(CMAKE_BUILD_WITH_CMAKE)
124 this->SourceGroups = mf.SourceGroups;
125 #endif
127 this->DefinitionStack.push_back(mf.DefinitionStack.back());
128 this->LocalGenerator = mf.LocalGenerator;
129 this->FunctionBlockers = mf.FunctionBlockers;
130 this->DataMap = mf.DataMap;
131 this->MacrosMap = mf.MacrosMap;
132 this->SubDirectoryOrder = mf.SubDirectoryOrder;
133 this->TemporaryDefinitionKey = mf.TemporaryDefinitionKey;
134 this->Properties = mf.Properties;
135 this->PreOrder = mf.PreOrder;
136 this->ListFileStack = mf.ListFileStack;
137 this->Initialize();
140 //----------------------------------------------------------------------------
141 void cmMakefile::Initialize()
143 this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
144 this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
145 this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
147 // Enter a policy level for this directory.
148 this->PushPolicy();
150 // By default the check is not done. It is enabled by
151 // cmListFileCache in the top level if necessary.
152 this->CheckCMP0000 = false;
155 unsigned int cmMakefile::GetCacheMajorVersion()
157 return this->GetCacheManager()->GetCacheMajorVersion();
160 unsigned int cmMakefile::GetCacheMinorVersion()
162 return this->GetCacheManager()->GetCacheMinorVersion();
165 bool cmMakefile::NeedCacheCompatibility(int major, int minor)
167 return this->GetCacheManager()->NeedCacheCompatibility(major, minor);
170 cmMakefile::~cmMakefile()
172 for(std::vector<cmInstallGenerator*>::iterator
173 i = this->InstallGenerators.begin();
174 i != this->InstallGenerators.end(); ++i)
176 delete *i;
178 for(std::vector<cmSourceFile*>::iterator i = this->SourceFiles.begin();
179 i != this->SourceFiles.end(); ++i)
181 delete *i;
183 for(std::vector<cmTest*>::iterator i = this->Tests.begin();
184 i != this->Tests.end(); ++i)
186 delete *i;
188 for(std::vector<cmTarget*>::iterator
189 i = this->ImportedTargetsOwned.begin();
190 i != this->ImportedTargetsOwned.end(); ++i)
192 delete *i;
194 for(unsigned int i=0; i < this->UsedCommands.size(); i++)
196 delete this->UsedCommands[i];
198 for(DataMapType::const_iterator d = this->DataMap.begin();
199 d != this->DataMap.end(); ++d)
201 if(d->second)
203 delete d->second;
206 std::list<cmFunctionBlocker *>::iterator pos;
207 for (pos = this->FunctionBlockers.begin();
208 pos != this->FunctionBlockers.end(); ++pos)
210 cmFunctionBlocker* b = *pos;
211 delete b;
213 this->FunctionBlockers.clear();
214 if (this->PolicyStack.size() != 1)
216 cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
217 " popped properly");
221 void cmMakefile::PrintStringVector(const char* s,
222 const std::vector<std::string>& v) const
224 std::cout << s << ": ( \n";
225 for(std::vector<std::string>::const_iterator i = v.begin();
226 i != v.end(); ++i)
228 std::cout << (*i).c_str() << " ";
230 std::cout << " )\n";
233 void cmMakefile
234 ::PrintStringVector(const char* s,
235 const std::vector<std::pair<cmStdString, bool> >& v) const
237 std::cout << s << ": ( \n";
238 for(std::vector<std::pair<cmStdString, bool> >::const_iterator i
239 = v.begin(); i != v.end(); ++i)
241 std::cout << i->first.c_str() << " " << i->second;
243 std::cout << " )\n";
247 // call print on all the classes in the makefile
248 void cmMakefile::Print()
250 // print the class lists
251 std::cout << "classes:\n";
253 std::cout << " this->Targets: ";
254 for (cmTargets::iterator l = this->Targets.begin();
255 l != this->Targets.end(); l++)
257 std::cout << l->first << std::endl;
260 std::cout << " this->StartOutputDirectory; " <<
261 this->StartOutputDirectory.c_str() << std::endl;
262 std::cout << " this->HomeOutputDirectory; " <<
263 this->HomeOutputDirectory.c_str() << std::endl;
264 std::cout << " this->cmStartDirectory; " <<
265 this->cmStartDirectory.c_str() << std::endl;
266 std::cout << " this->cmHomeDirectory; " <<
267 this->cmHomeDirectory.c_str() << std::endl;
268 std::cout << " this->ProjectName; "
269 << this->ProjectName.c_str() << std::endl;
270 this->PrintStringVector("this->IncludeDirectories;",
271 this->IncludeDirectories);
272 this->PrintStringVector("this->LinkDirectories", this->LinkDirectories);
273 #if defined(CMAKE_BUILD_WITH_CMAKE)
274 for( std::vector<cmSourceGroup>::const_iterator i =
275 this->SourceGroups.begin(); i != this->SourceGroups.end(); ++i)
277 std::cout << "Source Group: " << i->GetName() << std::endl;
279 #endif
282 bool cmMakefile::CommandExists(const char* name) const
284 return this->GetCMakeInstance()->CommandExists(name);
288 //----------------------------------------------------------------------------
289 void cmMakefile::IssueMessage(cmake::MessageType t,
290 std::string const& text) const
292 // Collect context information.
293 cmListFileBacktrace backtrace;
294 if(!this->CallStack.empty())
296 if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR))
298 this->CallStack.back().Status->SetNestedError(true);
300 this->GetBacktrace(backtrace);
302 else if(!this->ListFileStack.empty())
304 // We are processing the project but are not currently executing a
305 // command. Add whatever context information we have.
306 cmListFileContext lfc;
307 lfc.FilePath = this->ListFileStack.back();
308 lfc.Line = 0;
309 if(!this->GetCMakeInstance()->GetIsInTryCompile())
311 lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath.c_str(),
312 cmLocalGenerator::HOME);
314 backtrace.push_back(lfc);
317 // Issue the message.
318 this->GetCMakeInstance()->IssueMessage(t, text, backtrace);
321 //----------------------------------------------------------------------------
322 bool cmMakefile::GetBacktrace(cmListFileBacktrace& backtrace) const
324 if(this->CallStack.empty())
326 return false;
328 for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
329 i != this->CallStack.rend(); ++i)
331 cmListFileContext lfc = *(*i).Context;
332 lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath.c_str(),
333 cmLocalGenerator::HOME);
334 backtrace.push_back(lfc);
336 return true;
339 //----------------------------------------------------------------------------
340 // Helper class to make sure the call stack is valid.
341 class cmMakefileCall
343 public:
344 cmMakefileCall(cmMakefile* mf,
345 cmListFileContext const& lfc,
346 cmExecutionStatus& status): Makefile(mf)
348 cmMakefile::CallStackEntry entry = {&lfc, &status};
349 this->Makefile->CallStack.push_back(entry);
351 ~cmMakefileCall()
353 this->Makefile->CallStack.pop_back();
355 private:
356 cmMakefile* Makefile;
359 //----------------------------------------------------------------------------
360 bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
361 cmExecutionStatus &status)
363 bool result = true;
365 // quick return if blocked
366 if(this->IsFunctionBlocked(lff,status))
368 // No error.
369 return result;
372 std::string name = lff.Name;
374 // Place this call on the call stack.
375 cmMakefileCall stack_manager(this, lff, status);
376 static_cast<void>(stack_manager);
378 // Lookup the command prototype.
379 if(cmCommand* proto = this->GetCMakeInstance()->GetCommand(name.c_str()))
381 // Clone the prototype.
382 cmsys::auto_ptr<cmCommand> pcmd(proto->Clone());
383 pcmd->SetMakefile(this);
385 // Decide whether to invoke the command.
386 if(pcmd->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() &&
387 (!this->GetCMakeInstance()->GetScriptMode() || pcmd->IsScriptable()))
389 // Try invoking the command.
390 if(!pcmd->InvokeInitialPass(lff.Arguments,status) ||
391 status.GetNestedError())
393 if(!status.GetNestedError())
395 // The command invocation requested that we report an error.
396 this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError());
398 result = false;
399 if ( this->GetCMakeInstance()->GetScriptMode() )
401 cmSystemTools::SetFatalErrorOccured();
404 else
406 // use the command
407 this->UsedCommands.push_back(pcmd.release());
410 else if ( this->GetCMakeInstance()->GetScriptMode()
411 && !pcmd->IsScriptable() )
413 std::string error = "Command ";
414 error += pcmd->GetName();
415 error += "() is not scriptable";
416 this->IssueMessage(cmake::FATAL_ERROR, error);
417 result = false;
418 cmSystemTools::SetFatalErrorOccured();
421 else
423 if(!cmSystemTools::GetFatalErrorOccured())
425 std::string error = "Unknown CMake command \"";
426 error += lff.Name;
427 error += "\".";
428 this->IssueMessage(cmake::FATAL_ERROR, error);
429 result = false;
430 cmSystemTools::SetFatalErrorOccured();
434 return result;
437 // Parse the given CMakeLists.txt file executing all commands
439 bool cmMakefile::ReadListFile(const char* filename_in,
440 const char *external_in,
441 std::string* fullPath)
443 std::string currentParentFile
444 = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
445 std::string currentFile
446 = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
447 this->AddDefinition("CMAKE_PARENT_LIST_FILE", filename_in);
449 // used to watch for blockers going out of scope
450 // e.g. mismatched IF statement
451 std::set<cmFunctionBlocker *> originalBlockers;
453 const char* external = 0;
454 std::string external_abs;
456 const char* filename = filename_in;
457 std::string filename_abs;
459 if (external_in)
461 external_abs =
462 cmSystemTools::CollapseFullPath(external_in,
463 this->cmStartDirectory.c_str());
464 external = external_abs.c_str();
465 if (filename_in)
467 filename_abs =
468 cmSystemTools::CollapseFullPath(filename_in,
469 this->cmStartDirectory.c_str());
470 filename = filename_abs.c_str();
474 // keep track of the current file being read
475 if (filename)
477 if(this->cmCurrentListFile != filename)
479 this->cmCurrentListFile = filename;
481 // loop over current function blockers and record them
482 std::list<cmFunctionBlocker *>::iterator pos;
483 for (pos = this->FunctionBlockers.begin();
484 pos != this->FunctionBlockers.end(); ++pos)
486 originalBlockers.insert(*pos);
490 // Now read the input file
491 const char *filenametoread= filename;
493 if( external)
495 filenametoread= external;
498 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
500 // try to see if the list file is the top most
501 // list file for a project, and if it is, then it
502 // must have a project command. If there is not
503 // one, then cmake will provide one via the
504 // cmListFileCache class.
505 bool requireProjectCommand = false;
506 if(!external && this->cmStartDirectory == this->cmHomeDirectory)
508 if(cmSystemTools::LowerCase(
509 cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt")
511 requireProjectCommand = true;
515 // push the listfile onto the stack
516 this->ListFileStack.push_back(filenametoread);
517 if(fullPath!=0)
519 *fullPath=filenametoread;
521 cmListFile cacheFile;
522 if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
524 // pop the listfile off the stack
525 this->ListFileStack.pop_back();
526 if(fullPath!=0)
528 *fullPath = "";
530 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
531 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
532 return false;
534 // add this list file to the list of dependencies
535 this->ListFiles.push_back( filenametoread);
536 bool endScopeNicely = filename? true: false;
537 const size_t numberFunctions = cacheFile.Functions.size();
538 for(size_t i =0; i < numberFunctions; ++i)
540 cmExecutionStatus status;
541 this->ExecuteCommand(cacheFile.Functions[i],status);
542 if (status.GetReturnInvoked() ||
543 cmSystemTools::GetFatalErrorOccured() )
545 // Exit early from processing this file.
546 endScopeNicely = false;
547 break;
551 // send scope ended to and function blockers
552 if (endScopeNicely)
554 // loop over all function blockers to see if any block this command
555 std::list<cmFunctionBlocker *>::iterator pos;
556 for (pos = this->FunctionBlockers.begin();
557 pos != this->FunctionBlockers.end(); ++pos)
559 // if this blocker was not in the original then send a
560 // scope ended message
561 if (originalBlockers.find(*pos) == originalBlockers.end())
563 (*pos)->ScopeEnded(*this);
568 // If this is the directory-level CMakeLists.txt file then perform
569 // some extra checks.
570 if(this->ListFileStack.size() == 1)
572 this->EnforceDirectoryLevelRules(endScopeNicely);
575 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
576 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
578 // pop the listfile off the stack
579 this->ListFileStack.pop_back();
581 return true;
584 //----------------------------------------------------------------------------
585 void cmMakefile::EnforceDirectoryLevelRules(bool endScopeNicely)
587 // Enforce policy stack depth.
588 while(this->PolicyStack.size() > 1)
590 if(endScopeNicely)
592 this->IssueMessage(cmake::FATAL_ERROR,
593 "cmake_policy PUSH without matching POP");
595 this->PopPolicy(false);
598 // Diagnose a violation of CMP0000 if necessary.
599 if(this->CheckCMP0000)
601 cmOStringStream msg;
602 msg << "No cmake_minimum_required command is present. "
603 << "A line of code such as\n"
604 << " cmake_minimum_required(VERSION "
605 << cmVersion::GetMajorVersion() << "."
606 << cmVersion::GetMinorVersion()
607 << ")\n"
608 << "should be added at the top of the file. "
609 << "The version specified may be lower if you wish to "
610 << "support older CMake versions for this project. "
611 << "For more information run "
612 << "\"cmake --help-policy CMP0000\".";
613 switch (this->GetPolicyStatus(cmPolicies::CMP0000))
615 case cmPolicies::WARN:
616 // Warn because the user did not provide a mimimum required
617 // version.
618 this->IssueMessage(cmake::AUTHOR_WARNING, msg.str().c_str());
619 case cmPolicies::OLD:
620 // OLD behavior is to use policy version 2.4 set in
621 // cmListFileCache.
622 break;
623 case cmPolicies::REQUIRED_IF_USED:
624 case cmPolicies::REQUIRED_ALWAYS:
625 case cmPolicies::NEW:
626 // NEW behavior is to issue an error.
627 this->IssueMessage(cmake::FATAL_ERROR, msg.str().c_str());
628 cmSystemTools::SetFatalErrorOccured();
629 return;
634 void cmMakefile::AddCommand(cmCommand* wg)
636 this->GetCMakeInstance()->AddCommand(wg);
639 // Set the make file
640 void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
642 this->LocalGenerator = lg;
645 bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
646 unsigned int minor,
647 unsigned int patch)
649 if(this->LocalGenerator)
651 return
652 this->LocalGenerator->NeedBackwardsCompatibility(major, minor, patch);
654 else
656 return false;
660 void cmMakefile::FinalPass()
662 // do all the variable expansions here
663 this->ExpandVariables();
665 // give all the commands a chance to do something
666 // after the file has been parsed before generation
667 for(std::vector<cmCommand*>::iterator i = this->UsedCommands.begin();
668 i != this->UsedCommands.end(); ++i)
670 (*i)->FinalPass();
675 // Generate the output file
676 void cmMakefile::ConfigureFinalPass()
678 this->FinalPass();
679 const char* oldValue
680 = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
681 if (oldValue && atof(oldValue) <= 1.2)
683 cmSystemTools::Error("You have requested backwards compatibility "
684 "with CMake version 1.2 or earlier. This version "
685 "of CMake only supports backwards compatibility "
686 "with CMake 1.4 or later. For compatibility with "
687 "1.2 or earlier please use CMake 2.0");
689 for (cmTargets::iterator l = this->Targets.begin();
690 l != this->Targets.end(); l++)
692 l->second.AnalyzeLibDependencies(*this);
696 //----------------------------------------------------------------------------
697 void
698 cmMakefile::AddCustomCommandToTarget(const char* target,
699 const std::vector<std::string>& depends,
700 const cmCustomCommandLines& commandLines,
701 cmTarget::CustomCommandType type,
702 const char* comment,
703 const char* workingDir,
704 bool escapeOldStyle)
706 // Find the target to which to add the custom command.
707 cmTargets::iterator ti = this->Targets.find(target);
708 if(ti != this->Targets.end())
710 // Add the command to the appropriate build step for the target.
711 std::vector<std::string> no_output;
712 cmCustomCommand cc(no_output, depends, commandLines, comment, workingDir);
713 cc.SetEscapeOldStyle(escapeOldStyle);
714 switch(type)
716 case cmTarget::PRE_BUILD:
717 ti->second.GetPreBuildCommands().push_back(cc);
718 break;
719 case cmTarget::PRE_LINK:
720 ti->second.GetPreLinkCommands().push_back(cc);
721 break;
722 case cmTarget::POST_BUILD:
723 ti->second.GetPostBuildCommands().push_back(cc);
724 break;
729 //----------------------------------------------------------------------------
730 void
731 cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
732 const std::vector<std::string>& depends,
733 const char* main_dependency,
734 const cmCustomCommandLines& commandLines,
735 const char* comment,
736 const char* workingDir,
737 bool replace,
738 bool escapeOldStyle)
740 // Make sure there is at least one output.
741 if(outputs.empty())
743 cmSystemTools::Error("Attempt to add a custom rule with no output!");
744 return;
747 // Choose a source file on which to store the custom command.
748 cmSourceFile* file = 0;
749 if(main_dependency && main_dependency[0])
751 // The main dependency was specified. Use it unless a different
752 // custom command already used it.
753 file = this->GetSource(main_dependency);
754 if(file && file->GetCustomCommand() && !replace)
756 // The main dependency already has a custom command.
757 if(commandLines == file->GetCustomCommand()->GetCommandLines())
759 // The existing custom command is identical. Silently ignore
760 // the duplicate.
761 return;
763 else
765 // The existing custom command is different. We need to
766 // generate a rule file for this new command.
767 file = 0;
770 else
772 // The main dependency does not have a custom command or we are
773 // allowed to replace it. Use it to store the command.
774 file = this->GetOrCreateSource(main_dependency);
778 // Generate a rule file if the main dependency is not available.
779 if(!file)
781 // Construct a rule file associated with the first output produced.
782 std::string outName = outputs[0];
783 outName += ".rule";
785 // Check if the rule file already exists.
786 file = this->GetSource(outName.c_str());
787 if(file && file->GetCustomCommand() && !replace)
789 // The rule file already exists.
790 if(commandLines != file->GetCustomCommand()->GetCommandLines())
792 cmSystemTools::Error("Attempt to add a custom rule to output \"",
793 outName.c_str(),
794 "\" which already has a custom rule.");
796 return;
799 // Create a cmSourceFile for the rule file.
800 file = this->GetOrCreateSource(outName.c_str(), true);
803 // Always create the output sources and mark them generated.
804 for(std::vector<std::string>::const_iterator o = outputs.begin();
805 o != outputs.end(); ++o)
807 if(cmSourceFile* out = this->GetOrCreateSource(o->c_str(), true))
809 out->SetProperty("GENERATED", "1");
813 // Construct a complete list of dependencies.
814 std::vector<std::string> depends2(depends);
815 if(main_dependency && main_dependency[0])
817 depends2.push_back(main_dependency);
820 // Attach the custom command to the file.
821 if(file)
823 cmCustomCommand* cc =
824 new cmCustomCommand(outputs, depends2, commandLines,
825 comment, workingDir);
826 cc->SetEscapeOldStyle(escapeOldStyle);
827 file->SetCustomCommand(cc);
831 //----------------------------------------------------------------------------
832 void
833 cmMakefile::AddCustomCommandToOutput(const char* output,
834 const std::vector<std::string>& depends,
835 const char* main_dependency,
836 const cmCustomCommandLines& commandLines,
837 const char* comment,
838 const char* workingDir,
839 bool replace,
840 bool escapeOldStyle)
842 std::vector<std::string> outputs;
843 outputs.push_back(output);
844 this->AddCustomCommandToOutput(outputs, depends, main_dependency,
845 commandLines, comment, workingDir,
846 replace, escapeOldStyle);
849 //----------------------------------------------------------------------------
850 void
851 cmMakefile::AddCustomCommandOldStyle(const char* target,
852 const std::vector<std::string>& outputs,
853 const std::vector<std::string>& depends,
854 const char* source,
855 const cmCustomCommandLines& commandLines,
856 const char* comment)
858 // Translate the old-style signature to one of the new-style
859 // signatures.
860 if(strcmp(source, target) == 0)
862 // In the old-style signature if the source and target were the
863 // same then it added a post-build rule to the target. Preserve
864 // this behavior.
865 this->AddCustomCommandToTarget(target, depends, commandLines,
866 cmTarget::POST_BUILD, comment, 0);
867 return;
870 // Each output must get its own copy of this rule.
871 cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|"
872 "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
873 "hm|hpp|hxx|in|txx|inl)$");
874 for(std::vector<std::string>::const_iterator oi = outputs.begin();
875 oi != outputs.end(); ++oi)
877 // Get the name of this output.
878 const char* output = oi->c_str();
880 // Choose whether to use a main dependency.
881 if(sourceFiles.find(source))
883 // The source looks like a real file. Use it as the main dependency.
884 this->AddCustomCommandToOutput(output, depends, source,
885 commandLines, comment, 0);
887 else
889 // The source may not be a real file. Do not use a main dependency.
890 const char* no_main_dependency = 0;
891 std::vector<std::string> depends2 = depends;
892 depends2.push_back(source);
893 this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
894 commandLines, comment, 0);
897 // If the rule was added to the source (and not a .rule file),
898 // then add the source to the target to make sure the rule is
899 // included.
900 std::string sname = output;
901 sname += ".rule";
902 if(!this->GetSource(sname.c_str()))
904 if (this->Targets.find(target) != this->Targets.end())
906 this->Targets[target].AddSource(source);
908 else
910 cmSystemTools::Error("Attempt to add a custom rule to a target "
911 "that does not exist yet for target ", target);
912 return;
918 //----------------------------------------------------------------------------
919 void cmMakefile::AddUtilityCommand(const char* utilityName,
920 bool excludeFromAll,
921 const std::vector<std::string>& depends,
922 const char* workingDirectory,
923 const char* command,
924 const char* arg1,
925 const char* arg2,
926 const char* arg3,
927 const char* arg4)
929 // Construct the command line for the custom command.
930 cmCustomCommandLine commandLine;
931 commandLine.push_back(command);
932 if(arg1)
934 commandLine.push_back(arg1);
936 if(arg2)
938 commandLine.push_back(arg2);
940 if(arg3)
942 commandLine.push_back(arg3);
944 if(arg4)
946 commandLine.push_back(arg4);
948 cmCustomCommandLines commandLines;
949 commandLines.push_back(commandLine);
951 // Call the real signature of this method.
952 this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
953 depends, commandLines);
956 //----------------------------------------------------------------------------
957 void cmMakefile::AddUtilityCommand(const char* utilityName,
958 bool excludeFromAll,
959 const char* workingDirectory,
960 const std::vector<std::string>& depends,
961 const cmCustomCommandLines& commandLines,
962 bool escapeOldStyle, const char* comment)
964 // Create a target instance for this utility.
965 cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
966 if (excludeFromAll)
968 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
970 if(!comment)
972 // Use an empty comment to avoid generation of default comment.
973 comment = "";
976 // Store the custom command in the target.
977 std::string force = this->GetStartOutputDirectory();
978 force += cmake::GetCMakeFilesDirectory();
979 force += "/";
980 force += utilityName;
981 const char* no_main_dependency = 0;
982 bool no_replace = false;
983 this->AddCustomCommandToOutput(force.c_str(), depends,
984 no_main_dependency,
985 commandLines, comment,
986 workingDirectory, no_replace,
987 escapeOldStyle);
988 cmSourceFile* sf = target->AddSource(force.c_str());
990 // The output is not actually created so mark it symbolic.
991 if(sf)
993 sf->SetProperty("SYMBOLIC", "1");
995 else
997 cmSystemTools::Error("Could not get source file entry for ",
998 force.c_str());
1002 void cmMakefile::AddDefineFlag(const char* flag)
1004 if (!flag)
1006 return;
1009 // If this is really a definition, update COMPILE_DEFINITIONS.
1010 if(this->ParseDefineFlag(flag, false))
1012 return;
1015 // remove any \n\r
1016 std::string ret = flag;
1017 std::string::size_type pos = 0;
1018 while((pos = ret.find('\n', pos)) != std::string::npos)
1020 ret[pos] = ' ';
1021 pos++;
1023 pos = 0;
1024 while((pos = ret.find('\r', pos)) != std::string::npos)
1026 ret[pos] = ' ';
1027 pos++;
1030 this->DefineFlags += " ";
1031 this->DefineFlags += ret;
1035 void cmMakefile::RemoveDefineFlag(const char* flag)
1037 // Check the length of the flag to remove.
1038 std::string::size_type len = strlen(flag);
1039 if(len < 1)
1041 return;
1044 // If this is really a definition, update COMPILE_DEFINITIONS.
1045 if(this->ParseDefineFlag(flag, true))
1047 return;
1050 // Remove all instances of the flag that are surrounded by
1051 // whitespace or the beginning/end of the string.
1052 for(std::string::size_type lpos = this->DefineFlags.find(flag, 0);
1053 lpos != std::string::npos; lpos = this->DefineFlags.find(flag, lpos))
1055 std::string::size_type rpos = lpos + len;
1056 if((lpos <= 0 || isspace(this->DefineFlags[lpos-1])) &&
1057 (rpos >= this->DefineFlags.size() || isspace(this->DefineFlags[rpos])))
1059 this->DefineFlags.erase(lpos, len);
1061 else
1063 ++lpos;
1068 bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
1070 // Create a regular expression to match valid definitions.
1071 static cmsys::RegularExpression
1072 valid("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=.*)?$");
1074 // Make sure the definition matches.
1075 if(!valid.find(def.c_str()))
1077 return false;
1080 // VS6 IDE does not support definitions with values.
1081 if((strcmp(this->LocalGenerator->GetGlobalGenerator()->GetName(),
1082 "Visual Studio 6") == 0) &&
1083 (def.find("=") != def.npos))
1085 return false;
1088 // Definitions with non-trivial values require a policy check.
1089 static cmsys::RegularExpression
1090 trivial("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=[A-Za-z0-9_.]+)?$");
1091 if(!trivial.find(def.c_str()))
1093 // This definition has a non-trivial value.
1094 switch(this->GetPolicyStatus(cmPolicies::CMP0005))
1096 case cmPolicies::WARN:
1097 this->IssueMessage(
1098 cmake::AUTHOR_WARNING,
1099 this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0005)
1101 case cmPolicies::OLD:
1102 // OLD behavior is to not escape the value. We should not
1103 // convert the definition to use the property.
1104 return false;
1105 case cmPolicies::REQUIRED_IF_USED:
1106 case cmPolicies::REQUIRED_ALWAYS:
1107 this->IssueMessage(
1108 cmake::FATAL_ERROR,
1109 this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0005)
1111 return false;
1112 case cmPolicies::NEW:
1113 // NEW behavior is to escape the value. Proceed to convert it
1114 // to an entry in the property.
1115 break;
1119 // Get the definition part after the flag.
1120 const char* define = def.c_str() + 2;
1122 if(remove)
1124 if(const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS"))
1126 // Expand the list.
1127 std::vector<std::string> defs;
1128 cmSystemTools::ExpandListArgument(cdefs, defs);
1130 // Recompose the list without the definition.
1131 std::string ndefs;
1132 const char* sep = "";
1133 for(std::vector<std::string>::const_iterator di = defs.begin();
1134 di != defs.end(); ++di)
1136 if(*di != define)
1138 ndefs += sep;
1139 sep = ";";
1140 ndefs += *di;
1144 // Store the new list.
1145 this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
1148 else
1150 // Append the definition to the directory property.
1151 this->AppendProperty("COMPILE_DEFINITIONS", define);
1154 return true;
1157 void cmMakefile::AddLinkLibrary(const char* lib,
1158 cmTarget::LinkLibraryType llt)
1160 cmTarget::LibraryID tmp;
1161 tmp.first = lib;
1162 tmp.second = llt;
1163 this->LinkLibraries.push_back(tmp);
1166 void cmMakefile::AddLinkLibraryForTarget(const char *target,
1167 const char* lib,
1168 cmTarget::LinkLibraryType llt)
1170 cmTargets::iterator i = this->Targets.find(target);
1171 if ( i != this->Targets.end())
1173 cmTarget* tgt =
1174 this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib);
1175 if(tgt)
1177 // CMake versions below 2.4 allowed linking to modules.
1178 bool allowModules = this->NeedBackwardsCompatibility(2,3);
1179 // if it is not a static or shared library then you can not link to it
1180 if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
1181 (tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
1182 tgt->IsExecutableWithExports()))
1184 cmOStringStream e;
1185 e << "Attempt to add link target " << lib << " of type: "
1186 << cmTarget::TargetTypeNames[static_cast<int>(tgt->GetType())]
1187 << "\nto target " << target
1188 << ". One can only link to STATIC or SHARED libraries, or "
1189 << "to executables with the ENABLE_EXPORTS property set.";
1190 // in older versions of cmake linking to modules was allowed
1191 if( tgt->GetType() == cmTarget::MODULE_LIBRARY )
1193 e <<
1194 "\nTo allow linking of modules set "
1195 "CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower\n";
1197 // if no modules are allowed then this is always an error
1198 if(!allowModules ||
1199 // if we allow modules but the type is not a module then it is
1200 // still an error
1201 (allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY))
1203 cmSystemTools::Error(e.str().c_str());
1207 i->second.AddLinkLibrary( *this, target, lib, llt );
1209 else
1211 cmOStringStream e;
1212 e << "Attempt to add link library \""
1213 << lib << "\" to target \""
1214 << target << "\" which is not built by this project.";
1215 cmSystemTools::Error(e.str().c_str());
1219 void cmMakefile::AddLinkDirectoryForTarget(const char *target,
1220 const char* d)
1222 cmTargets::iterator i = this->Targets.find(target);
1223 if ( i != this->Targets.end())
1225 i->second.AddLinkDirectory( d );
1227 else
1229 cmSystemTools::Error
1230 ("Attempt to add link directories to non-existant target: ",
1231 target, " for directory ", d);
1235 void cmMakefile::AddLinkLibrary(const char* lib)
1237 this->AddLinkLibrary(lib,cmTarget::GENERAL);
1240 void cmMakefile::AddLinkDirectory(const char* dir)
1242 // Don't add a link directory that is already present. Yes, this
1243 // linear search results in n^2 behavior, but n won't be getting
1244 // much bigger than 20. We cannot use a set because of order
1245 // dependency of the link search path.
1247 if(!dir)
1249 return;
1251 // remove trailing slashes
1252 if(dir[strlen(dir)-1] == '/')
1254 std::string newdir = dir;
1255 newdir = newdir.substr(0, newdir.size()-1);
1256 if(std::find(this->LinkDirectories.begin(),
1257 this->LinkDirectories.end(),
1258 newdir.c_str()) == this->LinkDirectories.end())
1260 this->LinkDirectories.push_back(newdir);
1263 else
1265 if(std::find(this->LinkDirectories.begin(),
1266 this->LinkDirectories.end(), dir)
1267 == this->LinkDirectories.end())
1269 this->LinkDirectories.push_back(dir);
1274 void cmMakefile::InitializeFromParent()
1276 cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
1278 // copy the definitions
1279 this->DefinitionStack.front() = parent->DefinitionStack.back();
1281 // copy include paths
1282 this->IncludeDirectories = parent->IncludeDirectories;
1283 this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
1285 // define flags
1286 this->DefineFlags = parent->DefineFlags;
1288 // compile definitions property and per-config versions
1290 this->SetProperty("COMPILE_DEFINITIONS",
1291 parent->GetProperty("COMPILE_DEFINITIONS"));
1292 std::vector<std::string> configs;
1293 if(const char* configTypes =
1294 this->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
1296 cmSystemTools::ExpandListArgument(configTypes, configs);
1298 else if(const char* buildType =
1299 this->GetDefinition("CMAKE_BUILD_TYPE"))
1301 configs.push_back(buildType);
1303 for(std::vector<std::string>::const_iterator ci = configs.begin();
1304 ci != configs.end(); ++ci)
1306 std::string defPropName = "COMPILE_DEFINITIONS_";
1307 defPropName += cmSystemTools::UpperCase(*ci);
1308 this->SetProperty(defPropName.c_str(),
1309 parent->GetProperty(defPropName.c_str()));
1313 // link libraries
1314 this->LinkLibraries = parent->LinkLibraries;
1316 // link directories
1317 this->LinkDirectories = parent->LinkDirectories;
1319 // the initial project name
1320 this->ProjectName = parent->ProjectName;
1322 // Copy include regular expressions.
1323 this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
1324 this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
1326 // Imported targets.
1327 this->ImportedTargets = parent->ImportedTargets;
1330 void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
1332 // copy our variables from the child makefile
1333 lg2->GetMakefile()->InitializeFromParent();
1334 lg2->GetMakefile()->MakeStartDirectoriesCurrent();
1335 if (this->GetCMakeInstance()->GetDebugOutput())
1337 std::string msg=" Entering ";
1338 msg += lg2->GetMakefile()->GetCurrentDirectory();
1339 cmSystemTools::Message(msg.c_str());
1341 // finally configure the subdir
1342 lg2->Configure();
1343 if (this->GetCMakeInstance()->GetDebugOutput())
1345 std::string msg=" Returning to ";
1346 msg += this->GetCurrentDirectory();
1347 cmSystemTools::Message(msg.c_str());
1351 void cmMakefile::AddSubDirectory(const char* sub,
1352 bool excludeFromAll, bool preorder)
1354 // the source path must be made full if it isn't already
1355 std::string srcPath = sub;
1356 if (!cmSystemTools::FileIsFullPath(srcPath.c_str()))
1358 srcPath = this->GetCurrentDirectory();
1359 srcPath += "/";
1360 srcPath += sub;
1363 // binary path must be made full if it isn't already
1364 std::string binPath = sub;
1365 if (!cmSystemTools::FileIsFullPath(binPath.c_str()))
1367 binPath = this->GetCurrentOutputDirectory();
1368 binPath += "/";
1369 binPath += sub;
1373 this->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
1374 excludeFromAll, preorder, false);
1378 void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
1379 bool excludeFromAll, bool preorder,
1380 bool immediate)
1382 std::vector<cmLocalGenerator *>& children =
1383 this->LocalGenerator->GetChildren();
1384 // has this directory already been added? If so error
1385 unsigned int i;
1386 for (i = 0; i < children.size(); ++i)
1388 if (srcPath == children[i]->GetMakefile()->GetStartDirectory())
1390 cmSystemTools::Error
1391 ("Attempt to add subdirectory multiple times for directory.\n",
1392 srcPath);
1393 return;
1397 // create a new local generator and set its parent
1398 cmLocalGenerator *lg2 =
1399 this->LocalGenerator->GetGlobalGenerator()->CreateLocalGenerator();
1400 lg2->SetParent(this->LocalGenerator);
1401 this->LocalGenerator->GetGlobalGenerator()->AddLocalGenerator(lg2);
1403 // set the subdirs start dirs
1404 lg2->GetMakefile()->SetStartDirectory(srcPath);
1405 lg2->GetMakefile()->SetStartOutputDirectory(binPath);
1406 if(excludeFromAll)
1408 lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1410 lg2->GetMakefile()->SetPreOrder(preorder);
1412 if (immediate)
1414 this->ConfigureSubDirectory(lg2);
1418 void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
1420 // if there is a newline then break it into multiple arguments
1421 if (!inc)
1423 return;
1426 // Don't add an include directory that is already present. Yes,
1427 // this linear search results in n^2 behavior, but n won't be
1428 // getting much bigger than 20. We cannot use a set because of
1429 // order dependency of the include path.
1430 std::vector<std::string>::iterator i =
1431 std::find(this->IncludeDirectories.begin(),
1432 this->IncludeDirectories.end(), inc);
1433 if(i == this->IncludeDirectories.end())
1435 if (before)
1437 // WARNING: this *is* expensive (linear time) since it's a vector
1438 this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
1440 else
1442 this->IncludeDirectories.push_back(inc);
1445 else
1447 if(before)
1449 // if this before and already in the path then remove it
1450 this->IncludeDirectories.erase(i);
1451 // WARNING: this *is* expensive (linear time) since it's a vector
1452 this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
1457 //----------------------------------------------------------------------------
1458 void cmMakefile::AddSystemIncludeDirectory(const char* dir)
1460 this->SystemIncludeDirectories.insert(dir);
1463 //----------------------------------------------------------------------------
1464 bool cmMakefile::IsSystemIncludeDirectory(const char* dir)
1466 return (this->SystemIncludeDirectories.find(dir) !=
1467 this->SystemIncludeDirectories.end());
1470 void cmMakefile::AddDefinition(const char* name, const char* value)
1472 if (!value )
1474 return;
1477 #ifdef CMAKE_STRICT
1478 if (this->GetCMakeInstance())
1480 this->GetCMakeInstance()->
1481 RecordPropertyAccess(name,cmProperty::VARIABLE);
1483 #endif
1485 this->TemporaryDefinitionKey = name;
1486 this->DefinitionStack.back()[this->TemporaryDefinitionKey] = value;
1488 #ifdef CMAKE_BUILD_WITH_CMAKE
1489 cmVariableWatch* vv = this->GetVariableWatch();
1490 if ( vv )
1492 vv->VariableAccessed(this->TemporaryDefinitionKey,
1493 cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1494 value,
1495 this);
1497 #endif
1501 void cmMakefile::AddCacheDefinition(const char* name, const char* value,
1502 const char* doc,
1503 cmCacheManager::CacheEntryType type)
1505 const char* val = value;
1506 cmCacheManager::CacheIterator it =
1507 this->GetCacheManager()->GetCacheIterator(name);
1508 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1509 it.Initialized())
1511 val = it.GetValue();
1512 if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH )
1514 std::vector<std::string>::size_type cc;
1515 std::vector<std::string> files;
1516 std::string nvalue = "";
1517 cmSystemTools::ExpandListArgument(val, files);
1518 for ( cc = 0; cc < files.size(); cc ++ )
1520 files[cc] = cmSystemTools::CollapseFullPath(files[cc].c_str());
1521 if ( cc > 0 )
1523 nvalue += ";";
1525 nvalue += files[cc];
1528 this->GetCacheManager()->AddCacheEntry(name, nvalue.c_str(), doc, type);
1529 val = it.GetValue();
1533 this->GetCacheManager()->AddCacheEntry(name, val, doc, type);
1534 // if there was a definition then remove it
1535 this->DefinitionStack.back().erase( DefinitionMap::key_type(name));
1539 void cmMakefile::AddDefinition(const char* name, bool value)
1541 if(value)
1543 this->DefinitionStack.back()
1544 .erase( DefinitionMap::key_type(name));
1545 this->DefinitionStack.back()
1546 .insert(DefinitionMap::value_type(name, "ON"));
1548 else
1550 this->DefinitionStack.back()
1551 .erase( DefinitionMap::key_type(name));
1552 this->DefinitionStack.back()
1553 .insert(DefinitionMap::value_type(name, "OFF"));
1555 #ifdef CMAKE_BUILD_WITH_CMAKE
1556 cmVariableWatch* vv = this->GetVariableWatch();
1557 if ( vv )
1559 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1560 value?"ON":"OFF", this);
1562 #endif
1566 void cmMakefile::AddCacheDefinition(const char* name,
1567 bool value,
1568 const char* doc)
1570 bool val = value;
1571 cmCacheManager::CacheIterator it =
1572 this->GetCacheManager()->GetCacheIterator(name);
1573 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1574 it.Initialized())
1576 val = it.GetValueAsBool();
1578 this->GetCacheManager()->AddCacheEntry(name, val, doc);
1579 this->AddDefinition(name, val);
1582 void cmMakefile::RemoveDefinition(const char* name)
1584 this->DefinitionStack.back().erase(DefinitionMap::key_type(name));
1585 #ifdef CMAKE_BUILD_WITH_CMAKE
1586 cmVariableWatch* vv = this->GetVariableWatch();
1587 if ( vv )
1589 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
1590 0, this);
1592 #endif
1595 void cmMakefile::SetProjectName(const char* p)
1597 this->ProjectName = p;
1601 void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
1603 // for these targets do not add anything
1604 switch(target.GetType())
1606 case cmTarget::UTILITY:
1607 case cmTarget::GLOBAL_TARGET:
1608 return;
1609 default:;
1611 std::vector<std::string>::iterator j;
1612 for(j = this->LinkDirectories.begin();
1613 j != this->LinkDirectories.end(); ++j)
1615 target.AddLinkDirectory(j->c_str());
1617 target.MergeLinkLibraries( *this, name, this->LinkLibraries );
1621 void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
1622 const std::vector<std::string> &srcs,
1623 bool excludeFromAll)
1625 // wrong type ? default to STATIC
1626 if ( (type != cmTarget::STATIC_LIBRARY)
1627 && (type != cmTarget::SHARED_LIBRARY)
1628 && (type != cmTarget::MODULE_LIBRARY))
1630 type = cmTarget::STATIC_LIBRARY;
1633 cmTarget* target = this->AddNewTarget(type, lname);
1634 // Clear its dependencies. Otherwise, dependencies might persist
1635 // over changes in CMakeLists.txt, making the information stale and
1636 // hence useless.
1637 target->ClearDependencyInformation( *this, lname );
1638 if(excludeFromAll)
1640 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1642 target->AddSources(srcs);
1643 this->AddGlobalLinkInformation(lname, *target);
1646 cmTarget* cmMakefile::AddExecutable(const char *exeName,
1647 const std::vector<std::string> &srcs,
1648 bool excludeFromAll)
1650 cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName);
1651 if(excludeFromAll)
1653 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1655 target->AddSources(srcs);
1656 this->AddGlobalLinkInformation(exeName, *target);
1657 return target;
1660 //----------------------------------------------------------------------------
1661 cmTarget*
1662 cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name)
1664 cmTargets::iterator it =
1665 this->Targets.insert(cmTargets::value_type(name, cmTarget())).first;
1666 cmTarget& target = it->second;
1667 target.SetType(type, name);
1668 target.SetMakefile(this);
1669 this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it);
1670 return &it->second;
1673 cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
1675 std::string name = cname;
1676 std::string out;
1678 // look through all the source files that have custom commands
1679 // and see if the custom command has the passed source file as an output
1680 // keep in mind the possible .rule extension that may be tacked on
1681 for(std::vector<cmSourceFile*>::const_iterator i =
1682 this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
1684 // does this source file have a custom command?
1685 if ((*i)->GetCustomCommand())
1687 // is the output of the custom command match the source files name
1688 const std::vector<std::string>& outputs =
1689 (*i)->GetCustomCommand()->GetOutputs();
1690 for(std::vector<std::string>::const_iterator o = outputs.begin();
1691 o != outputs.end(); ++o)
1693 out = *o;
1694 std::string::size_type pos = out.rfind(name);
1695 // If the output matches exactly
1696 if (pos != out.npos &&
1697 pos == out.size() - name.size() &&
1698 (pos ==0 || out[pos-1] == '/'))
1700 return *i;
1706 // otherwise return NULL
1707 return 0;
1710 #if defined(CMAKE_BUILD_WITH_CMAKE)
1711 cmSourceGroup* cmMakefile::GetSourceGroup(const std::vector<std::string>&name)
1713 cmSourceGroup* sg = 0;
1715 // first look for source group starting with the same as the one we wants
1716 for (std::vector<cmSourceGroup>::iterator sgIt = this->SourceGroups.begin();
1717 sgIt != this->SourceGroups.end(); ++sgIt)
1720 std::string sgName = sgIt->GetName();
1721 if(sgName == name[0])
1723 sg = &(*sgIt);
1724 break;
1728 if(sg != 0)
1730 // iterate through its children to find match source group
1731 for(unsigned int i=1; i<name.size(); ++i)
1733 sg = sg->lookupChild(name[i].c_str());
1734 if(sg == 0)
1736 break;
1740 return sg;
1743 void cmMakefile::AddSourceGroup(const char* name,
1744 const char* regex)
1746 if (name)
1748 std::vector<std::string> nameVector;
1749 nameVector.push_back(name);
1750 AddSourceGroup(nameVector, regex);
1754 void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
1755 const char* regex)
1757 cmSourceGroup* sg = 0;
1758 std::vector<std::string> currentName;
1759 int i = 0;
1760 const int lastElement = static_cast<int>(name.size()-1);
1761 for(i=lastElement; i>=0; --i)
1763 currentName.assign(name.begin(), name.begin()+i+1);
1764 sg = this->GetSourceGroup(currentName);
1765 if(sg != 0)
1767 break;
1771 // i now contains the index of the last found component
1772 if(i==lastElement)
1774 // group already exists, replace its regular expression
1775 if ( regex )
1777 // We only want to set the regular expression. If there are already
1778 // source files in the group, we don't want to remove them.
1779 sg->SetGroupRegex(regex);
1781 return;
1783 else if(i==-1)
1785 // group does not exists nor belong to any existing group
1786 // add its first component
1787 this->SourceGroups.push_back(cmSourceGroup(name[0].c_str(), regex));
1788 sg = this->GetSourceGroup(currentName);
1789 i = 0; // last component found
1792 // build the whole source group path
1793 for(++i; i<=lastElement; ++i)
1795 sg->AddChild(cmSourceGroup(name[i].c_str(), 0));
1796 sg = sg->lookupChild(name[i].c_str());
1799 sg->SetGroupRegex(regex);
1802 #endif
1804 void cmMakefile::AddExtraDirectory(const char* dir)
1806 this->AuxSourceDirectories.push_back(dir);
1810 // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
1811 // include and library directories.
1813 void cmMakefile::ExpandVariables()
1815 // Now expand variables in the include and link strings
1816 for(std::vector<std::string>::iterator d = this->IncludeDirectories.begin();
1817 d != this->IncludeDirectories.end(); ++d)
1819 this->ExpandVariablesInString(*d, true, true);
1821 for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
1822 d != this->LinkDirectories.end(); ++d)
1824 this->ExpandVariablesInString(*d, true, true);
1826 for(cmTarget::LinkLibraryVectorType::iterator l =
1827 this->LinkLibraries.begin();
1828 l != this->LinkLibraries.end(); ++l)
1830 this->ExpandVariablesInString(l->first, true, true);
1834 bool cmMakefile::IsOn(const char* name) const
1836 const char* value = this->GetDefinition(name);
1837 return cmSystemTools::IsOn(value);
1840 bool cmMakefile::IsSet(const char* name) const
1842 const char* value = this->GetDefinition(name);
1843 if ( !value )
1845 return false;
1848 if ( ! *value )
1850 return false;
1853 if ( cmSystemTools::IsNOTFOUND(value) )
1855 return false;
1858 return true;
1861 bool cmMakefile::CanIWriteThisFile(const char* fileName)
1863 if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
1865 return true;
1867 // If we are doing an in-source build, than the test will always fail
1868 if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
1869 this->GetHomeOutputDirectory()) )
1871 if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
1873 return false;
1875 return true;
1878 // Check if this is subdirectory of the source tree but not a
1879 // subdirectory of a build tree
1880 if ( cmSystemTools::IsSubDirectory(fileName,
1881 this->GetHomeDirectory()) &&
1882 !cmSystemTools::IsSubDirectory(fileName,
1883 this->GetHomeOutputDirectory()) )
1885 return false;
1887 return true;
1890 const char* cmMakefile::GetRequiredDefinition(const char* name) const
1892 const char* ret = this->GetDefinition(name);
1893 if(!ret)
1895 cmSystemTools::Error("Error required internal CMake variable not "
1896 "set, cmake may be not be built correctly.\n",
1897 "Missing variable is:\n",
1898 name);
1899 return "";
1901 return ret;
1904 bool cmMakefile::IsDefinitionSet(const char* name) const
1906 const char* def = 0;
1907 DefinitionMap::const_iterator pos =
1908 this->DefinitionStack.back().find(name);
1909 if(pos != this->DefinitionStack.back().end())
1911 def = (*pos).second.c_str();
1913 else
1915 def = this->GetCacheManager()->GetCacheValue(name);
1917 #ifdef CMAKE_BUILD_WITH_CMAKE
1918 if(cmVariableWatch* vv = this->GetVariableWatch())
1920 if(!def)
1922 vv->VariableAccessed
1923 (name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS,
1924 def, this);
1927 #endif
1928 return def?true:false;
1931 const char* cmMakefile::GetDefinition(const char* name) const
1933 #ifdef CMAKE_STRICT
1934 if (this->GetCMakeInstance())
1936 this->GetCMakeInstance()->
1937 RecordPropertyAccess(name,cmProperty::VARIABLE);
1939 #endif
1940 const char* def = 0;
1941 DefinitionMap::const_iterator pos =
1942 this->DefinitionStack.back().find(name);
1943 if(pos != this->DefinitionStack.back().end())
1945 def = (*pos).second.c_str();
1947 else
1949 def = this->GetCacheManager()->GetCacheValue(name);
1951 #ifdef CMAKE_BUILD_WITH_CMAKE
1952 cmVariableWatch* vv = this->GetVariableWatch();
1953 if ( vv )
1955 if ( def )
1957 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
1958 def, this);
1960 else
1962 // are unknown access allowed
1963 DefinitionMap::const_iterator pos2 =
1964 this->DefinitionStack.back()
1965 .find("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
1966 if (pos2 != this->DefinitionStack.back().end() &&
1967 cmSystemTools::IsOn((*pos2).second.c_str()))
1969 vv->VariableAccessed(name,
1970 cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, def, this);
1972 else
1974 vv->VariableAccessed(name,
1975 cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
1979 #endif
1980 return def;
1983 const char* cmMakefile::GetSafeDefinition(const char* def) const
1985 const char* ret = this->GetDefinition(def);
1986 if(!ret)
1988 return "";
1990 return ret;
1993 std::vector<std::string> cmMakefile
1994 ::GetDefinitions(int cacheonly /* = 0 */) const
1996 std::map<cmStdString, int> definitions;
1997 if ( !cacheonly )
1999 DefinitionMap::const_iterator it;
2000 for ( it = this->DefinitionStack.back().begin();
2001 it != this->DefinitionStack.back().end(); it ++ )
2003 definitions[it->first] = 1;
2006 cmCacheManager::CacheIterator cit =
2007 this->GetCacheManager()->GetCacheIterator();
2008 for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
2010 definitions[cit.GetName()] = 1;
2013 std::vector<std::string> res;
2015 std::map<cmStdString, int>::iterator fit;
2016 for ( fit = definitions.begin(); fit != definitions.end(); fit ++ )
2018 res.push_back(fit->first);
2020 return res;
2024 const char *cmMakefile::ExpandVariablesInString(std::string& source)
2026 return this->ExpandVariablesInString(source, false, false);
2029 const char *cmMakefile::ExpandVariablesInString(std::string& source,
2030 bool escapeQuotes,
2031 bool noEscapes,
2032 bool atOnly,
2033 const char* filename,
2034 long line,
2035 bool removeEmpty,
2036 bool replaceAt)
2038 if ( source.empty() || source.find_first_of("$@\\") == source.npos)
2040 return source.c_str();
2043 // Special-case the @ONLY mode.
2044 if(atOnly)
2046 if(!noEscapes || !removeEmpty || !replaceAt)
2048 // This case should never be called. At-only is for
2049 // configure-file/string which always does no escapes.
2050 this->IssueMessage(cmake::INTERNAL_ERROR,
2051 "ExpandVariablesInString @ONLY called "
2052 "on something with escapes.");
2055 // Store an original copy of the input.
2056 std::string input = source;
2058 // Start with empty output.
2059 source = "";
2061 // Look for one @VAR@ at a time.
2062 const char* in = input.c_str();
2063 while(this->cmAtVarRegex.find(in))
2065 // Get the range of the string to replace.
2066 const char* first = in + this->cmAtVarRegex.start();
2067 const char* last = in + this->cmAtVarRegex.end();
2069 // Store the unchanged part of the string now.
2070 source.append(in, first-in);
2072 // Lookup the definition of VAR.
2073 std::string var(first+1, last-first-2);
2074 if(const char* val = this->GetDefinition(var.c_str()))
2076 // Store the value in the output escaping as requested.
2077 if(escapeQuotes)
2079 source.append(cmSystemTools::EscapeQuotes(val));
2081 else
2083 source.append(val);
2087 // Continue looking for @VAR@ further along the string.
2088 in = last;
2091 // Append the rest of the unchanged part of the string.
2092 source.append(in);
2094 return source.c_str();
2097 // This method replaces ${VAR} and @VAR@ where VAR is looked up
2098 // with GetDefinition(), if not found in the map, nothing is expanded.
2099 // It also supports the $ENV{VAR} syntax where VAR is looked up in
2100 // the current environment variables.
2102 cmCommandArgumentParserHelper parser;
2103 parser.SetMakefile(this);
2104 parser.SetLineFile(line, filename);
2105 parser.SetEscapeQuotes(escapeQuotes);
2106 parser.SetNoEscapeMode(noEscapes);
2107 parser.SetReplaceAtSyntax(replaceAt);
2108 parser.SetRemoveEmpty(removeEmpty);
2109 int res = parser.ParseString(source.c_str(), 0);
2110 if ( res )
2112 source = parser.GetResult();
2114 else
2116 cmOStringStream error;
2117 error << "Syntax error in cmake code at\n"
2118 << (filename?filename:"(no filename given)")
2119 << ":" << line << ":\n"
2120 << parser.GetError() << ", when parsing string \""
2121 << source.c_str() << "\"";
2122 if(this->NeedBackwardsCompatibility(2,0))
2124 cmSystemTools::Error(error.str().c_str());
2125 cmSystemTools::SetFatalErrorOccured();
2126 return source.c_str();
2128 else
2130 cmSystemTools::Message(error.str().c_str());
2133 return source.c_str();
2136 void cmMakefile::RemoveVariablesInString(std::string& source,
2137 bool atOnly) const
2139 if(!atOnly)
2141 cmsys::RegularExpression var("(\\${[A-Za-z_0-9]*})");
2142 while (var.find(source))
2144 source.erase(var.start(),var.end() - var.start());
2148 if(!atOnly)
2150 cmsys::RegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
2151 while (varb.find(source))
2153 source.erase(varb.start(),varb.end() - varb.start());
2156 cmsys::RegularExpression var2("(@[A-Za-z_0-9]*@)");
2157 while (var2.find(source))
2159 source.erase(var2.start(),var2.end() - var2.start());
2164 * Add the default definitions to the makefile. These values must not
2165 * be dependent on anything that isn't known when this cmMakefile instance
2166 * is constructed.
2168 void cmMakefile::AddDefaultDefinitions()
2170 /* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set.
2171 With CMake must separate between target and host platform. In most cases
2172 the tests for WIN32, UNIX and APPLE will be for the target system, so an
2173 additional set of variables for the host system is required ->
2174 CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE.
2175 WIN32, UNIX and APPLE are now set in the platform files in
2176 Modules/Platforms/.
2177 To keep cmake scripts (-P) and custom language and compiler modules
2178 working, these variables are still also set here in this place, but they
2179 will be reset in CMakeSystemSpecificInformation.cmake before the platform
2180 files are executed. */
2181 #if defined(_WIN32) || defined(__CYGWIN__)
2182 this->AddDefinition("WIN32", "1");
2183 this->AddDefinition("CMAKE_HOST_WIN32", "1");
2184 #else
2185 this->AddDefinition("UNIX", "1");
2186 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2187 #endif
2188 // Cygwin is more like unix so enable the unix commands
2189 #if defined(__CYGWIN__)
2190 this->AddDefinition("UNIX", "1");
2191 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2192 #endif
2193 #if defined(__APPLE__)
2194 this->AddDefinition("APPLE", "1");
2195 this->AddDefinition("CMAKE_HOST_APPLE", "1");
2196 #endif
2198 char temp[1024];
2199 sprintf(temp, "%d", cmVersion::GetMinorVersion());
2200 this->AddDefinition("CMAKE_MINOR_VERSION", temp);
2201 sprintf(temp, "%d", cmVersion::GetMajorVersion());
2202 this->AddDefinition("CMAKE_MAJOR_VERSION", temp);
2203 sprintf(temp, "%d", cmVersion::GetPatchVersion());
2204 this->AddDefinition("CMAKE_PATCH_VERSION", temp);
2206 this->AddDefinition("CMAKE_FILES_DIRECTORY",
2207 cmake::GetCMakeFilesDirectory());
2210 #if defined(CMAKE_BUILD_WITH_CMAKE)
2212 * Find a source group whose regular expression matches the filename
2213 * part of the given source name. Search backward through the list of
2214 * source groups, and take the first matching group found. This way
2215 * non-inherited SOURCE_GROUP commands will have precedence over
2216 * inherited ones.
2218 cmSourceGroup&
2219 cmMakefile::FindSourceGroup(const char* source,
2220 std::vector<cmSourceGroup> &groups)
2222 // First search for a group that lists the file explicitly.
2223 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2224 sg != groups.rend(); ++sg)
2226 cmSourceGroup *result = sg->MatchChildrenFiles(source);
2227 if(result)
2229 return *result;
2233 // Now search for a group whose regex matches the file.
2234 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2235 sg != groups.rend(); ++sg)
2237 cmSourceGroup *result = sg->MatchChildrenRegex(source);
2238 if(result)
2240 return *result;
2245 // Shouldn't get here, but just in case, return the default group.
2246 return groups.front();
2248 #endif
2250 bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
2251 cmExecutionStatus &status)
2253 // if there are no blockers get out of here
2254 if (this->FunctionBlockers.begin() == this->FunctionBlockers.end())
2256 return false;
2259 // loop over all function blockers to see if any block this command
2260 // evaluate in reverse, this is critical for balanced IF statements etc
2261 std::list<cmFunctionBlocker *>::reverse_iterator pos;
2262 for (pos = this->FunctionBlockers.rbegin();
2263 pos != this->FunctionBlockers.rend(); ++pos)
2265 if((*pos)->IsFunctionBlocked(lff, *this, status))
2267 return true;
2271 return false;
2274 void cmMakefile::ExpandArguments(
2275 std::vector<cmListFileArgument> const& inArgs,
2276 std::vector<std::string>& outArgs)
2278 std::vector<cmListFileArgument>::const_iterator i;
2279 std::string value;
2280 outArgs.reserve(inArgs.size());
2281 for(i = inArgs.begin(); i != inArgs.end(); ++i)
2283 // Expand the variables in the argument.
2284 value = i->Value;
2285 this->ExpandVariablesInString(value, false, false, false,
2286 i->FilePath, i->Line,
2287 false, true);
2289 // If the argument is quoted, it should be one argument.
2290 // Otherwise, it may be a list of arguments.
2291 if(i->Quoted)
2293 outArgs.push_back(value);
2295 else
2297 cmSystemTools::ExpandListArgument(value, outArgs);
2302 void cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
2304 // loop over all function blockers to see if any block this command
2305 std::list<cmFunctionBlocker *>::reverse_iterator pos;
2306 for (pos = this->FunctionBlockers.rbegin();
2307 pos != this->FunctionBlockers.rend(); ++pos)
2309 if ((*pos)->ShouldRemove(lff, *this))
2311 cmFunctionBlocker* b = *pos;
2312 this->FunctionBlockers.remove(b);
2313 delete b;
2314 break;
2318 return;
2321 void cmMakefile::SetHomeDirectory(const char* dir)
2323 this->cmHomeDirectory = dir;
2324 cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
2325 this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
2326 if ( !this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR") )
2328 this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", this->GetHomeDirectory());
2332 void cmMakefile::SetHomeOutputDirectory(const char* lib)
2334 this->HomeOutputDirectory = lib;
2335 cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
2336 this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
2337 if ( !this->GetDefinition("CMAKE_CURRENT_BINARY_DIR") )
2339 this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
2340 this->GetHomeOutputDirectory());
2346 * Register the given cmData instance with its own name.
2348 void cmMakefile::RegisterData(cmData* data)
2350 std::string name = data->GetName();
2351 DataMapType::const_iterator d = this->DataMap.find(name);
2352 if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
2354 delete d->second;
2356 this->DataMap[name] = data;
2361 * Register the given cmData instance with the given name. This can be used
2362 * to register a NULL pointer.
2364 void cmMakefile::RegisterData(const char* name, cmData* data)
2366 DataMapType::const_iterator d = this->DataMap.find(name);
2367 if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
2369 delete d->second;
2371 this->DataMap[name] = data;
2376 * Lookup a cmData instance previously registered with the given name. If
2377 * the instance cannot be found, return NULL.
2379 cmData* cmMakefile::LookupData(const char* name) const
2381 DataMapType::const_iterator d = this->DataMap.find(name);
2382 if(d != this->DataMap.end())
2384 return d->second;
2386 else
2388 return 0;
2392 //----------------------------------------------------------------------------
2393 cmSourceFile* cmMakefile::GetSource(const char* sourceName)
2395 cmSourceFileLocation sfl(this, sourceName);
2396 for(std::vector<cmSourceFile*>::const_iterator
2397 sfi = this->SourceFiles.begin();
2398 sfi != this->SourceFiles.end(); ++sfi)
2400 cmSourceFile* sf = *sfi;
2401 if(sf->Matches(sfl))
2403 return sf;
2406 return 0;
2409 //----------------------------------------------------------------------------
2410 cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
2411 bool generated)
2413 if(cmSourceFile* esf = this->GetSource(sourceName))
2415 return esf;
2417 else
2419 cmSourceFile* sf = new cmSourceFile(this, sourceName);
2420 if(generated)
2422 sf->SetProperty("GENERATED", "1");
2424 this->SourceFiles.push_back(sf);
2425 return sf;
2429 void cmMakefile::EnableLanguage(std::vector<std::string> const & lang,
2430 bool optional)
2432 this->AddDefinition("CMAKE_CFG_INTDIR",
2433 this->LocalGenerator->GetGlobalGenerator()->GetCMakeCFGInitDirectory());
2434 this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this,
2435 optional);
2438 void cmMakefile::ExpandSourceListArguments(
2439 std::vector<std::string> const& arguments,
2440 std::vector<std::string>& newargs, unsigned int /* start */)
2442 // now expand the args
2443 unsigned int i;
2444 for(i = 0; i < arguments.size(); ++i)
2446 // List expansion will have been done already.
2447 newargs.push_back(arguments[i]);
2451 int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
2452 const char *projectName, const char *targetName,
2453 const std::vector<std::string> *cmakeArgs,
2454 std::string *output)
2456 // does the binary directory exist ? If not create it...
2457 if (!cmSystemTools::FileIsDirectory(bindir))
2459 cmSystemTools::MakeDirectory(bindir);
2462 // change to the tests directory and run cmake
2463 // use the cmake object instead of calling cmake
2464 std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
2465 cmSystemTools::ChangeDirectory(bindir);
2467 // make sure the same generator is used
2468 // use this program as the cmake to be run, it should not
2469 // be run that way but the cmake object requires a vailid path
2470 std::string cmakeCommand = this->GetDefinition("CMAKE_COMMAND");
2471 cmake cm;
2472 cm.SetIsInTryCompile(true);
2473 cmGlobalGenerator *gg = cm.CreateGlobalGenerator
2474 (this->LocalGenerator->GetGlobalGenerator()->GetName());
2475 if (!gg)
2477 cmSystemTools::Error(
2478 "Internal CMake error, TryCompile bad GlobalGenerator");
2479 // return to the original directory
2480 cmSystemTools::ChangeDirectory(cwd.c_str());
2481 return 1;
2483 cm.SetGlobalGenerator(gg);
2485 // do a configure
2486 cm.SetHomeDirectory(srcdir);
2487 cm.SetHomeOutputDirectory(bindir);
2488 cm.SetStartDirectory(srcdir);
2489 cm.SetStartOutputDirectory(bindir);
2490 cm.SetCMakeCommand(cmakeCommand.c_str());
2491 cm.LoadCache();
2492 // if cmake args were provided then pass them in
2493 if (cmakeArgs)
2495 cm.SetCacheArgs(*cmakeArgs);
2497 // to save time we pass the EnableLanguage info directly
2498 gg->EnableLanguagesFromGenerator
2499 (this->LocalGenerator->GetGlobalGenerator());
2500 if(this->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"))
2502 cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
2503 "TRUE", "", cmCacheManager::INTERNAL);
2505 else
2507 cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
2508 "FALSE", "", cmCacheManager::INTERNAL);
2510 if (cm.Configure() != 0)
2512 cmSystemTools::Error(
2513 "Internal CMake error, TryCompile configure of cmake failed");
2514 // return to the original directory
2515 cmSystemTools::ChangeDirectory(cwd.c_str());
2516 return 1;
2519 if (cm.Generate() != 0)
2521 cmSystemTools::Error(
2522 "Internal CMake error, TryCompile generation of cmake failed");
2523 // return to the original directory
2524 cmSystemTools::ChangeDirectory(cwd.c_str());
2525 return 1;
2528 // finally call the generator to actually build the resulting project
2529 int ret =
2530 this->LocalGenerator->GetGlobalGenerator()->TryCompile(srcdir,bindir,
2531 projectName,
2532 targetName,
2533 output,
2534 this);
2536 cmSystemTools::ChangeDirectory(cwd.c_str());
2537 return ret;
2540 cmake *cmMakefile::GetCMakeInstance() const
2542 if ( this->LocalGenerator && this->LocalGenerator->GetGlobalGenerator() )
2544 return this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
2546 return 0;
2549 #ifdef CMAKE_BUILD_WITH_CMAKE
2550 cmVariableWatch *cmMakefile::GetVariableWatch() const
2552 if ( this->GetCMakeInstance() &&
2553 this->GetCMakeInstance()->GetVariableWatch() )
2555 return this->GetCMakeInstance()->GetVariableWatch();
2557 return 0;
2559 #endif
2561 void cmMakefile::AddMacro(const char* name, const char* signature)
2563 if ( !name || !signature )
2565 return;
2567 this->MacrosMap[name] = signature;
2570 void cmMakefile::GetListOfMacros(std::string& macros)
2572 StringStringMap::iterator it;
2573 macros = "";
2574 int cc = 0;
2575 for ( it = this->MacrosMap.begin(); it != this->MacrosMap.end(); ++it )
2577 if ( cc > 0 )
2579 macros += ";";
2581 macros += it->first;
2582 cc ++;
2586 cmCacheManager *cmMakefile::GetCacheManager() const
2588 return this->GetCMakeInstance()->GetCacheManager();
2591 void cmMakefile::DisplayStatus(const char* message, float s)
2593 this->GetLocalGenerator()->GetGlobalGenerator()
2594 ->GetCMakeInstance()->UpdateProgress(message, s);
2597 std::string cmMakefile::GetModulesFile(const char* filename)
2599 std::vector<std::string> modulePath;
2600 const char* def = this->GetDefinition("CMAKE_MODULE_PATH");
2601 if(def)
2603 cmSystemTools::ExpandListArgument(def, modulePath);
2606 // Also search in the standard modules location.
2607 def = this->GetDefinition("CMAKE_ROOT");
2608 if(def)
2610 std::string rootModules = def;
2611 rootModules += "/Modules";
2612 modulePath.push_back(rootModules);
2614 //std::string Look through the possible module directories.
2615 for(std::vector<std::string>::iterator i = modulePath.begin();
2616 i != modulePath.end(); ++i)
2618 std::string itempl = *i;
2619 cmSystemTools::ConvertToUnixSlashes(itempl);
2620 itempl += "/";
2621 itempl += filename;
2622 if(cmSystemTools::FileExists(itempl.c_str()))
2624 return itempl;
2627 return "";
2630 void cmMakefile::ConfigureString(const std::string& input,
2631 std::string& output, bool atOnly,
2632 bool escapeQuotes)
2634 // Split input to handle one line at a time.
2635 std::string::const_iterator lineStart = input.begin();
2636 while(lineStart != input.end())
2638 // Find the end of this line.
2639 std::string::const_iterator lineEnd = lineStart;
2640 while(lineEnd != input.end() && *lineEnd != '\n')
2642 ++lineEnd;
2645 // Copy the line.
2646 std::string line(lineStart, lineEnd);
2648 // Skip the newline character.
2649 bool haveNewline = (lineEnd != input.end());
2650 if(haveNewline)
2652 ++lineEnd;
2655 // Replace #cmakedefine instances.
2656 if(this->cmDefineRegex.find(line))
2658 const char* def =
2659 this->GetDefinition(this->cmDefineRegex.match(1).c_str());
2660 if(!cmSystemTools::IsOff(def))
2662 cmSystemTools::ReplaceString(line, "#cmakedefine", "#define");
2663 output += line;
2665 else
2667 output += "/* #undef ";
2668 output += this->cmDefineRegex.match(1);
2669 output += " */";
2672 else if(this->cmDefine01Regex.find(line))
2674 const char* def =
2675 this->GetDefinition(this->cmDefine01Regex.match(1).c_str());
2676 cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define");
2677 output += line;
2678 if(!cmSystemTools::IsOff(def))
2680 output += " 1";
2682 else
2684 output += " 0";
2687 else
2689 output += line;
2692 if(haveNewline)
2694 output += "\n";
2697 // Move to the next line.
2698 lineStart = lineEnd;
2701 // Perform variable replacements.
2702 this->ExpandVariablesInString(output, escapeQuotes, true,
2703 atOnly, 0, -1, true);
2706 int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
2707 bool copyonly, bool atOnly, bool escapeQuotes)
2709 int res = 1;
2710 if ( !this->CanIWriteThisFile(outfile) )
2712 cmSystemTools::Error("Attempt to write file: ",
2713 outfile, " into a source directory.");
2714 return 0;
2716 if ( !cmSystemTools::FileExists(infile) )
2718 cmSystemTools::Error("File ", infile, " does not exist.");
2719 return 0;
2721 std::string soutfile = outfile;
2722 std::string sinfile = infile;
2723 this->AddCMakeDependFile(infile);
2724 cmSystemTools::ConvertToUnixSlashes(soutfile);
2725 mode_t perm = 0;
2726 cmSystemTools::GetPermissions(sinfile.c_str(), perm);
2727 std::string::size_type pos = soutfile.rfind('/');
2728 if(pos != std::string::npos)
2730 std::string path = soutfile.substr(0, pos);
2731 cmSystemTools::MakeDirectory(path.c_str());
2734 if(copyonly)
2736 if ( !cmSystemTools::CopyFileIfDifferent(sinfile.c_str(),
2737 soutfile.c_str()))
2739 return 0;
2742 else
2744 std::string tempOutputFile = soutfile;
2745 tempOutputFile += ".tmp";
2746 std::ofstream fout(tempOutputFile.c_str());
2747 if(!fout)
2749 cmSystemTools::Error(
2750 "Could not open file for write in copy operation ",
2751 tempOutputFile.c_str());
2752 cmSystemTools::ReportLastSystemError("");
2753 return 0;
2755 std::ifstream fin(sinfile.c_str());
2756 if(!fin)
2758 cmSystemTools::Error("Could not open file for read in copy operation ",
2759 sinfile.c_str());
2760 return 0;
2763 // now copy input to output and expand variables in the
2764 // input file at the same time
2765 std::string inLine;
2766 std::string outLine;
2767 while( cmSystemTools::GetLineFromStream(fin, inLine) )
2769 outLine = "";
2770 this->ConfigureString(inLine, outLine, atOnly, escapeQuotes);
2771 fout << outLine.c_str() << "\n";
2773 // close the files before attempting to copy
2774 fin.close();
2775 fout.close();
2776 if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
2777 soutfile.c_str()) )
2779 res = 0;
2781 else
2783 cmSystemTools::SetPermissions(soutfile.c_str(), perm);
2785 cmSystemTools::RemoveFile(tempOutputFile.c_str());
2787 return res;
2790 void cmMakefile::AddWrittenFile(const char* file)
2791 { this->GetCMakeInstance()->AddWrittenFile(file); }
2793 bool cmMakefile::HasWrittenFile(const char* file)
2794 { return this->GetCMakeInstance()->HasWrittenFile(file); }
2796 bool cmMakefile::CheckInfiniteLoops()
2798 std::vector<std::string>::iterator it;
2799 for ( it = this->ListFiles.begin();
2800 it != this->ListFiles.end();
2801 ++ it )
2803 if ( this->HasWrittenFile(it->c_str()) )
2805 cmOStringStream str;
2806 str << "File " << it->c_str() <<
2807 " is written by WRITE_FILE (or FILE WRITE) command and should "
2808 "not be used as input to CMake. Please use CONFIGURE_FILE to "
2809 "be safe. Refer to the note next to FILE WRITE command.";
2810 cmSystemTools::Error(str.str().c_str());
2811 return false;
2814 return true;
2817 void cmMakefile::SetProperty(const char* prop, const char* value)
2819 if (!prop)
2821 return;
2824 // handle special props
2825 std::string propname = prop;
2826 if ( propname == "INCLUDE_DIRECTORIES" )
2828 std::vector<std::string> varArgsExpanded;
2829 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2830 this->SetIncludeDirectories(varArgsExpanded);
2831 return;
2834 if ( propname == "LINK_DIRECTORIES" )
2836 std::vector<std::string> varArgsExpanded;
2837 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2838 this->SetLinkDirectories(varArgsExpanded);
2839 return;
2842 if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
2844 this->SetIncludeRegularExpression(value);
2845 return;
2848 if ( propname == "ADDITIONAL_MAKE_CLEAN_FILES" )
2850 // This property is not inherrited
2851 if ( strcmp(this->GetCurrentDirectory(),
2852 this->GetStartDirectory()) != 0 )
2854 return;
2858 this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
2861 void cmMakefile::AppendProperty(const char* prop, const char* value)
2863 if (!prop)
2865 return;
2868 // handle special props
2869 std::string propname = prop;
2870 if ( propname == "INCLUDE_DIRECTORIES" )
2872 std::vector<std::string> varArgsExpanded;
2873 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2874 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
2875 vi != varArgsExpanded.end(); ++vi)
2877 this->AddIncludeDirectory(vi->c_str());
2879 return;
2882 if ( propname == "LINK_DIRECTORIES" )
2884 std::vector<std::string> varArgsExpanded;
2885 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2886 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
2887 vi != varArgsExpanded.end(); ++vi)
2889 this->AddLinkDirectory(vi->c_str());
2891 return;
2894 this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY);
2897 const char *cmMakefile::GetPropertyOrDefinition(const char* prop)
2899 const char *ret = this->GetProperty(prop, cmProperty::DIRECTORY);
2900 if (!ret)
2902 ret = this->GetDefinition(prop);
2904 return ret;
2907 const char *cmMakefile::GetProperty(const char* prop)
2909 return this->GetProperty(prop, cmProperty::DIRECTORY);
2912 const char *cmMakefile::GetProperty(const char* prop,
2913 cmProperty::ScopeType scope)
2915 // watch for specific properties
2916 static std::string output;
2917 output = "";
2918 if (!strcmp("PARENT_DIRECTORY",prop))
2920 output = this->LocalGenerator->GetParent()
2921 ->GetMakefile()->GetStartDirectory();
2922 return output.c_str();
2924 else if (!strcmp("INCLUDE_REGULAR_EXPRESSION",prop) )
2926 output = this->GetIncludeRegularExpression();
2927 return output.c_str();
2929 else if (!strcmp("LISTFILE_STACK",prop))
2931 for (std::deque<cmStdString>::iterator i = this->ListFileStack.begin();
2932 i != this->ListFileStack.end(); ++i)
2934 if (i != this->ListFileStack.begin())
2936 output += ";";
2938 output += *i;
2940 return output.c_str();
2942 else if (!strcmp("VARIABLES",prop) || !strcmp("CACHE_VARIABLES",prop))
2944 int cacheonly = 0;
2945 if ( !strcmp("CACHE_VARIABLES",prop) )
2947 cacheonly = 1;
2949 std::vector<std::string> vars = this->GetDefinitions(cacheonly);
2950 for (unsigned int cc = 0; cc < vars.size(); cc ++ )
2952 if ( cc > 0 )
2954 output += ";";
2956 output += vars[cc];
2958 return output.c_str();
2960 else if (!strcmp("MACROS",prop))
2962 this->GetListOfMacros(output);
2963 return output.c_str();
2965 else if (!strcmp("DEFINITIONS",prop))
2967 output = this->GetDefineFlags();
2968 return output.c_str();
2970 else if (!strcmp("INCLUDE_DIRECTORIES",prop) )
2972 cmOStringStream str;
2973 for (std::vector<std::string>::const_iterator
2974 it = this->GetIncludeDirectories().begin();
2975 it != this->GetIncludeDirectories().end();
2976 ++ it )
2978 if ( it != this->GetIncludeDirectories().begin())
2980 str << ";";
2982 str << it->c_str();
2984 output = str.str();
2985 return output.c_str();
2987 else if (!strcmp("LINK_DIRECTORIES",prop))
2989 cmOStringStream str;
2990 for (std::vector<std::string>::const_iterator
2991 it = this->GetLinkDirectories().begin();
2992 it != this->GetLinkDirectories().end();
2993 ++ it )
2995 if ( it != this->GetLinkDirectories().begin())
2997 str << ";";
2999 str << it->c_str();
3001 output = str.str();
3002 return output.c_str();
3005 bool chain = false;
3006 const char *retVal =
3007 this->Properties.GetPropertyValue(prop, scope, chain);
3008 if (chain)
3010 if(this->LocalGenerator->GetParent())
3012 return this->LocalGenerator->GetParent()->GetMakefile()->
3013 GetProperty(prop, scope);
3015 return this->GetCMakeInstance()->GetProperty(prop,scope);
3018 return retVal;
3021 bool cmMakefile::GetPropertyAsBool(const char* prop)
3023 return cmSystemTools::IsOn(this->GetProperty(prop));
3027 cmTarget* cmMakefile::FindTarget(const char* name)
3029 cmTargets& tgts = this->GetTargets();
3031 cmTargets::iterator i = tgts.find ( name );
3032 if ( i != tgts.end() )
3034 return &i->second;
3037 return 0;
3040 cmTest* cmMakefile::CreateTest(const char* testName)
3042 if ( !testName )
3044 return 0;
3046 cmTest* test = this->GetTest(testName);
3047 if ( test )
3049 return test;
3051 test = new cmTest;
3052 test->SetName(testName);
3053 test->SetMakefile(this);
3054 this->Tests.push_back(test);
3055 return test;
3058 cmTest* cmMakefile::GetTest(const char* testName) const
3060 if ( !testName )
3062 return 0;
3064 std::vector<cmTest*>::const_iterator it;
3065 for ( it = this->Tests.begin(); it != this->Tests.end(); ++ it )
3067 if ( strcmp((*it)->GetName(), testName) == 0 )
3069 return *it;
3072 return 0;
3075 const std::vector<cmTest*> *cmMakefile::GetTests() const
3077 return &this->Tests;
3080 std::vector<cmTest*> *cmMakefile::GetTests()
3082 return &this->Tests;
3085 std::string cmMakefile::GetListFileStack()
3087 cmOStringStream tmp;
3088 size_t depth = this->ListFileStack.size();
3089 if (depth > 0)
3091 std::deque<cmStdString>::iterator it = this->ListFileStack.end();
3094 if (depth != this->ListFileStack.size())
3096 tmp << "\n ";
3098 --it;
3099 tmp << "[";
3100 tmp << depth;
3101 tmp << "]\t";
3102 tmp << *it;
3103 depth--;
3105 while (it != this->ListFileStack.begin());
3107 return tmp.str();
3111 void cmMakefile::PushScope()
3113 // Get the index of the next stack entry.
3114 std::vector<DefinitionMap>::size_type index = this->DefinitionStack.size();
3116 // Allocate a new stack entry.
3117 this->DefinitionStack.push_back(DefinitionMap());
3119 // Copy the previous top to the new top.
3120 this->DefinitionStack[index] = this->DefinitionStack[index-1];
3123 void cmMakefile::PopScope()
3125 this->DefinitionStack.pop_back();
3128 void cmMakefile::RaiseScope(const char *var, const char *varDef)
3130 if (!var || !strlen(var))
3132 return;
3135 // multiple scopes in this directory?
3136 if (this->DefinitionStack.size() > 1)
3138 if(varDef)
3140 this->DefinitionStack[this->DefinitionStack.size()-2][var] = varDef;
3142 else
3144 this->DefinitionStack[this->DefinitionStack.size()-2].erase(var);
3147 // otherwise do the parent (if one exists)
3148 else if (this->LocalGenerator->GetParent())
3150 cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
3151 if (parent)
3153 if(varDef)
3155 parent->AddDefinition(var,varDef);
3157 else
3159 parent->RemoveDefinition(var);
3166 // define properties
3167 void cmMakefile::DefineProperties(cmake *cm)
3169 cm->DefineProperty
3170 ("ADDITIONAL_MAKE_CLEAN_FILES", cmProperty::DIRECTORY,
3171 "Additional files to clean during the make clean stage.",
3172 "A list of files that will be cleaned as a part of the "
3173 "\"make clean\" stage. ");
3175 cm->DefineProperty
3176 ("CLEAN_NO_CUSTOM", cmProperty::DIRECTORY,
3177 "Should the output of custom commands be left.",
3178 "If this is true then the outputs of custom commands for this "
3179 "directory will not be removed during the \"make clean\" stage. ");
3181 cm->DefineProperty
3182 ("LISTFILE_STACK", cmProperty::DIRECTORY,
3183 "The current stack of listfiles being processed.",
3184 "This property is mainly useful when trying to debug errors "
3185 "in your CMake scripts. It returns a list of what list files "
3186 "are currently being processed, in order. So if one listfile "
3187 "does an INCLUDE command then that is effectively pushing "
3188 "the included listfile onto the stack.");
3190 cm->DefineProperty
3191 ("TEST_INCLUDE_FILE", cmProperty::DIRECTORY,
3192 "A cmake file that will be included when ctest is run.",
3193 "If you specify TEST_INCLUDE_FILE, that file will be "
3194 "included and processed when ctest is run on the directory.");
3196 cm->DefineProperty
3197 ("COMPILE_DEFINITIONS", cmProperty::DIRECTORY,
3198 "Preprocessor definitions for compiling a directory's sources.",
3199 "The COMPILE_DEFINITIONS property may be set to a list of preprocessor "
3200 "definitions using the syntax VAR or VAR=value. Function-style "
3201 "definitions are not supported. CMake will automatically escape "
3202 "the value correctly for the native build system (note that CMake "
3203 "language syntax may require escapes to specify some values). "
3204 "This property may be set on a per-configuration basis using the name "
3205 "COMPILE_DEFINITIONS_<CONFIG> where <CONFIG> is an upper-case name "
3206 "(ex. \"COMPILE_DEFINITIONS_DEBUG\"). "
3207 "This property will be initialized in each directory by its value "
3208 "in the directory's parent.\n"
3209 "CMake will automatically drop some definitions that "
3210 "are not supported by the native build tool. "
3211 "The VS6 IDE does not support definitions with values "
3212 "(but NMake does).\n"
3213 "Dislaimer: Most native build tools have poor support for escaping "
3214 "certain values. CMake has work-arounds for many cases but some "
3215 "values may just not be possible to pass correctly. If a value "
3216 "does not seem to be escaped correctly, do not attempt to "
3217 "work-around the problem by adding escape sequences to the value. "
3218 "Your work-around may break in a future version of CMake that "
3219 "has improved escape support. Instead consider defining the macro "
3220 "in a (configured) header file. Then report the limitation.");
3222 cm->DefineProperty
3223 ("COMPILE_DEFINITIONS_<CONFIG>", cmProperty::DIRECTORY,
3224 "Per-configuration preprocessor definitions in a directory.",
3225 "This is the configuration-specific version of COMPILE_DEFINITIONS. "
3226 "This property will be initialized in each directory by its value "
3227 "in the directory's parent.\n");
3229 cm->DefineProperty
3230 ("EXCLUDE_FROM_ALL", cmProperty::DIRECTORY,
3231 "Exclude the directory from the all target of its parent.",
3232 "A property on a directory that indicates if its targets are excluded "
3233 "from the default build target. If it is not, then with a Makefile "
3234 "for example typing make will cause the targets to be built. "
3235 "The same concept applies to the default build of other generators.",
3236 false);
3239 //----------------------------------------------------------------------------
3240 cmTarget*
3241 cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type)
3243 // Create the target.
3244 cmsys::auto_ptr<cmTarget> target(new cmTarget);
3245 target->SetType(type, name);
3246 target->SetMakefile(this);
3247 target->MarkAsImported();
3249 // Add to the set of available imported targets.
3250 this->ImportedTargets[name] = target.get();
3252 // Transfer ownership to this cmMakefile object.
3253 this->ImportedTargetsOwned.push_back(target.get());
3254 return target.release();
3257 //----------------------------------------------------------------------------
3258 cmTarget* cmMakefile::FindTargetToUse(const char* name)
3260 // Look for an imported target. These take priority because they
3261 // are more local in scope and do not have to be globally unique.
3262 std::map<cmStdString, cmTarget*>::const_iterator
3263 imported = this->ImportedTargets.find(name);
3264 if(imported != this->ImportedTargets.end())
3266 return imported->second;
3269 // Look for a target built in this project.
3270 return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name);
3273 //----------------------------------------------------------------------------
3274 bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
3275 bool isCustom)
3277 if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
3279 // The name given conflicts with an existing target. Produce an
3280 // error in a compatible way.
3281 if(existing->IsImported())
3283 // Imported targets were not supported in previous versions.
3284 // This is new code, so we can make it an error.
3285 cmOStringStream e;
3286 e << "cannot create target \"" << name
3287 << "\" because an imported target with the same name already exists.";
3288 msg = e.str();
3289 return false;
3291 else
3293 // target names must be globally unique
3294 switch (this->GetPolicyStatus(cmPolicies::CMP0002))
3296 case cmPolicies::WARN:
3297 this->IssueMessage(cmake::AUTHOR_WARNING, this->GetPolicies()->
3298 GetPolicyWarning(cmPolicies::CMP0002));
3299 case cmPolicies::OLD:
3300 return true;
3301 case cmPolicies::REQUIRED_IF_USED:
3302 case cmPolicies::REQUIRED_ALWAYS:
3303 this->IssueMessage(cmake::FATAL_ERROR,
3304 this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0002)
3306 return true;
3307 case cmPolicies::NEW:
3308 break;
3311 // The conflict is with a non-imported target.
3312 // Allow this if the user has requested support.
3313 cmake* cm =
3314 this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
3315 if(isCustom && existing->GetType() == cmTarget::UTILITY &&
3316 this != existing->GetMakefile() &&
3317 cm->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
3319 return true;
3322 // Produce an error that tells the user how to work around the
3323 // problem.
3324 cmOStringStream e;
3325 e << "cannot create target \"" << name
3326 << "\" because another target with the same name already exists. "
3327 << "The existing target is ";
3328 switch(existing->GetType())
3330 case cmTarget::EXECUTABLE:
3331 e << "an executable ";
3332 break;
3333 case cmTarget::STATIC_LIBRARY:
3334 e << "a static library ";
3335 break;
3336 case cmTarget::SHARED_LIBRARY:
3337 e << "a shared library ";
3338 break;
3339 case cmTarget::MODULE_LIBRARY:
3340 e << "a module library ";
3341 break;
3342 case cmTarget::UTILITY:
3343 e << "a custom target ";
3344 break;
3345 default: break;
3347 e << "created in source directory \""
3348 << existing->GetMakefile()->GetCurrentDirectory() << "\". "
3349 << "See documentation for policy CMP0002 for more details.";
3350 msg = e.str();
3351 return false;
3354 return true;
3357 cmPolicies::PolicyStatus cmMakefile
3358 ::GetPolicyStatus(cmPolicies::PolicyID id)
3360 cmPolicies::PolicyStatus status = cmPolicies::REQUIRED_IF_USED;
3361 PolicyMap::iterator mappos;
3362 int vecpos;
3363 bool done = false;
3365 // check our policy stack first
3366 for (vecpos = static_cast<int>(this->PolicyStack.size()) - 1;
3367 vecpos >= 0 && !done; vecpos--)
3369 mappos = this->PolicyStack[vecpos].find(id);
3370 if (mappos != this->PolicyStack[vecpos].end())
3372 status = mappos->second;
3373 done = true;
3377 // if not found then
3378 if (!done)
3380 // pass the buck to our parent if we have one
3381 if (this->LocalGenerator->GetParent())
3383 cmMakefile *parent =
3384 this->LocalGenerator->GetParent()->GetMakefile();
3385 return parent->GetPolicyStatus(id);
3387 // otherwise use the default
3388 else
3390 status = this->GetPolicies()->GetPolicyStatus(id);
3394 // warn if we see a REQUIRED_IF_USED above a OLD or WARN
3395 if (!this->GetPolicies()->IsValidUsedPolicyStatus(id,status))
3397 return cmPolicies::REQUIRED_IF_USED;
3400 return status;
3403 bool cmMakefile::SetPolicy(const char *id,
3404 cmPolicies::PolicyStatus status)
3406 cmPolicies::PolicyID pid;
3407 if (!this->GetPolicies()->GetPolicyID(id, /* out */ pid))
3409 cmOStringStream e;
3410 e << "Policy \"" << id << "\" is not known to this version of CMake.";
3411 this->IssueMessage(cmake::FATAL_ERROR, e.str());
3412 return false;
3414 return this->SetPolicy(pid,status);
3417 bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
3418 cmPolicies::PolicyStatus status)
3420 // setting a REQUIRED_ALWAYS policy to WARN or OLD is an insta error
3421 if (this->GetPolicies()->
3422 IsValidPolicyStatus(id,status))
3424 this->PolicyStack.back()[id] = status;
3426 // Special hook for presenting compatibility variable as soon as
3427 // the user requests it.
3428 if(id == cmPolicies::CMP0001 &&
3429 (status == cmPolicies::WARN || status == cmPolicies::OLD))
3431 if(!(this->GetCacheManager()
3432 ->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
3434 // Set it to 2.4 because that is the last version where the
3435 // variable had meaning.
3436 this->AddCacheDefinition
3437 ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
3438 "For backwards compatibility, what version of CMake "
3439 "commands and "
3440 "syntax should this version of CMake try to support.",
3441 cmCacheManager::STRING);
3445 return true;
3447 return false;
3450 bool cmMakefile::PushPolicy()
3452 // Allocate a new stack entry.
3453 this->PolicyStack.push_back(PolicyMap());
3454 return true;
3457 bool cmMakefile::PopPolicy(bool reportError)
3459 if(this->PolicyStack.size() == 1)
3461 if(reportError)
3463 cmSystemTools::Error("Attempt to pop the policy stack past "
3464 "it's beginning.");
3466 return false;
3468 this->PolicyStack.pop_back();
3469 return true;
3472 bool cmMakefile::SetPolicyVersion(const char *version)
3474 return this->GetCMakeInstance()->GetPolicies()->
3475 ApplyPolicyVersion(this,version);
3478 cmPolicies *cmMakefile::GetPolicies()
3480 if (!this->GetCMakeInstance())
3482 return 0;
3484 return this->GetCMakeInstance()->GetPolicies();