STYLE: Fix line-too-long
[cmake.git] / Source / cmMakefile.cxx
blob73435bb62c152d617b981df43fde2fd122390d11
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmMakefile.cxx,v $
5 Language: C++
6 Date: $Date: 2008-10-09 17:52:25 $
7 Version: $Revision: 1.486 $
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|f|f90|for|fpp"
87 "|ftn|m|mm|rc|def|r|odl|idl|hpj|bat)$");
88 this->AddSourceGroup("Header Files",
89 "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
90 this->AddSourceGroup("CMake Rules", "\\.rule$");
91 this->AddSourceGroup("Resources", "\\.plist$");
92 #endif
93 this->AddDefaultDefinitions();
94 this->Initialize();
95 this->PreOrder = false;
98 cmMakefile::cmMakefile(const cmMakefile& mf)
100 this->Prefix = mf.Prefix;
101 this->AuxSourceDirectories = mf.AuxSourceDirectories;
102 this->cmStartDirectory = mf.cmStartDirectory;
103 this->StartOutputDirectory = mf.StartOutputDirectory;
104 this->cmHomeDirectory = mf.cmHomeDirectory;
105 this->HomeOutputDirectory = mf.HomeOutputDirectory;
106 this->cmCurrentListFile = mf.cmCurrentListFile;
107 this->ProjectName = mf.ProjectName;
108 this->Targets = mf.Targets;
109 this->SourceFiles = mf.SourceFiles;
110 this->Tests = mf.Tests;
111 this->IncludeDirectories = mf.IncludeDirectories;
112 this->LinkDirectories = mf.LinkDirectories;
113 this->SystemIncludeDirectories = mf.SystemIncludeDirectories;
114 this->ListFiles = mf.ListFiles;
115 this->OutputFiles = mf.OutputFiles;
116 this->LinkLibraries = mf.LinkLibraries;
117 this->InstallGenerators = mf.InstallGenerators;
118 this->IncludeFileRegularExpression = mf.IncludeFileRegularExpression;
119 this->ComplainFileRegularExpression = mf.ComplainFileRegularExpression;
120 this->SourceFileExtensions = mf.SourceFileExtensions;
121 this->HeaderFileExtensions = mf.HeaderFileExtensions;
122 this->DefineFlags = mf.DefineFlags;
123 this->DefineFlagsOrig = mf.DefineFlagsOrig;
125 #if defined(CMAKE_BUILD_WITH_CMAKE)
126 this->SourceGroups = mf.SourceGroups;
127 #endif
129 this->DefinitionStack.push_back(mf.DefinitionStack.back());
130 this->LocalGenerator = mf.LocalGenerator;
131 this->FunctionBlockers = mf.FunctionBlockers;
132 this->DataMap = mf.DataMap;
133 this->MacrosMap = mf.MacrosMap;
134 this->SubDirectoryOrder = mf.SubDirectoryOrder;
135 this->TemporaryDefinitionKey = mf.TemporaryDefinitionKey;
136 this->Properties = mf.Properties;
137 this->PreOrder = mf.PreOrder;
138 this->ListFileStack = mf.ListFileStack;
139 this->Initialize();
142 //----------------------------------------------------------------------------
143 void cmMakefile::Initialize()
145 this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
146 this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
147 this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
149 // Enter a policy level for this directory.
150 this->PushPolicy();
152 // By default the check is not done. It is enabled by
153 // cmListFileCache in the top level if necessary.
154 this->CheckCMP0000 = false;
157 unsigned int cmMakefile::GetCacheMajorVersion()
159 return this->GetCacheManager()->GetCacheMajorVersion();
162 unsigned int cmMakefile::GetCacheMinorVersion()
164 return this->GetCacheManager()->GetCacheMinorVersion();
167 bool cmMakefile::NeedCacheCompatibility(int major, int minor)
169 return this->GetCacheManager()->NeedCacheCompatibility(major, minor);
172 cmMakefile::~cmMakefile()
174 for(std::vector<cmInstallGenerator*>::iterator
175 i = this->InstallGenerators.begin();
176 i != this->InstallGenerators.end(); ++i)
178 delete *i;
180 for(std::vector<cmSourceFile*>::iterator i = this->SourceFiles.begin();
181 i != this->SourceFiles.end(); ++i)
183 delete *i;
185 for(std::vector<cmTest*>::iterator i = this->Tests.begin();
186 i != this->Tests.end(); ++i)
188 delete *i;
190 for(std::vector<cmTarget*>::iterator
191 i = this->ImportedTargetsOwned.begin();
192 i != this->ImportedTargetsOwned.end(); ++i)
194 delete *i;
196 for(unsigned int i=0; i < this->UsedCommands.size(); i++)
198 delete this->UsedCommands[i];
200 for(DataMapType::const_iterator d = this->DataMap.begin();
201 d != this->DataMap.end(); ++d)
203 if(d->second)
205 delete d->second;
208 std::list<cmFunctionBlocker *>::iterator pos;
209 for (pos = this->FunctionBlockers.begin();
210 pos != this->FunctionBlockers.end(); ++pos)
212 cmFunctionBlocker* b = *pos;
213 delete b;
215 this->FunctionBlockers.clear();
216 if (this->PolicyStack.size() != 1)
218 cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
219 " popped properly");
223 void cmMakefile::PrintStringVector(const char* s,
224 const std::vector<std::string>& v) const
226 std::cout << s << ": ( \n";
227 for(std::vector<std::string>::const_iterator i = v.begin();
228 i != v.end(); ++i)
230 std::cout << (*i).c_str() << " ";
232 std::cout << " )\n";
235 void cmMakefile
236 ::PrintStringVector(const char* s,
237 const std::vector<std::pair<cmStdString, bool> >& v) const
239 std::cout << s << ": ( \n";
240 for(std::vector<std::pair<cmStdString, bool> >::const_iterator i
241 = v.begin(); i != v.end(); ++i)
243 std::cout << i->first.c_str() << " " << i->second;
245 std::cout << " )\n";
249 // call print on all the classes in the makefile
250 void cmMakefile::Print()
252 // print the class lists
253 std::cout << "classes:\n";
255 std::cout << " this->Targets: ";
256 for (cmTargets::iterator l = this->Targets.begin();
257 l != this->Targets.end(); l++)
259 std::cout << l->first << std::endl;
262 std::cout << " this->StartOutputDirectory; " <<
263 this->StartOutputDirectory.c_str() << std::endl;
264 std::cout << " this->HomeOutputDirectory; " <<
265 this->HomeOutputDirectory.c_str() << std::endl;
266 std::cout << " this->cmStartDirectory; " <<
267 this->cmStartDirectory.c_str() << std::endl;
268 std::cout << " this->cmHomeDirectory; " <<
269 this->cmHomeDirectory.c_str() << std::endl;
270 std::cout << " this->ProjectName; "
271 << this->ProjectName.c_str() << std::endl;
272 this->PrintStringVector("this->IncludeDirectories;",
273 this->IncludeDirectories);
274 this->PrintStringVector("this->LinkDirectories", this->LinkDirectories);
275 #if defined(CMAKE_BUILD_WITH_CMAKE)
276 for( std::vector<cmSourceGroup>::const_iterator i =
277 this->SourceGroups.begin(); i != this->SourceGroups.end(); ++i)
279 std::cout << "Source Group: " << i->GetName() << std::endl;
281 #endif
284 bool cmMakefile::CommandExists(const char* name) const
286 return this->GetCMakeInstance()->CommandExists(name);
290 //----------------------------------------------------------------------------
291 void cmMakefile::IssueMessage(cmake::MessageType t,
292 std::string const& text) const
294 // Collect context information.
295 cmListFileBacktrace backtrace;
296 if(!this->CallStack.empty())
298 if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR))
300 this->CallStack.back().Status->SetNestedError(true);
302 this->GetBacktrace(backtrace);
304 else
306 cmListFileContext lfc;
307 if(this->ListFileStack.empty())
309 // We are not processing the project. Add the directory-level context.
310 lfc.FilePath = this->GetCurrentDirectory();
311 lfc.FilePath += "/CMakeLists.txt";
313 else
315 // We are processing the project but are not currently executing a
316 // command. Add whatever context information we have.
317 lfc.FilePath = this->ListFileStack.back();
319 lfc.Line = 0;
320 if(!this->GetCMakeInstance()->GetIsInTryCompile())
322 lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath.c_str(),
323 cmLocalGenerator::HOME);
325 backtrace.push_back(lfc);
328 // Issue the message.
329 this->GetCMakeInstance()->IssueMessage(t, text, backtrace);
332 //----------------------------------------------------------------------------
333 bool cmMakefile::GetBacktrace(cmListFileBacktrace& backtrace) const
335 if(this->CallStack.empty())
337 return false;
339 for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
340 i != this->CallStack.rend(); ++i)
342 cmListFileContext lfc = *(*i).Context;
343 lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath.c_str(),
344 cmLocalGenerator::HOME);
345 backtrace.push_back(lfc);
347 return true;
350 //----------------------------------------------------------------------------
351 // Helper class to make sure the call stack is valid.
352 class cmMakefileCall
354 public:
355 cmMakefileCall(cmMakefile* mf,
356 cmListFileContext const& lfc,
357 cmExecutionStatus& status): Makefile(mf)
359 cmMakefile::CallStackEntry entry = {&lfc, &status};
360 this->Makefile->CallStack.push_back(entry);
362 ~cmMakefileCall()
364 this->Makefile->CallStack.pop_back();
366 private:
367 cmMakefile* Makefile;
370 //----------------------------------------------------------------------------
371 bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
372 cmExecutionStatus &status)
374 bool result = true;
376 // quick return if blocked
377 if(this->IsFunctionBlocked(lff,status))
379 // No error.
380 return result;
383 std::string name = lff.Name;
385 // Place this call on the call stack.
386 cmMakefileCall stack_manager(this, lff, status);
387 static_cast<void>(stack_manager);
389 // Lookup the command prototype.
390 if(cmCommand* proto = this->GetCMakeInstance()->GetCommand(name.c_str()))
392 // Clone the prototype.
393 cmsys::auto_ptr<cmCommand> pcmd(proto->Clone());
394 pcmd->SetMakefile(this);
396 // Decide whether to invoke the command.
397 if(pcmd->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() &&
398 (!this->GetCMakeInstance()->GetScriptMode() || pcmd->IsScriptable()))
400 // if trace is one, print out invoke information
401 if(this->GetCMakeInstance()->GetTrace())
403 cmOStringStream msg;
404 msg << lff.FilePath << "(" << lff.Line << "): ";
405 msg << lff.Name << "(";
406 for(std::vector<cmListFileArgument>::const_iterator i =
407 lff.Arguments.begin(); i != lff.Arguments.end(); ++i)
409 msg << i->Value;
410 msg << " ";
412 msg << ")";
413 cmSystemTools::Message(msg.str().c_str());
415 // Try invoking the command.
416 if(!pcmd->InvokeInitialPass(lff.Arguments,status) ||
417 status.GetNestedError())
419 if(!status.GetNestedError())
421 // The command invocation requested that we report an error.
422 this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError());
424 result = false;
425 if ( this->GetCMakeInstance()->GetScriptMode() )
427 cmSystemTools::SetFatalErrorOccured();
430 else
432 // use the command
433 this->UsedCommands.push_back(pcmd.release());
436 else if ( this->GetCMakeInstance()->GetScriptMode()
437 && !pcmd->IsScriptable() )
439 std::string error = "Command ";
440 error += pcmd->GetName();
441 error += "() is not scriptable";
442 this->IssueMessage(cmake::FATAL_ERROR, error);
443 result = false;
444 cmSystemTools::SetFatalErrorOccured();
447 else
449 if(!cmSystemTools::GetFatalErrorOccured())
451 std::string error = "Unknown CMake command \"";
452 error += lff.Name;
453 error += "\".";
454 this->IssueMessage(cmake::FATAL_ERROR, error);
455 result = false;
456 cmSystemTools::SetFatalErrorOccured();
460 return result;
463 // Parse the given CMakeLists.txt file executing all commands
465 bool cmMakefile::ReadListFile(const char* filename_in,
466 const char *external_in,
467 std::string* fullPath)
469 std::string currentParentFile
470 = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
471 std::string currentFile
472 = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
473 this->AddDefinition("CMAKE_PARENT_LIST_FILE", filename_in);
475 // used to watch for blockers going out of scope
476 // e.g. mismatched IF statement
477 std::set<cmFunctionBlocker *> originalBlockers;
479 const char* external = 0;
480 std::string external_abs;
482 const char* filename = filename_in;
483 std::string filename_abs;
485 if (external_in)
487 external_abs =
488 cmSystemTools::CollapseFullPath(external_in,
489 this->cmStartDirectory.c_str());
490 external = external_abs.c_str();
491 if (filename_in)
493 filename_abs =
494 cmSystemTools::CollapseFullPath(filename_in,
495 this->cmStartDirectory.c_str());
496 filename = filename_abs.c_str();
500 // keep track of the current file being read
501 if (filename)
503 if(this->cmCurrentListFile != filename)
505 this->cmCurrentListFile = filename;
509 // loop over current function blockers and record them
510 for (std::list<cmFunctionBlocker *>::iterator pos
511 = this->FunctionBlockers.begin();
512 pos != this->FunctionBlockers.end(); ++pos)
514 originalBlockers.insert(*pos);
517 // Now read the input file
518 const char *filenametoread= filename;
520 if( external)
522 filenametoread= external;
525 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
527 // try to see if the list file is the top most
528 // list file for a project, and if it is, then it
529 // must have a project command. If there is not
530 // one, then cmake will provide one via the
531 // cmListFileCache class.
532 bool requireProjectCommand = false;
533 if(!external && this->cmStartDirectory == this->cmHomeDirectory)
535 if(cmSystemTools::LowerCase(
536 cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt")
538 requireProjectCommand = true;
542 // push the listfile onto the stack
543 this->ListFileStack.push_back(filenametoread);
544 if(fullPath!=0)
546 *fullPath=filenametoread;
548 cmListFile cacheFile;
549 if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
551 // pop the listfile off the stack
552 this->ListFileStack.pop_back();
553 if(fullPath!=0)
555 *fullPath = "";
557 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
558 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
559 return false;
561 // add this list file to the list of dependencies
562 this->ListFiles.push_back( filenametoread);
563 bool endScopeNicely = true;
564 const size_t numberFunctions = cacheFile.Functions.size();
565 for(size_t i =0; i < numberFunctions; ++i)
567 cmExecutionStatus status;
568 this->ExecuteCommand(cacheFile.Functions[i],status);
569 if (status.GetReturnInvoked() ||
570 cmSystemTools::GetFatalErrorOccured() )
572 // Exit early from processing this file.
573 endScopeNicely = false;
574 break;
578 // send scope ended to and function blockers
579 if (endScopeNicely)
581 // loop over all function blockers to see if any block this command
582 for (std::list<cmFunctionBlocker *>::iterator pos
583 = this->FunctionBlockers.begin();
584 pos != this->FunctionBlockers.end(); ++pos)
586 // if this blocker was not in the original then send a
587 // scope ended message
588 if (originalBlockers.find(*pos) == originalBlockers.end())
590 (*pos)->ScopeEnded(*this);
595 // If this is the directory-level CMakeLists.txt file then perform
596 // some extra checks.
597 if(this->ListFileStack.size() == 1)
599 this->EnforceDirectoryLevelRules(endScopeNicely);
602 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
603 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
605 // pop the listfile off the stack
606 this->ListFileStack.pop_back();
608 return true;
611 //----------------------------------------------------------------------------
612 void cmMakefile::EnforceDirectoryLevelRules(bool endScopeNicely)
614 // Enforce policy stack depth.
615 while(this->PolicyStack.size() > 1)
617 if(endScopeNicely)
619 this->IssueMessage(cmake::FATAL_ERROR,
620 "cmake_policy PUSH without matching POP");
622 this->PopPolicy(false);
625 // Diagnose a violation of CMP0000 if necessary.
626 if(this->CheckCMP0000)
628 cmOStringStream msg;
629 msg << "No cmake_minimum_required command is present. "
630 << "A line of code such as\n"
631 << " cmake_minimum_required(VERSION "
632 << cmVersion::GetMajorVersion() << "."
633 << cmVersion::GetMinorVersion()
634 << ")\n"
635 << "should be added at the top of the file. "
636 << "The version specified may be lower if you wish to "
637 << "support older CMake versions for this project. "
638 << "For more information run "
639 << "\"cmake --help-policy CMP0000\".";
640 switch (this->GetPolicyStatus(cmPolicies::CMP0000))
642 case cmPolicies::WARN:
643 // Warn because the user did not provide a mimimum required
644 // version.
645 this->IssueMessage(cmake::AUTHOR_WARNING, msg.str().c_str());
646 case cmPolicies::OLD:
647 // OLD behavior is to use policy version 2.4 set in
648 // cmListFileCache.
649 break;
650 case cmPolicies::REQUIRED_IF_USED:
651 case cmPolicies::REQUIRED_ALWAYS:
652 case cmPolicies::NEW:
653 // NEW behavior is to issue an error.
654 this->IssueMessage(cmake::FATAL_ERROR, msg.str().c_str());
655 cmSystemTools::SetFatalErrorOccured();
656 return;
661 void cmMakefile::AddCommand(cmCommand* wg)
663 this->GetCMakeInstance()->AddCommand(wg);
666 // Set the make file
667 void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
669 this->LocalGenerator = lg;
672 bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
673 unsigned int minor,
674 unsigned int patch)
676 if(this->LocalGenerator)
678 return
679 this->LocalGenerator->NeedBackwardsCompatibility(major, minor, patch);
681 else
683 return false;
687 void cmMakefile::FinalPass()
689 // do all the variable expansions here
690 this->ExpandVariables();
692 // give all the commands a chance to do something
693 // after the file has been parsed before generation
694 for(std::vector<cmCommand*>::iterator i = this->UsedCommands.begin();
695 i != this->UsedCommands.end(); ++i)
697 (*i)->FinalPass();
702 // Generate the output file
703 void cmMakefile::ConfigureFinalPass()
705 this->FinalPass();
706 const char* oldValue
707 = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
708 if (oldValue && atof(oldValue) <= 1.2)
710 cmSystemTools::Error("You have requested backwards compatibility "
711 "with CMake version 1.2 or earlier. This version "
712 "of CMake only supports backwards compatibility "
713 "with CMake 1.4 or later. For compatibility with "
714 "1.2 or earlier please use CMake 2.0");
716 for (cmTargets::iterator l = this->Targets.begin();
717 l != this->Targets.end(); l++)
719 l->second.AnalyzeLibDependencies(*this);
723 //----------------------------------------------------------------------------
724 void
725 cmMakefile::AddCustomCommandToTarget(const char* target,
726 const std::vector<std::string>& depends,
727 const cmCustomCommandLines& commandLines,
728 cmTarget::CustomCommandType type,
729 const char* comment,
730 const char* workingDir,
731 bool escapeOldStyle)
733 // Find the target to which to add the custom command.
734 cmTargets::iterator ti = this->Targets.find(target);
735 if(ti != this->Targets.end())
737 // Add the command to the appropriate build step for the target.
738 std::vector<std::string> no_output;
739 cmCustomCommand cc(no_output, depends, commandLines, comment, workingDir);
740 cc.SetEscapeOldStyle(escapeOldStyle);
741 cc.SetEscapeAllowMakeVars(true);
742 switch(type)
744 case cmTarget::PRE_BUILD:
745 ti->second.GetPreBuildCommands().push_back(cc);
746 break;
747 case cmTarget::PRE_LINK:
748 ti->second.GetPreLinkCommands().push_back(cc);
749 break;
750 case cmTarget::POST_BUILD:
751 ti->second.GetPostBuildCommands().push_back(cc);
752 break;
757 //----------------------------------------------------------------------------
758 void
759 cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
760 const std::vector<std::string>& depends,
761 const char* main_dependency,
762 const cmCustomCommandLines& commandLines,
763 const char* comment,
764 const char* workingDir,
765 bool replace,
766 bool escapeOldStyle)
768 // Make sure there is at least one output.
769 if(outputs.empty())
771 cmSystemTools::Error("Attempt to add a custom rule with no output!");
772 return;
775 // Choose a source file on which to store the custom command.
776 cmSourceFile* file = 0;
777 if(main_dependency && main_dependency[0])
779 // The main dependency was specified. Use it unless a different
780 // custom command already used it.
781 file = this->GetSource(main_dependency);
782 if(file && file->GetCustomCommand() && !replace)
784 // The main dependency already has a custom command.
785 if(commandLines == file->GetCustomCommand()->GetCommandLines())
787 // The existing custom command is identical. Silently ignore
788 // the duplicate.
789 return;
791 else
793 // The existing custom command is different. We need to
794 // generate a rule file for this new command.
795 file = 0;
798 else
800 // The main dependency does not have a custom command or we are
801 // allowed to replace it. Use it to store the command.
802 file = this->GetOrCreateSource(main_dependency);
806 // Generate a rule file if the main dependency is not available.
807 if(!file)
809 // Construct a rule file associated with the first output produced.
810 std::string outName = outputs[0];
811 outName += ".rule";
813 // Check if the rule file already exists.
814 file = this->GetSource(outName.c_str());
815 if(file && file->GetCustomCommand() && !replace)
817 // The rule file already exists.
818 if(commandLines != file->GetCustomCommand()->GetCommandLines())
820 cmSystemTools::Error("Attempt to add a custom rule to output \"",
821 outName.c_str(),
822 "\" which already has a custom rule.");
824 return;
827 // Create a cmSourceFile for the rule file.
828 file = this->GetOrCreateSource(outName.c_str(), true);
831 // Always create the output sources and mark them generated.
832 for(std::vector<std::string>::const_iterator o = outputs.begin();
833 o != outputs.end(); ++o)
835 if(cmSourceFile* out = this->GetOrCreateSource(o->c_str(), true))
837 out->SetProperty("GENERATED", "1");
841 // Construct a complete list of dependencies.
842 std::vector<std::string> depends2(depends);
843 if(main_dependency && main_dependency[0])
845 depends2.push_back(main_dependency);
848 // Attach the custom command to the file.
849 if(file)
851 cmCustomCommand* cc =
852 new cmCustomCommand(outputs, depends2, commandLines,
853 comment, workingDir);
854 cc->SetEscapeOldStyle(escapeOldStyle);
855 cc->SetEscapeAllowMakeVars(true);
856 file->SetCustomCommand(cc);
860 //----------------------------------------------------------------------------
861 void
862 cmMakefile::AddCustomCommandToOutput(const char* output,
863 const std::vector<std::string>& depends,
864 const char* main_dependency,
865 const cmCustomCommandLines& commandLines,
866 const char* comment,
867 const char* workingDir,
868 bool replace,
869 bool escapeOldStyle)
871 std::vector<std::string> outputs;
872 outputs.push_back(output);
873 this->AddCustomCommandToOutput(outputs, depends, main_dependency,
874 commandLines, comment, workingDir,
875 replace, escapeOldStyle);
878 //----------------------------------------------------------------------------
879 void
880 cmMakefile::AddCustomCommandOldStyle(const char* target,
881 const std::vector<std::string>& outputs,
882 const std::vector<std::string>& depends,
883 const char* source,
884 const cmCustomCommandLines& commandLines,
885 const char* comment)
887 // Translate the old-style signature to one of the new-style
888 // signatures.
889 if(strcmp(source, target) == 0)
891 // In the old-style signature if the source and target were the
892 // same then it added a post-build rule to the target. Preserve
893 // this behavior.
894 this->AddCustomCommandToTarget(target, depends, commandLines,
895 cmTarget::POST_BUILD, comment, 0);
896 return;
899 // Each output must get its own copy of this rule.
900 cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|"
901 "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
902 "hm|hpp|hxx|in|txx|inl)$");
903 for(std::vector<std::string>::const_iterator oi = outputs.begin();
904 oi != outputs.end(); ++oi)
906 // Get the name of this output.
907 const char* output = oi->c_str();
909 // Choose whether to use a main dependency.
910 if(sourceFiles.find(source))
912 // The source looks like a real file. Use it as the main dependency.
913 this->AddCustomCommandToOutput(output, depends, source,
914 commandLines, comment, 0);
916 else
918 // The source may not be a real file. Do not use a main dependency.
919 const char* no_main_dependency = 0;
920 std::vector<std::string> depends2 = depends;
921 depends2.push_back(source);
922 this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
923 commandLines, comment, 0);
926 // If the rule was added to the source (and not a .rule file),
927 // then add the source to the target to make sure the rule is
928 // included.
929 std::string sname = output;
930 sname += ".rule";
931 if(!this->GetSource(sname.c_str()))
933 if (this->Targets.find(target) != this->Targets.end())
935 this->Targets[target].AddSource(source);
937 else
939 cmSystemTools::Error("Attempt to add a custom rule to a target "
940 "that does not exist yet for target ", target);
941 return;
947 //----------------------------------------------------------------------------
948 void cmMakefile::AddUtilityCommand(const char* utilityName,
949 bool excludeFromAll,
950 const std::vector<std::string>& depends,
951 const char* workingDirectory,
952 const char* command,
953 const char* arg1,
954 const char* arg2,
955 const char* arg3,
956 const char* arg4)
958 // Construct the command line for the custom command.
959 cmCustomCommandLine commandLine;
960 commandLine.push_back(command);
961 if(arg1)
963 commandLine.push_back(arg1);
965 if(arg2)
967 commandLine.push_back(arg2);
969 if(arg3)
971 commandLine.push_back(arg3);
973 if(arg4)
975 commandLine.push_back(arg4);
977 cmCustomCommandLines commandLines;
978 commandLines.push_back(commandLine);
980 // Call the real signature of this method.
981 this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
982 depends, commandLines);
985 //----------------------------------------------------------------------------
986 cmTarget*
987 cmMakefile::AddUtilityCommand(const char* utilityName,
988 bool excludeFromAll,
989 const char* workingDirectory,
990 const std::vector<std::string>& depends,
991 const cmCustomCommandLines& commandLines,
992 bool escapeOldStyle, const char* comment)
994 // Create a target instance for this utility.
995 cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
996 if (excludeFromAll)
998 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1000 if(!comment)
1002 // Use an empty comment to avoid generation of default comment.
1003 comment = "";
1006 // Store the custom command in the target.
1007 std::string force = this->GetStartOutputDirectory();
1008 force += cmake::GetCMakeFilesDirectory();
1009 force += "/";
1010 force += utilityName;
1011 const char* no_main_dependency = 0;
1012 bool no_replace = false;
1013 this->AddCustomCommandToOutput(force.c_str(), depends,
1014 no_main_dependency,
1015 commandLines, comment,
1016 workingDirectory, no_replace,
1017 escapeOldStyle);
1018 cmSourceFile* sf = target->AddSource(force.c_str());
1020 // The output is not actually created so mark it symbolic.
1021 if(sf)
1023 sf->SetProperty("SYMBOLIC", "1");
1025 else
1027 cmSystemTools::Error("Could not get source file entry for ",
1028 force.c_str());
1030 return target;
1033 void cmMakefile::AddDefineFlag(const char* flag)
1035 if (!flag)
1037 return;
1040 // Update the string used for the old DEFINITIONS property.
1041 this->AddDefineFlag(flag, this->DefineFlagsOrig);
1043 // If this is really a definition, update COMPILE_DEFINITIONS.
1044 if(this->ParseDefineFlag(flag, false))
1046 return;
1049 // Add this flag that does not look like a definition.
1050 this->AddDefineFlag(flag, this->DefineFlags);
1053 void cmMakefile::AddDefineFlag(const char* flag, std::string& dflags)
1055 // remove any \n\r
1056 std::string ret = flag;
1057 std::string::size_type pos = 0;
1058 while((pos = ret.find('\n', pos)) != std::string::npos)
1060 ret[pos] = ' ';
1061 pos++;
1063 pos = 0;
1064 while((pos = ret.find('\r', pos)) != std::string::npos)
1066 ret[pos] = ' ';
1067 pos++;
1070 dflags += " ";
1071 dflags += ret;
1075 void cmMakefile::RemoveDefineFlag(const char* flag)
1077 // Check the length of the flag to remove.
1078 std::string::size_type len = strlen(flag);
1079 if(len < 1)
1081 return;
1084 // Update the string used for the old DEFINITIONS property.
1085 this->RemoveDefineFlag(flag, len, this->DefineFlagsOrig);
1087 // If this is really a definition, update COMPILE_DEFINITIONS.
1088 if(this->ParseDefineFlag(flag, true))
1090 return;
1093 // Remove this flag that does not look like a definition.
1094 this->RemoveDefineFlag(flag, len, this->DefineFlags);
1097 void cmMakefile::RemoveDefineFlag(const char* flag,
1098 std::string::size_type len,
1099 std::string& dflags)
1101 // Remove all instances of the flag that are surrounded by
1102 // whitespace or the beginning/end of the string.
1103 for(std::string::size_type lpos = dflags.find(flag, 0);
1104 lpos != std::string::npos; lpos = dflags.find(flag, lpos))
1106 std::string::size_type rpos = lpos + len;
1107 if((lpos <= 0 || isspace(dflags[lpos-1])) &&
1108 (rpos >= dflags.size() || isspace(dflags[rpos])))
1110 dflags.erase(lpos, len);
1112 else
1114 ++lpos;
1119 bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
1121 // Create a regular expression to match valid definitions.
1122 static cmsys::RegularExpression
1123 valid("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=.*)?$");
1125 // Make sure the definition matches.
1126 if(!valid.find(def.c_str()))
1128 return false;
1131 // VS6 IDE does not support definitions with values.
1132 if((strcmp(this->LocalGenerator->GetGlobalGenerator()->GetName(),
1133 "Visual Studio 6") == 0) &&
1134 (def.find("=") != def.npos))
1136 return false;
1139 // Definitions with non-trivial values require a policy check.
1140 static cmsys::RegularExpression
1141 trivial("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=[A-Za-z0-9_.]+)?$");
1142 if(!trivial.find(def.c_str()))
1144 // This definition has a non-trivial value.
1145 switch(this->GetPolicyStatus(cmPolicies::CMP0005))
1147 case cmPolicies::WARN:
1148 this->IssueMessage(
1149 cmake::AUTHOR_WARNING,
1150 this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0005)
1152 case cmPolicies::OLD:
1153 // OLD behavior is to not escape the value. We should not
1154 // convert the definition to use the property.
1155 return false;
1156 case cmPolicies::REQUIRED_IF_USED:
1157 case cmPolicies::REQUIRED_ALWAYS:
1158 this->IssueMessage(
1159 cmake::FATAL_ERROR,
1160 this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0005)
1162 return false;
1163 case cmPolicies::NEW:
1164 // NEW behavior is to escape the value. Proceed to convert it
1165 // to an entry in the property.
1166 break;
1170 // Get the definition part after the flag.
1171 const char* define = def.c_str() + 2;
1173 if(remove)
1175 if(const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS"))
1177 // Expand the list.
1178 std::vector<std::string> defs;
1179 cmSystemTools::ExpandListArgument(cdefs, defs);
1181 // Recompose the list without the definition.
1182 std::string ndefs;
1183 const char* sep = "";
1184 for(std::vector<std::string>::const_iterator di = defs.begin();
1185 di != defs.end(); ++di)
1187 if(*di != define)
1189 ndefs += sep;
1190 sep = ";";
1191 ndefs += *di;
1195 // Store the new list.
1196 this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
1199 else
1201 // Append the definition to the directory property.
1202 this->AppendProperty("COMPILE_DEFINITIONS", define);
1205 return true;
1208 void cmMakefile::AddLinkLibrary(const char* lib,
1209 cmTarget::LinkLibraryType llt)
1211 cmTarget::LibraryID tmp;
1212 tmp.first = lib;
1213 tmp.second = llt;
1214 this->LinkLibraries.push_back(tmp);
1217 void cmMakefile::AddLinkLibraryForTarget(const char *target,
1218 const char* lib,
1219 cmTarget::LinkLibraryType llt)
1221 cmTargets::iterator i = this->Targets.find(target);
1222 if ( i != this->Targets.end())
1224 cmTarget* tgt =
1225 this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib);
1226 if(tgt)
1228 // CMake versions below 2.4 allowed linking to modules.
1229 bool allowModules = this->NeedBackwardsCompatibility(2,2);
1230 // if it is not a static or shared library then you can not link to it
1231 if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
1232 (tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
1233 tgt->IsExecutableWithExports()))
1235 cmOStringStream e;
1236 e << "Target \"" << lib << "\" of type "
1237 << cmTarget::TargetTypeNames[static_cast<int>(tgt->GetType())]
1238 << " may not be linked into another target. "
1239 << "One may link only to STATIC or SHARED libraries, or "
1240 << "to executables with the ENABLE_EXPORTS property set.";
1241 // in older versions of cmake linking to modules was allowed
1242 if( tgt->GetType() == cmTarget::MODULE_LIBRARY )
1244 e << "\n"
1245 << "If you are developing a new project, re-organize it to avoid "
1246 << "linking to modules. "
1247 << "If you are just trying to build an existing project, "
1248 << "set CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower to allow "
1249 << "linking to modules.";
1251 // if no modules are allowed then this is always an error
1252 if(!allowModules ||
1253 // if we allow modules but the type is not a module then it is
1254 // still an error
1255 (allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY))
1257 this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
1261 i->second.AddLinkLibrary( *this, target, lib, llt );
1263 else
1265 cmOStringStream e;
1266 e << "Attempt to add link library \""
1267 << lib << "\" to target \""
1268 << target << "\" which is not built by this project.";
1269 cmSystemTools::Error(e.str().c_str());
1273 void cmMakefile::AddLinkDirectoryForTarget(const char *target,
1274 const char* d)
1276 cmTargets::iterator i = this->Targets.find(target);
1277 if ( i != this->Targets.end())
1279 i->second.AddLinkDirectory( d );
1281 else
1283 cmSystemTools::Error
1284 ("Attempt to add link directories to non-existant target: ",
1285 target, " for directory ", d);
1289 void cmMakefile::AddLinkLibrary(const char* lib)
1291 this->AddLinkLibrary(lib,cmTarget::GENERAL);
1294 void cmMakefile::AddLinkDirectory(const char* dir)
1296 // Don't add a link directory that is already present. Yes, this
1297 // linear search results in n^2 behavior, but n won't be getting
1298 // much bigger than 20. We cannot use a set because of order
1299 // dependency of the link search path.
1301 if(!dir)
1303 return;
1305 // remove trailing slashes
1306 if(dir[strlen(dir)-1] == '/')
1308 std::string newdir = dir;
1309 newdir = newdir.substr(0, newdir.size()-1);
1310 if(std::find(this->LinkDirectories.begin(),
1311 this->LinkDirectories.end(),
1312 newdir.c_str()) == this->LinkDirectories.end())
1314 this->LinkDirectories.push_back(newdir);
1317 else
1319 if(std::find(this->LinkDirectories.begin(),
1320 this->LinkDirectories.end(), dir)
1321 == this->LinkDirectories.end())
1323 this->LinkDirectories.push_back(dir);
1328 void cmMakefile::InitializeFromParent()
1330 cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
1332 // copy the definitions
1333 this->DefinitionStack.front() = parent->DefinitionStack.back();
1335 // copy include paths
1336 this->IncludeDirectories = parent->IncludeDirectories;
1337 this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
1339 // define flags
1340 this->DefineFlags = parent->DefineFlags;
1341 this->DefineFlagsOrig = parent->DefineFlagsOrig;
1343 // Include transform property. There is no per-config version.
1345 const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM";
1346 this->SetProperty(prop, parent->GetProperty(prop));
1349 // compile definitions property and per-config versions
1351 this->SetProperty("COMPILE_DEFINITIONS",
1352 parent->GetProperty("COMPILE_DEFINITIONS"));
1353 std::vector<std::string> configs;
1354 if(const char* configTypes =
1355 this->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
1357 cmSystemTools::ExpandListArgument(configTypes, configs);
1359 else if(const char* buildType =
1360 this->GetDefinition("CMAKE_BUILD_TYPE"))
1362 configs.push_back(buildType);
1364 for(std::vector<std::string>::const_iterator ci = configs.begin();
1365 ci != configs.end(); ++ci)
1367 std::string defPropName = "COMPILE_DEFINITIONS_";
1368 defPropName += cmSystemTools::UpperCase(*ci);
1369 this->SetProperty(defPropName.c_str(),
1370 parent->GetProperty(defPropName.c_str()));
1374 // link libraries
1375 this->LinkLibraries = parent->LinkLibraries;
1377 // link directories
1378 this->LinkDirectories = parent->LinkDirectories;
1380 // the initial project name
1381 this->ProjectName = parent->ProjectName;
1383 // Copy include regular expressions.
1384 this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
1385 this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
1387 // Imported targets.
1388 this->ImportedTargets = parent->ImportedTargets;
1391 void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
1393 // copy our variables from the child makefile
1394 lg2->GetMakefile()->InitializeFromParent();
1395 lg2->GetMakefile()->MakeStartDirectoriesCurrent();
1396 if (this->GetCMakeInstance()->GetDebugOutput())
1398 std::string msg=" Entering ";
1399 msg += lg2->GetMakefile()->GetCurrentDirectory();
1400 cmSystemTools::Message(msg.c_str());
1402 // finally configure the subdir
1403 lg2->Configure();
1404 if (this->GetCMakeInstance()->GetDebugOutput())
1406 std::string msg=" Returning to ";
1407 msg += this->GetCurrentDirectory();
1408 cmSystemTools::Message(msg.c_str());
1412 void cmMakefile::AddSubDirectory(const char* sub,
1413 bool excludeFromAll, bool preorder)
1415 // the source path must be made full if it isn't already
1416 std::string srcPath = sub;
1417 if (!cmSystemTools::FileIsFullPath(srcPath.c_str()))
1419 srcPath = this->GetCurrentDirectory();
1420 srcPath += "/";
1421 srcPath += sub;
1424 // binary path must be made full if it isn't already
1425 std::string binPath = sub;
1426 if (!cmSystemTools::FileIsFullPath(binPath.c_str()))
1428 binPath = this->GetCurrentOutputDirectory();
1429 binPath += "/";
1430 binPath += sub;
1434 this->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
1435 excludeFromAll, preorder, false);
1439 void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
1440 bool excludeFromAll, bool preorder,
1441 bool immediate)
1443 std::vector<cmLocalGenerator *>& children =
1444 this->LocalGenerator->GetChildren();
1445 // has this directory already been added? If so error
1446 unsigned int i;
1447 for (i = 0; i < children.size(); ++i)
1449 if (srcPath == children[i]->GetMakefile()->GetStartDirectory())
1451 cmSystemTools::Error
1452 ("Attempt to add subdirectory multiple times for directory.\n",
1453 srcPath);
1454 return;
1458 // create a new local generator and set its parent
1459 cmLocalGenerator *lg2 =
1460 this->LocalGenerator->GetGlobalGenerator()->CreateLocalGenerator();
1461 lg2->SetParent(this->LocalGenerator);
1462 this->LocalGenerator->GetGlobalGenerator()->AddLocalGenerator(lg2);
1464 // set the subdirs start dirs
1465 lg2->GetMakefile()->SetStartDirectory(srcPath);
1466 lg2->GetMakefile()->SetStartOutputDirectory(binPath);
1467 if(excludeFromAll)
1469 lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1471 lg2->GetMakefile()->SetPreOrder(preorder);
1473 if (immediate)
1475 this->ConfigureSubDirectory(lg2);
1479 void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
1481 // if there is a newline then break it into multiple arguments
1482 if (!inc)
1484 return;
1487 // Don't add an include directory that is already present. Yes,
1488 // this linear search results in n^2 behavior, but n won't be
1489 // getting much bigger than 20. We cannot use a set because of
1490 // order dependency of the include path.
1491 std::vector<std::string>::iterator i =
1492 std::find(this->IncludeDirectories.begin(),
1493 this->IncludeDirectories.end(), inc);
1494 if(i == this->IncludeDirectories.end())
1496 if (before)
1498 // WARNING: this *is* expensive (linear time) since it's a vector
1499 this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
1501 else
1503 this->IncludeDirectories.push_back(inc);
1506 else
1508 if(before)
1510 // if this before and already in the path then remove it
1511 this->IncludeDirectories.erase(i);
1512 // WARNING: this *is* expensive (linear time) since it's a vector
1513 this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
1518 //----------------------------------------------------------------------------
1519 void cmMakefile::AddSystemIncludeDirectory(const char* dir)
1521 this->SystemIncludeDirectories.insert(dir);
1524 //----------------------------------------------------------------------------
1525 bool cmMakefile::IsSystemIncludeDirectory(const char* dir)
1527 return (this->SystemIncludeDirectories.find(dir) !=
1528 this->SystemIncludeDirectories.end());
1531 void cmMakefile::AddDefinition(const char* name, const char* value)
1533 if (!value )
1535 return;
1538 #ifdef CMAKE_STRICT
1539 if (this->GetCMakeInstance())
1541 this->GetCMakeInstance()->
1542 RecordPropertyAccess(name,cmProperty::VARIABLE);
1544 #endif
1546 this->TemporaryDefinitionKey = name;
1547 this->DefinitionStack.back()[this->TemporaryDefinitionKey] = value;
1549 #ifdef CMAKE_BUILD_WITH_CMAKE
1550 cmVariableWatch* vv = this->GetVariableWatch();
1551 if ( vv )
1553 vv->VariableAccessed(this->TemporaryDefinitionKey,
1554 cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1555 value,
1556 this);
1558 #endif
1562 void cmMakefile::AddCacheDefinition(const char* name, const char* value,
1563 const char* doc,
1564 cmCacheManager::CacheEntryType type)
1566 const char* val = value;
1567 cmCacheManager::CacheIterator it =
1568 this->GetCacheManager()->GetCacheIterator(name);
1569 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1570 it.Initialized())
1572 val = it.GetValue();
1573 if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH )
1575 std::vector<std::string>::size_type cc;
1576 std::vector<std::string> files;
1577 std::string nvalue = "";
1578 cmSystemTools::ExpandListArgument(val, files);
1579 for ( cc = 0; cc < files.size(); cc ++ )
1581 files[cc] = cmSystemTools::CollapseFullPath(files[cc].c_str());
1582 if ( cc > 0 )
1584 nvalue += ";";
1586 nvalue += files[cc];
1589 this->GetCacheManager()->AddCacheEntry(name, nvalue.c_str(), doc, type);
1590 val = it.GetValue();
1594 this->GetCacheManager()->AddCacheEntry(name, val, doc, type);
1595 // if there was a definition then remove it
1596 this->DefinitionStack.back().erase( DefinitionMap::key_type(name));
1600 void cmMakefile::AddDefinition(const char* name, bool value)
1602 if(value)
1604 this->DefinitionStack.back()
1605 .erase( DefinitionMap::key_type(name));
1606 this->DefinitionStack.back()
1607 .insert(DefinitionMap::value_type(name, "ON"));
1609 else
1611 this->DefinitionStack.back()
1612 .erase( DefinitionMap::key_type(name));
1613 this->DefinitionStack.back()
1614 .insert(DefinitionMap::value_type(name, "OFF"));
1616 #ifdef CMAKE_BUILD_WITH_CMAKE
1617 cmVariableWatch* vv = this->GetVariableWatch();
1618 if ( vv )
1620 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1621 value?"ON":"OFF", this);
1623 #endif
1627 void cmMakefile::AddCacheDefinition(const char* name,
1628 bool value,
1629 const char* doc)
1631 bool val = value;
1632 cmCacheManager::CacheIterator it =
1633 this->GetCacheManager()->GetCacheIterator(name);
1634 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1635 it.Initialized())
1637 val = it.GetValueAsBool();
1639 this->GetCacheManager()->AddCacheEntry(name, val, doc);
1640 this->AddDefinition(name, val);
1643 void cmMakefile::RemoveDefinition(const char* name)
1645 this->DefinitionStack.back().erase(DefinitionMap::key_type(name));
1646 #ifdef CMAKE_BUILD_WITH_CMAKE
1647 cmVariableWatch* vv = this->GetVariableWatch();
1648 if ( vv )
1650 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
1651 0, this);
1653 #endif
1656 void cmMakefile::RemoveCacheDefinition(const char* name)
1658 this->GetCacheManager()->RemoveCacheEntry(name);
1661 void cmMakefile::SetProjectName(const char* p)
1663 this->ProjectName = p;
1667 void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
1669 // for these targets do not add anything
1670 switch(target.GetType())
1672 case cmTarget::UTILITY:
1673 case cmTarget::GLOBAL_TARGET:
1674 return;
1675 default:;
1677 std::vector<std::string>::iterator j;
1678 for(j = this->LinkDirectories.begin();
1679 j != this->LinkDirectories.end(); ++j)
1681 target.AddLinkDirectory(j->c_str());
1683 target.MergeLinkLibraries( *this, name, this->LinkLibraries );
1687 void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
1688 const std::vector<std::string> &srcs,
1689 bool excludeFromAll)
1691 // wrong type ? default to STATIC
1692 if ( (type != cmTarget::STATIC_LIBRARY)
1693 && (type != cmTarget::SHARED_LIBRARY)
1694 && (type != cmTarget::MODULE_LIBRARY))
1696 type = cmTarget::STATIC_LIBRARY;
1699 cmTarget* target = this->AddNewTarget(type, lname);
1700 // Clear its dependencies. Otherwise, dependencies might persist
1701 // over changes in CMakeLists.txt, making the information stale and
1702 // hence useless.
1703 target->ClearDependencyInformation( *this, lname );
1704 if(excludeFromAll)
1706 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1708 target->AddSources(srcs);
1709 this->AddGlobalLinkInformation(lname, *target);
1712 cmTarget* cmMakefile::AddExecutable(const char *exeName,
1713 const std::vector<std::string> &srcs,
1714 bool excludeFromAll)
1716 cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName);
1717 if(excludeFromAll)
1719 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1721 target->AddSources(srcs);
1722 this->AddGlobalLinkInformation(exeName, *target);
1723 return target;
1726 //----------------------------------------------------------------------------
1727 cmTarget*
1728 cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name)
1730 cmTargets::iterator it =
1731 this->Targets.insert(cmTargets::value_type(name, cmTarget())).first;
1732 cmTarget& target = it->second;
1733 target.SetType(type, name);
1734 target.SetMakefile(this);
1735 this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it);
1736 return &it->second;
1739 cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
1741 std::string name = cname;
1742 std::string out;
1744 // look through all the source files that have custom commands
1745 // and see if the custom command has the passed source file as an output
1746 // keep in mind the possible .rule extension that may be tacked on
1747 for(std::vector<cmSourceFile*>::const_iterator i =
1748 this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
1750 // does this source file have a custom command?
1751 if ((*i)->GetCustomCommand())
1753 // is the output of the custom command match the source files name
1754 const std::vector<std::string>& outputs =
1755 (*i)->GetCustomCommand()->GetOutputs();
1756 for(std::vector<std::string>::const_iterator o = outputs.begin();
1757 o != outputs.end(); ++o)
1759 out = *o;
1760 std::string::size_type pos = out.rfind(name);
1761 // If the output matches exactly
1762 if (pos != out.npos &&
1763 pos == out.size() - name.size() &&
1764 (pos ==0 || out[pos-1] == '/'))
1766 return *i;
1772 // otherwise return NULL
1773 return 0;
1776 #if defined(CMAKE_BUILD_WITH_CMAKE)
1777 cmSourceGroup* cmMakefile::GetSourceGroup(const std::vector<std::string>&name)
1779 cmSourceGroup* sg = 0;
1781 // first look for source group starting with the same as the one we wants
1782 for (std::vector<cmSourceGroup>::iterator sgIt = this->SourceGroups.begin();
1783 sgIt != this->SourceGroups.end(); ++sgIt)
1786 std::string sgName = sgIt->GetName();
1787 if(sgName == name[0])
1789 sg = &(*sgIt);
1790 break;
1794 if(sg != 0)
1796 // iterate through its children to find match source group
1797 for(unsigned int i=1; i<name.size(); ++i)
1799 sg = sg->lookupChild(name[i].c_str());
1800 if(sg == 0)
1802 break;
1806 return sg;
1809 void cmMakefile::AddSourceGroup(const char* name,
1810 const char* regex)
1812 if (name)
1814 std::vector<std::string> nameVector;
1815 nameVector.push_back(name);
1816 AddSourceGroup(nameVector, regex);
1820 void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
1821 const char* regex)
1823 cmSourceGroup* sg = 0;
1824 std::vector<std::string> currentName;
1825 int i = 0;
1826 const int lastElement = static_cast<int>(name.size()-1);
1827 for(i=lastElement; i>=0; --i)
1829 currentName.assign(name.begin(), name.begin()+i+1);
1830 sg = this->GetSourceGroup(currentName);
1831 if(sg != 0)
1833 break;
1837 // i now contains the index of the last found component
1838 if(i==lastElement)
1840 // group already exists, replace its regular expression
1841 if ( regex )
1843 // We only want to set the regular expression. If there are already
1844 // source files in the group, we don't want to remove them.
1845 sg->SetGroupRegex(regex);
1847 return;
1849 else if(i==-1)
1851 // group does not exists nor belong to any existing group
1852 // add its first component
1853 this->SourceGroups.push_back(cmSourceGroup(name[0].c_str(), regex));
1854 sg = this->GetSourceGroup(currentName);
1855 i = 0; // last component found
1858 // build the whole source group path
1859 for(++i; i<=lastElement; ++i)
1861 sg->AddChild(cmSourceGroup(name[i].c_str(), 0));
1862 sg = sg->lookupChild(name[i].c_str());
1865 sg->SetGroupRegex(regex);
1868 #endif
1870 void cmMakefile::AddExtraDirectory(const char* dir)
1872 this->AuxSourceDirectories.push_back(dir);
1876 // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
1877 // include and library directories.
1879 void cmMakefile::ExpandVariables()
1881 // Now expand variables in the include and link strings
1882 for(std::vector<std::string>::iterator d = this->IncludeDirectories.begin();
1883 d != this->IncludeDirectories.end(); ++d)
1885 this->ExpandVariablesInString(*d, true, true);
1887 for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
1888 d != this->LinkDirectories.end(); ++d)
1890 this->ExpandVariablesInString(*d, true, true);
1892 for(cmTarget::LinkLibraryVectorType::iterator l =
1893 this->LinkLibraries.begin();
1894 l != this->LinkLibraries.end(); ++l)
1896 this->ExpandVariablesInString(l->first, true, true);
1900 bool cmMakefile::IsOn(const char* name) const
1902 const char* value = this->GetDefinition(name);
1903 return cmSystemTools::IsOn(value);
1906 bool cmMakefile::IsSet(const char* name) const
1908 const char* value = this->GetDefinition(name);
1909 if ( !value )
1911 return false;
1914 if ( ! *value )
1916 return false;
1919 if ( cmSystemTools::IsNOTFOUND(value) )
1921 return false;
1924 return true;
1927 bool cmMakefile::CanIWriteThisFile(const char* fileName)
1929 if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
1931 return true;
1933 // If we are doing an in-source build, than the test will always fail
1934 if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
1935 this->GetHomeOutputDirectory()) )
1937 if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
1939 return false;
1941 return true;
1944 // Check if this is subdirectory of the source tree but not a
1945 // subdirectory of a build tree
1946 if ( cmSystemTools::IsSubDirectory(fileName,
1947 this->GetHomeDirectory()) &&
1948 !cmSystemTools::IsSubDirectory(fileName,
1949 this->GetHomeOutputDirectory()) )
1951 return false;
1953 return true;
1956 const char* cmMakefile::GetRequiredDefinition(const char* name) const
1958 const char* ret = this->GetDefinition(name);
1959 if(!ret)
1961 cmSystemTools::Error("Error required internal CMake variable not "
1962 "set, cmake may be not be built correctly.\n",
1963 "Missing variable is:\n",
1964 name);
1965 return "";
1967 return ret;
1970 bool cmMakefile::IsDefinitionSet(const char* name) const
1972 const char* def = 0;
1973 DefinitionMap::const_iterator pos =
1974 this->DefinitionStack.back().find(name);
1975 if(pos != this->DefinitionStack.back().end())
1977 def = (*pos).second.c_str();
1979 else
1981 def = this->GetCacheManager()->GetCacheValue(name);
1983 #ifdef CMAKE_BUILD_WITH_CMAKE
1984 if(cmVariableWatch* vv = this->GetVariableWatch())
1986 if(!def)
1988 vv->VariableAccessed
1989 (name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS,
1990 def, this);
1993 #endif
1994 return def?true:false;
1997 const char* cmMakefile::GetDefinition(const char* name) const
1999 #ifdef CMAKE_STRICT
2000 if (this->GetCMakeInstance())
2002 this->GetCMakeInstance()->
2003 RecordPropertyAccess(name,cmProperty::VARIABLE);
2005 #endif
2006 const char* def = 0;
2007 DefinitionMap::const_iterator pos =
2008 this->DefinitionStack.back().find(name);
2009 if(pos != this->DefinitionStack.back().end())
2011 def = (*pos).second.c_str();
2013 else
2015 def = this->GetCacheManager()->GetCacheValue(name);
2017 #ifdef CMAKE_BUILD_WITH_CMAKE
2018 cmVariableWatch* vv = this->GetVariableWatch();
2019 if ( vv )
2021 if ( def )
2023 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
2024 def, this);
2026 else
2028 // are unknown access allowed
2029 DefinitionMap::const_iterator pos2 =
2030 this->DefinitionStack.back()
2031 .find("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
2032 if (pos2 != this->DefinitionStack.back().end() &&
2033 cmSystemTools::IsOn((*pos2).second.c_str()))
2035 vv->VariableAccessed(name,
2036 cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, def, this);
2038 else
2040 vv->VariableAccessed(name,
2041 cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
2045 #endif
2046 return def;
2049 const char* cmMakefile::GetSafeDefinition(const char* def) const
2051 const char* ret = this->GetDefinition(def);
2052 if(!ret)
2054 return "";
2056 return ret;
2059 std::vector<std::string> cmMakefile
2060 ::GetDefinitions(int cacheonly /* = 0 */) const
2062 std::map<cmStdString, int> definitions;
2063 if ( !cacheonly )
2065 DefinitionMap::const_iterator it;
2066 for ( it = this->DefinitionStack.back().begin();
2067 it != this->DefinitionStack.back().end(); it ++ )
2069 definitions[it->first] = 1;
2072 cmCacheManager::CacheIterator cit =
2073 this->GetCacheManager()->GetCacheIterator();
2074 for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
2076 definitions[cit.GetName()] = 1;
2079 std::vector<std::string> res;
2081 std::map<cmStdString, int>::iterator fit;
2082 for ( fit = definitions.begin(); fit != definitions.end(); fit ++ )
2084 res.push_back(fit->first);
2086 return res;
2090 const char *cmMakefile::ExpandVariablesInString(std::string& source)
2092 return this->ExpandVariablesInString(source, false, false);
2095 const char *cmMakefile::ExpandVariablesInString(std::string& source,
2096 bool escapeQuotes,
2097 bool noEscapes,
2098 bool atOnly,
2099 const char* filename,
2100 long line,
2101 bool removeEmpty,
2102 bool replaceAt)
2104 if ( source.empty() || source.find_first_of("$@\\") == source.npos)
2106 return source.c_str();
2109 // Special-case the @ONLY mode.
2110 if(atOnly)
2112 if(!noEscapes || !removeEmpty || !replaceAt)
2114 // This case should never be called. At-only is for
2115 // configure-file/string which always does no escapes.
2116 this->IssueMessage(cmake::INTERNAL_ERROR,
2117 "ExpandVariablesInString @ONLY called "
2118 "on something with escapes.");
2121 // Store an original copy of the input.
2122 std::string input = source;
2124 // Start with empty output.
2125 source = "";
2127 // Look for one @VAR@ at a time.
2128 const char* in = input.c_str();
2129 while(this->cmAtVarRegex.find(in))
2131 // Get the range of the string to replace.
2132 const char* first = in + this->cmAtVarRegex.start();
2133 const char* last = in + this->cmAtVarRegex.end();
2135 // Store the unchanged part of the string now.
2136 source.append(in, first-in);
2138 // Lookup the definition of VAR.
2139 std::string var(first+1, last-first-2);
2140 if(const char* val = this->GetDefinition(var.c_str()))
2142 // Store the value in the output escaping as requested.
2143 if(escapeQuotes)
2145 source.append(cmSystemTools::EscapeQuotes(val));
2147 else
2149 source.append(val);
2153 // Continue looking for @VAR@ further along the string.
2154 in = last;
2157 // Append the rest of the unchanged part of the string.
2158 source.append(in);
2160 return source.c_str();
2163 // This method replaces ${VAR} and @VAR@ where VAR is looked up
2164 // with GetDefinition(), if not found in the map, nothing is expanded.
2165 // It also supports the $ENV{VAR} syntax where VAR is looked up in
2166 // the current environment variables.
2168 cmCommandArgumentParserHelper parser;
2169 parser.SetMakefile(this);
2170 parser.SetLineFile(line, filename);
2171 parser.SetEscapeQuotes(escapeQuotes);
2172 parser.SetNoEscapeMode(noEscapes);
2173 parser.SetReplaceAtSyntax(replaceAt);
2174 parser.SetRemoveEmpty(removeEmpty);
2175 int res = parser.ParseString(source.c_str(), 0);
2176 const char* emsg = parser.GetError();
2177 if ( res && !emsg[0] )
2179 source = parser.GetResult();
2181 else
2183 // Construct the main error message.
2184 cmOStringStream error;
2185 error << "Syntax error in cmake code ";
2186 if(filename && line > 0)
2188 // This filename and line number may be more specific than the
2189 // command context because one command invocation can have
2190 // arguments on multiple lines.
2191 error << "at\n"
2192 << " " << filename << ":" << line << "\n";
2194 error << "when parsing string\n"
2195 << " " << source.c_str() << "\n";
2196 error << emsg;
2198 // If the parser failed ("res" is false) then this is a real
2199 // argument parsing error, so the policy applies. Otherwise the
2200 // parser reported an error message without failing because the
2201 // helper implementation is unhappy, which has always reported an
2202 // error.
2203 cmake::MessageType mtype = cmake::FATAL_ERROR;
2204 if(!res)
2206 // This is a real argument parsing error. Use policy CMP0010 to
2207 // decide whether it is an error.
2208 switch(this->GetPolicyStatus(cmPolicies::CMP0010))
2210 case cmPolicies::WARN:
2211 error << "\n"
2212 << (this->GetPolicies()
2213 ->GetPolicyWarning(cmPolicies::CMP0010));
2214 case cmPolicies::OLD:
2215 // OLD behavior is to just warn and continue.
2216 mtype = cmake::AUTHOR_WARNING;
2217 break;
2218 case cmPolicies::REQUIRED_IF_USED:
2219 case cmPolicies::REQUIRED_ALWAYS:
2220 error << "\n"
2221 << (this->GetPolicies()
2222 ->GetRequiredPolicyError(cmPolicies::CMP0010));
2223 case cmPolicies::NEW:
2224 // NEW behavior is to report the error.
2225 cmSystemTools::SetFatalErrorOccured();
2226 break;
2229 this->IssueMessage(mtype, error.str());
2231 return source.c_str();
2234 void cmMakefile::RemoveVariablesInString(std::string& source,
2235 bool atOnly) const
2237 if(!atOnly)
2239 cmsys::RegularExpression var("(\\${[A-Za-z_0-9]*})");
2240 while (var.find(source))
2242 source.erase(var.start(),var.end() - var.start());
2246 if(!atOnly)
2248 cmsys::RegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
2249 while (varb.find(source))
2251 source.erase(varb.start(),varb.end() - varb.start());
2254 cmsys::RegularExpression var2("(@[A-Za-z_0-9]*@)");
2255 while (var2.find(source))
2257 source.erase(var2.start(),var2.end() - var2.start());
2262 * Add the default definitions to the makefile. These values must not
2263 * be dependent on anything that isn't known when this cmMakefile instance
2264 * is constructed.
2266 void cmMakefile::AddDefaultDefinitions()
2268 /* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set.
2269 With CMake must separate between target and host platform. In most cases
2270 the tests for WIN32, UNIX and APPLE will be for the target system, so an
2271 additional set of variables for the host system is required ->
2272 CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE.
2273 WIN32, UNIX and APPLE are now set in the platform files in
2274 Modules/Platforms/.
2275 To keep cmake scripts (-P) and custom language and compiler modules
2276 working, these variables are still also set here in this place, but they
2277 will be reset in CMakeSystemSpecificInformation.cmake before the platform
2278 files are executed. */
2279 #if defined(_WIN32) || defined(__CYGWIN__)
2280 this->AddDefinition("WIN32", "1");
2281 this->AddDefinition("CMAKE_HOST_WIN32", "1");
2282 #else
2283 this->AddDefinition("UNIX", "1");
2284 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2285 #endif
2286 // Cygwin is more like unix so enable the unix commands
2287 #if defined(__CYGWIN__)
2288 this->AddDefinition("UNIX", "1");
2289 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2290 #endif
2291 #if defined(__APPLE__)
2292 this->AddDefinition("APPLE", "1");
2293 this->AddDefinition("CMAKE_HOST_APPLE", "1");
2294 #endif
2296 char temp[1024];
2297 sprintf(temp, "%d", cmVersion::GetMinorVersion());
2298 this->AddDefinition("CMAKE_MINOR_VERSION", temp);
2299 sprintf(temp, "%d", cmVersion::GetMajorVersion());
2300 this->AddDefinition("CMAKE_MAJOR_VERSION", temp);
2301 sprintf(temp, "%d", cmVersion::GetPatchVersion());
2302 this->AddDefinition("CMAKE_PATCH_VERSION", temp);
2304 this->AddDefinition("CMAKE_FILES_DIRECTORY",
2305 cmake::GetCMakeFilesDirectory());
2308 #if defined(CMAKE_BUILD_WITH_CMAKE)
2310 * Find a source group whose regular expression matches the filename
2311 * part of the given source name. Search backward through the list of
2312 * source groups, and take the first matching group found. This way
2313 * non-inherited SOURCE_GROUP commands will have precedence over
2314 * inherited ones.
2316 cmSourceGroup&
2317 cmMakefile::FindSourceGroup(const char* source,
2318 std::vector<cmSourceGroup> &groups)
2320 // First search for a group that lists the file explicitly.
2321 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2322 sg != groups.rend(); ++sg)
2324 cmSourceGroup *result = sg->MatchChildrenFiles(source);
2325 if(result)
2327 return *result;
2331 // Now search for a group whose regex matches the file.
2332 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2333 sg != groups.rend(); ++sg)
2335 cmSourceGroup *result = sg->MatchChildrenRegex(source);
2336 if(result)
2338 return *result;
2343 // Shouldn't get here, but just in case, return the default group.
2344 return groups.front();
2346 #endif
2348 bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
2349 cmExecutionStatus &status)
2351 // if there are no blockers get out of here
2352 if (this->FunctionBlockers.begin() == this->FunctionBlockers.end())
2354 return false;
2357 // loop over all function blockers to see if any block this command
2358 // evaluate in reverse, this is critical for balanced IF statements etc
2359 std::list<cmFunctionBlocker *>::reverse_iterator pos;
2360 for (pos = this->FunctionBlockers.rbegin();
2361 pos != this->FunctionBlockers.rend(); ++pos)
2363 if((*pos)->IsFunctionBlocked(lff, *this, status))
2365 return true;
2369 return false;
2372 bool cmMakefile::ExpandArguments(
2373 std::vector<cmListFileArgument> const& inArgs,
2374 std::vector<std::string>& outArgs)
2376 std::vector<cmListFileArgument>::const_iterator i;
2377 std::string value;
2378 outArgs.reserve(inArgs.size());
2379 for(i = inArgs.begin(); i != inArgs.end(); ++i)
2381 // Expand the variables in the argument.
2382 value = i->Value;
2383 this->ExpandVariablesInString(value, false, false, false,
2384 i->FilePath, i->Line,
2385 false, true);
2387 // If the argument is quoted, it should be one argument.
2388 // Otherwise, it may be a list of arguments.
2389 if(i->Quoted)
2391 outArgs.push_back(value);
2393 else
2395 cmSystemTools::ExpandListArgument(value, outArgs);
2398 return !cmSystemTools::GetFatalErrorOccured();
2401 void cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
2403 // loop over all function blockers to see if any block this command
2404 std::list<cmFunctionBlocker *>::reverse_iterator pos;
2405 for (pos = this->FunctionBlockers.rbegin();
2406 pos != this->FunctionBlockers.rend(); ++pos)
2408 if ((*pos)->ShouldRemove(lff, *this))
2410 cmFunctionBlocker* b = *pos;
2411 this->FunctionBlockers.remove(b);
2412 delete b;
2413 break;
2417 return;
2420 void cmMakefile::SetHomeDirectory(const char* dir)
2422 this->cmHomeDirectory = dir;
2423 cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
2424 this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
2425 if ( !this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR") )
2427 this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", this->GetHomeDirectory());
2431 void cmMakefile::SetHomeOutputDirectory(const char* lib)
2433 this->HomeOutputDirectory = lib;
2434 cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
2435 this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
2436 if ( !this->GetDefinition("CMAKE_CURRENT_BINARY_DIR") )
2438 this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
2439 this->GetHomeOutputDirectory());
2445 * Register the given cmData instance with its own name.
2447 void cmMakefile::RegisterData(cmData* data)
2449 std::string name = data->GetName();
2450 DataMapType::const_iterator d = this->DataMap.find(name);
2451 if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
2453 delete d->second;
2455 this->DataMap[name] = data;
2460 * Register the given cmData instance with the given name. This can be used
2461 * to register a NULL pointer.
2463 void cmMakefile::RegisterData(const char* name, cmData* data)
2465 DataMapType::const_iterator d = this->DataMap.find(name);
2466 if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
2468 delete d->second;
2470 this->DataMap[name] = data;
2475 * Lookup a cmData instance previously registered with the given name. If
2476 * the instance cannot be found, return NULL.
2478 cmData* cmMakefile::LookupData(const char* name) const
2480 DataMapType::const_iterator d = this->DataMap.find(name);
2481 if(d != this->DataMap.end())
2483 return d->second;
2485 else
2487 return 0;
2491 //----------------------------------------------------------------------------
2492 cmSourceFile* cmMakefile::GetSource(const char* sourceName)
2494 cmSourceFileLocation sfl(this, sourceName);
2495 for(std::vector<cmSourceFile*>::const_iterator
2496 sfi = this->SourceFiles.begin();
2497 sfi != this->SourceFiles.end(); ++sfi)
2499 cmSourceFile* sf = *sfi;
2500 if(sf->Matches(sfl))
2502 return sf;
2505 return 0;
2508 //----------------------------------------------------------------------------
2509 cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
2510 bool generated)
2512 if(cmSourceFile* esf = this->GetSource(sourceName))
2514 return esf;
2516 else
2518 cmSourceFile* sf = new cmSourceFile(this, sourceName);
2519 if(generated)
2521 sf->SetProperty("GENERATED", "1");
2523 this->SourceFiles.push_back(sf);
2524 return sf;
2528 void cmMakefile::EnableLanguage(std::vector<std::string> const & lang,
2529 bool optional)
2531 this->AddDefinition("CMAKE_CFG_INTDIR",
2532 this->LocalGenerator->GetGlobalGenerator()->GetCMakeCFGInitDirectory());
2533 this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this,
2534 optional);
2537 void cmMakefile::ExpandSourceListArguments(
2538 std::vector<std::string> const& arguments,
2539 std::vector<std::string>& newargs, unsigned int /* start */)
2541 // now expand the args
2542 unsigned int i;
2543 for(i = 0; i < arguments.size(); ++i)
2545 // List expansion will have been done already.
2546 newargs.push_back(arguments[i]);
2550 int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
2551 const char *projectName, const char *targetName,
2552 const std::vector<std::string> *cmakeArgs,
2553 std::string *output)
2555 // does the binary directory exist ? If not create it...
2556 if (!cmSystemTools::FileIsDirectory(bindir))
2558 cmSystemTools::MakeDirectory(bindir);
2561 // change to the tests directory and run cmake
2562 // use the cmake object instead of calling cmake
2563 std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
2564 cmSystemTools::ChangeDirectory(bindir);
2566 // make sure the same generator is used
2567 // use this program as the cmake to be run, it should not
2568 // be run that way but the cmake object requires a vailid path
2569 std::string cmakeCommand = this->GetDefinition("CMAKE_COMMAND");
2570 cmake cm;
2571 cm.SetIsInTryCompile(true);
2572 cmGlobalGenerator *gg = cm.CreateGlobalGenerator
2573 (this->LocalGenerator->GetGlobalGenerator()->GetName());
2574 if (!gg)
2576 cmSystemTools::Error(
2577 "Internal CMake error, TryCompile bad GlobalGenerator");
2578 // return to the original directory
2579 cmSystemTools::ChangeDirectory(cwd.c_str());
2580 return 1;
2582 cm.SetGlobalGenerator(gg);
2584 // do a configure
2585 cm.SetHomeDirectory(srcdir);
2586 cm.SetHomeOutputDirectory(bindir);
2587 cm.SetStartDirectory(srcdir);
2588 cm.SetStartOutputDirectory(bindir);
2589 cm.SetCMakeCommand(cmakeCommand.c_str());
2590 cm.LoadCache();
2591 // if cmake args were provided then pass them in
2592 if (cmakeArgs)
2594 cm.SetCacheArgs(*cmakeArgs);
2596 // to save time we pass the EnableLanguage info directly
2597 gg->EnableLanguagesFromGenerator
2598 (this->LocalGenerator->GetGlobalGenerator());
2599 if(this->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"))
2601 cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
2602 "TRUE", "", cmCacheManager::INTERNAL);
2604 else
2606 cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
2607 "FALSE", "", cmCacheManager::INTERNAL);
2609 if (cm.Configure() != 0)
2611 cmSystemTools::Error(
2612 "Internal CMake error, TryCompile configure of cmake failed");
2613 // return to the original directory
2614 cmSystemTools::ChangeDirectory(cwd.c_str());
2615 return 1;
2618 if (cm.Generate() != 0)
2620 cmSystemTools::Error(
2621 "Internal CMake error, TryCompile generation of cmake failed");
2622 // return to the original directory
2623 cmSystemTools::ChangeDirectory(cwd.c_str());
2624 return 1;
2627 // finally call the generator to actually build the resulting project
2628 int ret =
2629 this->LocalGenerator->GetGlobalGenerator()->TryCompile(srcdir,bindir,
2630 projectName,
2631 targetName,
2632 output,
2633 this);
2635 cmSystemTools::ChangeDirectory(cwd.c_str());
2636 return ret;
2639 cmake *cmMakefile::GetCMakeInstance() const
2641 if ( this->LocalGenerator && this->LocalGenerator->GetGlobalGenerator() )
2643 return this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
2645 return 0;
2648 #ifdef CMAKE_BUILD_WITH_CMAKE
2649 cmVariableWatch *cmMakefile::GetVariableWatch() const
2651 if ( this->GetCMakeInstance() &&
2652 this->GetCMakeInstance()->GetVariableWatch() )
2654 return this->GetCMakeInstance()->GetVariableWatch();
2656 return 0;
2658 #endif
2660 void cmMakefile::AddMacro(const char* name, const char* signature)
2662 if ( !name || !signature )
2664 return;
2666 this->MacrosMap[name] = signature;
2669 void cmMakefile::GetListOfMacros(std::string& macros)
2671 StringStringMap::iterator it;
2672 macros = "";
2673 int cc = 0;
2674 for ( it = this->MacrosMap.begin(); it != this->MacrosMap.end(); ++it )
2676 if ( cc > 0 )
2678 macros += ";";
2680 macros += it->first;
2681 cc ++;
2685 cmCacheManager *cmMakefile::GetCacheManager() const
2687 return this->GetCMakeInstance()->GetCacheManager();
2690 void cmMakefile::DisplayStatus(const char* message, float s)
2692 this->GetLocalGenerator()->GetGlobalGenerator()
2693 ->GetCMakeInstance()->UpdateProgress(message, s);
2696 std::string cmMakefile::GetModulesFile(const char* filename)
2698 std::vector<std::string> modulePath;
2699 const char* def = this->GetDefinition("CMAKE_MODULE_PATH");
2700 if(def)
2702 cmSystemTools::ExpandListArgument(def, modulePath);
2705 // Also search in the standard modules location.
2706 def = this->GetDefinition("CMAKE_ROOT");
2707 if(def)
2709 std::string rootModules = def;
2710 rootModules += "/Modules";
2711 modulePath.push_back(rootModules);
2713 //std::string Look through the possible module directories.
2714 for(std::vector<std::string>::iterator i = modulePath.begin();
2715 i != modulePath.end(); ++i)
2717 std::string itempl = *i;
2718 cmSystemTools::ConvertToUnixSlashes(itempl);
2719 itempl += "/";
2720 itempl += filename;
2721 if(cmSystemTools::FileExists(itempl.c_str()))
2723 return itempl;
2726 return "";
2729 void cmMakefile::ConfigureString(const std::string& input,
2730 std::string& output, bool atOnly,
2731 bool escapeQuotes)
2733 // Split input to handle one line at a time.
2734 std::string::const_iterator lineStart = input.begin();
2735 while(lineStart != input.end())
2737 // Find the end of this line.
2738 std::string::const_iterator lineEnd = lineStart;
2739 while(lineEnd != input.end() && *lineEnd != '\n')
2741 ++lineEnd;
2744 // Copy the line.
2745 std::string line(lineStart, lineEnd);
2747 // Skip the newline character.
2748 bool haveNewline = (lineEnd != input.end());
2749 if(haveNewline)
2751 ++lineEnd;
2754 // Replace #cmakedefine instances.
2755 if(this->cmDefineRegex.find(line))
2757 const char* def =
2758 this->GetDefinition(this->cmDefineRegex.match(1).c_str());
2759 if(!cmSystemTools::IsOff(def))
2761 cmSystemTools::ReplaceString(line, "#cmakedefine", "#define");
2762 output += line;
2764 else
2766 output += "/* #undef ";
2767 output += this->cmDefineRegex.match(1);
2768 output += " */";
2771 else if(this->cmDefine01Regex.find(line))
2773 const char* def =
2774 this->GetDefinition(this->cmDefine01Regex.match(1).c_str());
2775 cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define");
2776 output += line;
2777 if(!cmSystemTools::IsOff(def))
2779 output += " 1";
2781 else
2783 output += " 0";
2786 else
2788 output += line;
2791 if(haveNewline)
2793 output += "\n";
2796 // Move to the next line.
2797 lineStart = lineEnd;
2800 // Perform variable replacements.
2801 this->ExpandVariablesInString(output, escapeQuotes, true,
2802 atOnly, 0, -1, true);
2805 int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
2806 bool copyonly, bool atOnly, bool escapeQuotes)
2808 int res = 1;
2809 if ( !this->CanIWriteThisFile(outfile) )
2811 cmSystemTools::Error("Attempt to write file: ",
2812 outfile, " into a source directory.");
2813 return 0;
2815 if ( !cmSystemTools::FileExists(infile) )
2817 cmSystemTools::Error("File ", infile, " does not exist.");
2818 return 0;
2820 std::string soutfile = outfile;
2821 std::string sinfile = infile;
2822 this->AddCMakeDependFile(infile);
2823 cmSystemTools::ConvertToUnixSlashes(soutfile);
2824 mode_t perm = 0;
2825 cmSystemTools::GetPermissions(sinfile.c_str(), perm);
2826 std::string::size_type pos = soutfile.rfind('/');
2827 if(pos != std::string::npos)
2829 std::string path = soutfile.substr(0, pos);
2830 cmSystemTools::MakeDirectory(path.c_str());
2833 if(copyonly)
2835 if ( !cmSystemTools::CopyFileIfDifferent(sinfile.c_str(),
2836 soutfile.c_str()))
2838 return 0;
2841 else
2843 std::string tempOutputFile = soutfile;
2844 tempOutputFile += ".tmp";
2845 std::ofstream fout(tempOutputFile.c_str());
2846 if(!fout)
2848 cmSystemTools::Error(
2849 "Could not open file for write in copy operation ",
2850 tempOutputFile.c_str());
2851 cmSystemTools::ReportLastSystemError("");
2852 return 0;
2854 std::ifstream fin(sinfile.c_str());
2855 if(!fin)
2857 cmSystemTools::Error("Could not open file for read in copy operation ",
2858 sinfile.c_str());
2859 return 0;
2862 // now copy input to output and expand variables in the
2863 // input file at the same time
2864 std::string inLine;
2865 std::string outLine;
2866 while( cmSystemTools::GetLineFromStream(fin, inLine) )
2868 outLine = "";
2869 this->ConfigureString(inLine, outLine, atOnly, escapeQuotes);
2870 fout << outLine.c_str() << "\n";
2872 // close the files before attempting to copy
2873 fin.close();
2874 fout.close();
2875 if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
2876 soutfile.c_str()) )
2878 res = 0;
2880 else
2882 cmSystemTools::SetPermissions(soutfile.c_str(), perm);
2884 cmSystemTools::RemoveFile(tempOutputFile.c_str());
2886 return res;
2889 void cmMakefile::SetProperty(const char* prop, const char* value)
2891 if (!prop)
2893 return;
2896 // handle special props
2897 std::string propname = prop;
2898 if ( propname == "INCLUDE_DIRECTORIES" )
2900 std::vector<std::string> varArgsExpanded;
2901 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2902 this->SetIncludeDirectories(varArgsExpanded);
2903 return;
2906 if ( propname == "LINK_DIRECTORIES" )
2908 std::vector<std::string> varArgsExpanded;
2909 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2910 this->SetLinkDirectories(varArgsExpanded);
2911 return;
2914 if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
2916 this->SetIncludeRegularExpression(value);
2917 return;
2920 if ( propname == "ADDITIONAL_MAKE_CLEAN_FILES" )
2922 // This property is not inherrited
2923 if ( strcmp(this->GetCurrentDirectory(),
2924 this->GetStartDirectory()) != 0 )
2926 return;
2930 this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
2933 void cmMakefile::AppendProperty(const char* prop, const char* value)
2935 if (!prop)
2937 return;
2940 // handle special props
2941 std::string propname = prop;
2942 if ( propname == "INCLUDE_DIRECTORIES" )
2944 std::vector<std::string> varArgsExpanded;
2945 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2946 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
2947 vi != varArgsExpanded.end(); ++vi)
2949 this->AddIncludeDirectory(vi->c_str());
2951 return;
2954 if ( propname == "LINK_DIRECTORIES" )
2956 std::vector<std::string> varArgsExpanded;
2957 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2958 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
2959 vi != varArgsExpanded.end(); ++vi)
2961 this->AddLinkDirectory(vi->c_str());
2963 return;
2966 this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY);
2969 const char *cmMakefile::GetPropertyOrDefinition(const char* prop)
2971 const char *ret = this->GetProperty(prop, cmProperty::DIRECTORY);
2972 if (!ret)
2974 ret = this->GetDefinition(prop);
2976 return ret;
2979 const char *cmMakefile::GetProperty(const char* prop)
2981 return this->GetProperty(prop, cmProperty::DIRECTORY);
2984 const char *cmMakefile::GetProperty(const char* prop,
2985 cmProperty::ScopeType scope)
2987 // watch for specific properties
2988 static std::string output;
2989 output = "";
2990 if (!strcmp("PARENT_DIRECTORY",prop))
2992 if(cmLocalGenerator* plg = this->LocalGenerator->GetParent())
2994 output = plg->GetMakefile()->GetStartDirectory();
2996 return output.c_str();
2998 else if (!strcmp("INCLUDE_REGULAR_EXPRESSION",prop) )
3000 output = this->GetIncludeRegularExpression();
3001 return output.c_str();
3003 else if (!strcmp("LISTFILE_STACK",prop))
3005 for (std::deque<cmStdString>::iterator i = this->ListFileStack.begin();
3006 i != this->ListFileStack.end(); ++i)
3008 if (i != this->ListFileStack.begin())
3010 output += ";";
3012 output += *i;
3014 return output.c_str();
3016 else if (!strcmp("VARIABLES",prop) || !strcmp("CACHE_VARIABLES",prop))
3018 int cacheonly = 0;
3019 if ( !strcmp("CACHE_VARIABLES",prop) )
3021 cacheonly = 1;
3023 std::vector<std::string> vars = this->GetDefinitions(cacheonly);
3024 for (unsigned int cc = 0; cc < vars.size(); cc ++ )
3026 if ( cc > 0 )
3028 output += ";";
3030 output += vars[cc];
3032 return output.c_str();
3034 else if (!strcmp("MACROS",prop))
3036 this->GetListOfMacros(output);
3037 return output.c_str();
3039 else if (!strcmp("DEFINITIONS",prop))
3041 output += this->DefineFlagsOrig;
3042 return output.c_str();
3044 else if (!strcmp("INCLUDE_DIRECTORIES",prop) )
3046 cmOStringStream str;
3047 for (std::vector<std::string>::const_iterator
3048 it = this->GetIncludeDirectories().begin();
3049 it != this->GetIncludeDirectories().end();
3050 ++ it )
3052 if ( it != this->GetIncludeDirectories().begin())
3054 str << ";";
3056 str << it->c_str();
3058 output = str.str();
3059 return output.c_str();
3061 else if (!strcmp("LINK_DIRECTORIES",prop))
3063 cmOStringStream str;
3064 for (std::vector<std::string>::const_iterator
3065 it = this->GetLinkDirectories().begin();
3066 it != this->GetLinkDirectories().end();
3067 ++ it )
3069 if ( it != this->GetLinkDirectories().begin())
3071 str << ";";
3073 str << it->c_str();
3075 output = str.str();
3076 return output.c_str();
3079 bool chain = false;
3080 const char *retVal =
3081 this->Properties.GetPropertyValue(prop, scope, chain);
3082 if (chain)
3084 if(this->LocalGenerator->GetParent())
3086 return this->LocalGenerator->GetParent()->GetMakefile()->
3087 GetProperty(prop, scope);
3089 return this->GetCMakeInstance()->GetProperty(prop,scope);
3092 return retVal;
3095 bool cmMakefile::GetPropertyAsBool(const char* prop)
3097 return cmSystemTools::IsOn(this->GetProperty(prop));
3101 cmTarget* cmMakefile::FindTarget(const char* name)
3103 cmTargets& tgts = this->GetTargets();
3105 cmTargets::iterator i = tgts.find ( name );
3106 if ( i != tgts.end() )
3108 return &i->second;
3111 return 0;
3114 cmTest* cmMakefile::CreateTest(const char* testName)
3116 if ( !testName )
3118 return 0;
3120 cmTest* test = this->GetTest(testName);
3121 if ( test )
3123 return test;
3125 test = new cmTest;
3126 test->SetName(testName);
3127 test->SetMakefile(this);
3128 this->Tests.push_back(test);
3129 return test;
3132 cmTest* cmMakefile::GetTest(const char* testName) const
3134 if ( !testName )
3136 return 0;
3138 std::vector<cmTest*>::const_iterator it;
3139 for ( it = this->Tests.begin(); it != this->Tests.end(); ++ it )
3141 if ( strcmp((*it)->GetName(), testName) == 0 )
3143 return *it;
3146 return 0;
3149 const std::vector<cmTest*> *cmMakefile::GetTests() const
3151 return &this->Tests;
3154 std::vector<cmTest*> *cmMakefile::GetTests()
3156 return &this->Tests;
3159 std::string cmMakefile::GetListFileStack()
3161 cmOStringStream tmp;
3162 size_t depth = this->ListFileStack.size();
3163 if (depth > 0)
3165 std::deque<cmStdString>::iterator it = this->ListFileStack.end();
3168 if (depth != this->ListFileStack.size())
3170 tmp << "\n ";
3172 --it;
3173 tmp << "[";
3174 tmp << depth;
3175 tmp << "]\t";
3176 tmp << *it;
3177 depth--;
3179 while (it != this->ListFileStack.begin());
3181 return tmp.str();
3185 void cmMakefile::PushScope()
3187 // Get the index of the next stack entry.
3188 std::vector<DefinitionMap>::size_type index = this->DefinitionStack.size();
3190 // Allocate a new stack entry.
3191 this->DefinitionStack.push_back(DefinitionMap());
3193 // Copy the previous top to the new top.
3194 this->DefinitionStack[index] = this->DefinitionStack[index-1];
3197 void cmMakefile::PopScope()
3199 this->DefinitionStack.pop_back();
3202 void cmMakefile::RaiseScope(const char *var, const char *varDef)
3204 if (!var || !strlen(var))
3206 return;
3209 // multiple scopes in this directory?
3210 if (this->DefinitionStack.size() > 1)
3212 if(varDef)
3214 this->DefinitionStack[this->DefinitionStack.size()-2][var] = varDef;
3216 else
3218 this->DefinitionStack[this->DefinitionStack.size()-2].erase(var);
3221 // otherwise do the parent (if one exists)
3222 else if (this->LocalGenerator->GetParent())
3224 cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
3225 if (parent)
3227 if(varDef)
3229 parent->AddDefinition(var,varDef);
3231 else
3233 parent->RemoveDefinition(var);
3240 // define properties
3241 void cmMakefile::DefineProperties(cmake *cm)
3243 cm->DefineProperty
3244 ("ADDITIONAL_MAKE_CLEAN_FILES", cmProperty::DIRECTORY,
3245 "Additional files to clean during the make clean stage.",
3246 "A list of files that will be cleaned as a part of the "
3247 "\"make clean\" stage. ");
3249 cm->DefineProperty
3250 ("CLEAN_NO_CUSTOM", cmProperty::DIRECTORY,
3251 "Should the output of custom commands be left.",
3252 "If this is true then the outputs of custom commands for this "
3253 "directory will not be removed during the \"make clean\" stage. ");
3255 cm->DefineProperty
3256 ("LISTFILE_STACK", cmProperty::DIRECTORY,
3257 "The current stack of listfiles being processed.",
3258 "This property is mainly useful when trying to debug errors "
3259 "in your CMake scripts. It returns a list of what list files "
3260 "are currently being processed, in order. So if one listfile "
3261 "does an INCLUDE command then that is effectively pushing "
3262 "the included listfile onto the stack.", false);
3264 cm->DefineProperty
3265 ("TEST_INCLUDE_FILE", cmProperty::DIRECTORY,
3266 "A cmake file that will be included when ctest is run.",
3267 "If you specify TEST_INCLUDE_FILE, that file will be "
3268 "included and processed when ctest is run on the directory.");
3270 cm->DefineProperty
3271 ("COMPILE_DEFINITIONS", cmProperty::DIRECTORY,
3272 "Preprocessor definitions for compiling a directory's sources.",
3273 "The COMPILE_DEFINITIONS property may be set to a list of preprocessor "
3274 "definitions using the syntax VAR or VAR=value. Function-style "
3275 "definitions are not supported. CMake will automatically escape "
3276 "the value correctly for the native build system (note that CMake "
3277 "language syntax may require escapes to specify some values). "
3278 "This property may be set on a per-configuration basis using the name "
3279 "COMPILE_DEFINITIONS_<CONFIG> where <CONFIG> is an upper-case name "
3280 "(ex. \"COMPILE_DEFINITIONS_DEBUG\"). "
3281 "This property will be initialized in each directory by its value "
3282 "in the directory's parent.\n"
3283 "CMake will automatically drop some definitions that "
3284 "are not supported by the native build tool. "
3285 "The VS6 IDE does not support definitions with values "
3286 "(but NMake does).\n"
3287 "Dislaimer: Most native build tools have poor support for escaping "
3288 "certain values. CMake has work-arounds for many cases but some "
3289 "values may just not be possible to pass correctly. If a value "
3290 "does not seem to be escaped correctly, do not attempt to "
3291 "work-around the problem by adding escape sequences to the value. "
3292 "Your work-around may break in a future version of CMake that "
3293 "has improved escape support. Instead consider defining the macro "
3294 "in a (configured) header file. Then report the limitation.");
3296 cm->DefineProperty
3297 ("COMPILE_DEFINITIONS_<CONFIG>", cmProperty::DIRECTORY,
3298 "Per-configuration preprocessor definitions in a directory.",
3299 "This is the configuration-specific version of COMPILE_DEFINITIONS. "
3300 "This property will be initialized in each directory by its value "
3301 "in the directory's parent.\n");
3303 cm->DefineProperty
3304 ("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM", cmProperty::DIRECTORY,
3305 "Specify #include line transforms for dependencies in a directory.",
3306 "This property specifies rules to transform macro-like #include lines "
3307 "during implicit dependency scanning of C and C++ source files. "
3308 "The list of rules must be semicolon-separated with each entry of "
3309 "the form \"A_MACRO(%)=value-with-%\" (the % must be literal). "
3310 "During dependency scanning occurrences of A_MACRO(...) on #include "
3311 "lines will be replaced by the value given with the macro argument "
3312 "substituted for '%'. For example, the entry\n"
3313 " MYDIR(%)=<mydir/%>\n"
3314 "will convert lines of the form\n"
3315 " #include MYDIR(myheader.h)\n"
3316 "to\n"
3317 " #include <mydir/myheader.h>\n"
3318 "allowing the dependency to be followed.\n"
3319 "This property applies to sources in all targets within a directory. "
3320 "The property value is initialized in each directory by its value "
3321 "in the directory's parent.");
3323 cm->DefineProperty
3324 ("EXCLUDE_FROM_ALL", cmProperty::DIRECTORY,
3325 "Exclude the directory from the all target of its parent.",
3326 "A property on a directory that indicates if its targets are excluded "
3327 "from the default build target. If it is not, then with a Makefile "
3328 "for example typing make will cause the targets to be built. "
3329 "The same concept applies to the default build of other generators.",
3330 false);
3332 cm->DefineProperty
3333 ("PARENT_DIRECTORY", cmProperty::DIRECTORY,
3334 "Source directory that added current subdirectory.",
3335 "This read-only property specifies the source directory that "
3336 "added the current source directory as a subdirectory of the build. "
3337 "In the top-level directory the value is the empty-string.", false);
3339 cm->DefineProperty
3340 ("INCLUDE_REGULAR_EXPRESSION", cmProperty::DIRECTORY,
3341 "Include file scanning regular expression.",
3342 "This read-only property specifies the regular expression used "
3343 "during dependency scanning to match include files that should "
3344 "be followed. See the include_regular_expression command.", false);
3346 cm->DefineProperty
3347 ("VARIABLES", cmProperty::DIRECTORY,
3348 "List of variables defined in the current directory.",
3349 "This read-only property specifies the list of CMake variables "
3350 "currently defined. "
3351 "It is intended for debugging purposes.", false);
3353 cm->DefineProperty
3354 ("CACHE_VARIABLES", cmProperty::DIRECTORY,
3355 "List of cache variables available in the current directory.",
3356 "This read-only property specifies the list of CMake cache "
3357 "variables currently defined. "
3358 "It is intended for debugging purposes.", false);
3360 cm->DefineProperty
3361 ("MACROS", cmProperty::DIRECTORY,
3362 "List of macro commands available in the current directory.",
3363 "This read-only property specifies the list of CMake macros "
3364 "currently defined. "
3365 "It is intended for debugging purposes. "
3366 "See the macro command.", false);
3368 cm->DefineProperty
3369 ("DEFINITIONS", cmProperty::DIRECTORY,
3370 "For CMake 2.4 compatibility only. Use COMPILE_DEFINITIONS instead.",
3371 "This read-only property specifies the list of flags given so far "
3372 "to the add_definitions command. "
3373 "It is intended for debugging purposes. "
3374 "Use the COMPILE_DEFINITIONS instead.", false);
3376 cm->DefineProperty
3377 ("INCLUDE_DIRECTORIES", cmProperty::DIRECTORY,
3378 "List of preprocessor include file search directories.",
3379 "This read-only property specifies the list of directories given "
3380 "so far to the include_directories command. "
3381 "It is intended for debugging purposes.", false);
3383 cm->DefineProperty
3384 ("LINK_DIRECTORIES", cmProperty::DIRECTORY,
3385 "List of linker search directories.",
3386 "This read-only property specifies the list of directories given "
3387 "so far to the link_directories command. "
3388 "It is intended for debugging purposes.", false);
3391 //----------------------------------------------------------------------------
3392 cmTarget*
3393 cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type)
3395 // Create the target.
3396 cmsys::auto_ptr<cmTarget> target(new cmTarget);
3397 target->SetType(type, name);
3398 target->SetMakefile(this);
3399 target->MarkAsImported();
3401 // Add to the set of available imported targets.
3402 this->ImportedTargets[name] = target.get();
3404 // Transfer ownership to this cmMakefile object.
3405 this->ImportedTargetsOwned.push_back(target.get());
3406 return target.release();
3409 //----------------------------------------------------------------------------
3410 cmTarget* cmMakefile::FindTargetToUse(const char* name)
3412 // Look for an imported target. These take priority because they
3413 // are more local in scope and do not have to be globally unique.
3414 std::map<cmStdString, cmTarget*>::const_iterator
3415 imported = this->ImportedTargets.find(name);
3416 if(imported != this->ImportedTargets.end())
3418 return imported->second;
3421 // Look for a target built in this project.
3422 return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name);
3425 //----------------------------------------------------------------------------
3426 bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
3427 bool isCustom)
3429 if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
3431 // The name given conflicts with an existing target. Produce an
3432 // error in a compatible way.
3433 if(existing->IsImported())
3435 // Imported targets were not supported in previous versions.
3436 // This is new code, so we can make it an error.
3437 cmOStringStream e;
3438 e << "cannot create target \"" << name
3439 << "\" because an imported target with the same name already exists.";
3440 msg = e.str();
3441 return false;
3443 else
3445 // target names must be globally unique
3446 switch (this->GetPolicyStatus(cmPolicies::CMP0002))
3448 case cmPolicies::WARN:
3449 this->IssueMessage(cmake::AUTHOR_WARNING, this->GetPolicies()->
3450 GetPolicyWarning(cmPolicies::CMP0002));
3451 case cmPolicies::OLD:
3452 return true;
3453 case cmPolicies::REQUIRED_IF_USED:
3454 case cmPolicies::REQUIRED_ALWAYS:
3455 this->IssueMessage(cmake::FATAL_ERROR,
3456 this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0002)
3458 return true;
3459 case cmPolicies::NEW:
3460 break;
3463 // The conflict is with a non-imported target.
3464 // Allow this if the user has requested support.
3465 cmake* cm =
3466 this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
3467 if(isCustom && existing->GetType() == cmTarget::UTILITY &&
3468 this != existing->GetMakefile() &&
3469 cm->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
3471 return true;
3474 // Produce an error that tells the user how to work around the
3475 // problem.
3476 cmOStringStream e;
3477 e << "cannot create target \"" << name
3478 << "\" because another target with the same name already exists. "
3479 << "The existing target is ";
3480 switch(existing->GetType())
3482 case cmTarget::EXECUTABLE:
3483 e << "an executable ";
3484 break;
3485 case cmTarget::STATIC_LIBRARY:
3486 e << "a static library ";
3487 break;
3488 case cmTarget::SHARED_LIBRARY:
3489 e << "a shared library ";
3490 break;
3491 case cmTarget::MODULE_LIBRARY:
3492 e << "a module library ";
3493 break;
3494 case cmTarget::UTILITY:
3495 e << "a custom target ";
3496 break;
3497 default: break;
3499 e << "created in source directory \""
3500 << existing->GetMakefile()->GetCurrentDirectory() << "\". "
3501 << "See documentation for policy CMP0002 for more details.";
3502 msg = e.str();
3503 return false;
3506 return true;
3509 //----------------------------------------------------------------------------
3510 cmPolicies::PolicyStatus
3511 cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id)
3513 // Get the current setting of the policy.
3514 cmPolicies::PolicyStatus cur = this->GetPolicyStatusInternal(id);
3516 // If the policy is required to be set to NEW but is not, ignore the
3517 // current setting and tell the caller.
3518 if(cur != cmPolicies::NEW)
3520 if(cur == cmPolicies::REQUIRED_ALWAYS ||
3521 cur == cmPolicies::REQUIRED_IF_USED)
3523 return cur;
3525 cmPolicies::PolicyStatus def = this->GetPolicies()->GetPolicyStatus(id);
3526 if(def == cmPolicies::REQUIRED_ALWAYS ||
3527 def == cmPolicies::REQUIRED_IF_USED)
3529 return def;
3533 // The current setting is okay.
3534 return cur;
3537 //----------------------------------------------------------------------------
3538 cmPolicies::PolicyStatus
3539 cmMakefile::GetPolicyStatusInternal(cmPolicies::PolicyID id)
3541 // Is the policy set in our stack?
3542 for(std::vector<PolicyMap>::reverse_iterator
3543 psi = this->PolicyStack.rbegin();
3544 psi != this->PolicyStack.rend(); ++psi)
3546 PolicyMap::const_iterator pse = psi->find(id);
3547 if(pse != psi->end())
3549 return pse->second;
3553 // If we have a parent directory, recurse up to it.
3554 if(this->LocalGenerator->GetParent())
3556 cmMakefile* parent = this->LocalGenerator->GetParent()->GetMakefile();
3557 return parent->GetPolicyStatusInternal(id);
3560 // The policy is not set. Use the default for this CMake version.
3561 return this->GetPolicies()->GetPolicyStatus(id);
3564 bool cmMakefile::SetPolicy(const char *id,
3565 cmPolicies::PolicyStatus status)
3567 cmPolicies::PolicyID pid;
3568 if (!this->GetPolicies()->GetPolicyID(id, /* out */ pid))
3570 cmOStringStream e;
3571 e << "Policy \"" << id << "\" is not known to this version of CMake.";
3572 this->IssueMessage(cmake::FATAL_ERROR, e.str());
3573 return false;
3575 return this->SetPolicy(pid,status);
3578 //----------------------------------------------------------------------------
3579 bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
3580 cmPolicies::PolicyStatus status)
3582 // A REQUIRED_ALWAYS policy may be set only to NEW.
3583 if(status != cmPolicies::NEW &&
3584 this->GetPolicies()->GetPolicyStatus(id) ==
3585 cmPolicies::REQUIRED_ALWAYS)
3587 std::string msg =
3588 this->GetPolicies()->GetRequiredAlwaysPolicyError(id);
3589 this->IssueMessage(cmake::FATAL_ERROR, msg.c_str());
3590 return false;
3593 // Store the setting.
3594 this->PolicyStack.back()[id] = status;
3596 // Special hook for presenting compatibility variable as soon as
3597 // the user requests it.
3598 if(id == cmPolicies::CMP0001 &&
3599 (status == cmPolicies::WARN || status == cmPolicies::OLD))
3601 if(!(this->GetCacheManager()
3602 ->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
3604 // Set it to 2.4 because that is the last version where the
3605 // variable had meaning.
3606 this->AddCacheDefinition
3607 ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
3608 "For backwards compatibility, what version of CMake "
3609 "commands and "
3610 "syntax should this version of CMake try to support.",
3611 cmCacheManager::STRING);
3615 return true;
3618 bool cmMakefile::PushPolicy()
3620 // Allocate a new stack entry.
3621 this->PolicyStack.push_back(PolicyMap());
3622 return true;
3625 bool cmMakefile::PopPolicy(bool reportError)
3627 if(this->PolicyStack.size() == 1)
3629 if(reportError)
3631 cmSystemTools::Error("Attempt to pop the policy stack past "
3632 "it's beginning.");
3634 return false;
3636 this->PolicyStack.pop_back();
3637 return true;
3640 bool cmMakefile::SetPolicyVersion(const char *version)
3642 return this->GetCMakeInstance()->GetPolicies()->
3643 ApplyPolicyVersion(this,version);
3646 cmPolicies *cmMakefile::GetPolicies()
3648 if (!this->GetCMakeInstance())
3650 return 0;
3652 return this->GetCMakeInstance()->GetPolicies();