Resync. (Hmmm, somebody changed FindLua*.cmake.)
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmMakefile.cxx
blobd1282df5a4e27eab2636d5c9b437e62660e160f0
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmMakefile.cxx,v $
5 Language: C++
6 Date: $Date: 2008-03-10 19:41:07 $
7 Version: $Revision: 1.455 $
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 "cmDocumentationFormatterText.h"
40 #include <cmsys/RegularExpression.hxx>
42 #include <cmsys/auto_ptr.hxx>
44 #include <ctype.h> // for isspace
46 // default is not to be building executables
47 cmMakefile::cmMakefile()
49 this->DefinitionStack.push_back(DefinitionMap());
51 // Setup the default include file regular expression (match everything).
52 this->IncludeFileRegularExpression = "^.*$";
53 // Setup the default include complaint regular expression (match nothing).
54 this->ComplainFileRegularExpression = "^$";
55 // Source and header file extensions that we can handle
57 // Set up a list of source and header extensions
58 // these are used to find files when the extension
59 // is not given
60 // The "c" extension MUST precede the "C" extension.
61 this->SourceFileExtensions.push_back( "c" );
62 this->SourceFileExtensions.push_back( "C" );
64 this->SourceFileExtensions.push_back( "c++" );
65 this->SourceFileExtensions.push_back( "cc" );
66 this->SourceFileExtensions.push_back( "cpp" );
67 this->SourceFileExtensions.push_back( "cxx" );
68 this->SourceFileExtensions.push_back( "m" );
69 this->SourceFileExtensions.push_back( "M" );
70 this->SourceFileExtensions.push_back( "mm" );
72 this->HeaderFileExtensions.push_back( "h" );
73 this->HeaderFileExtensions.push_back( "hh" );
74 this->HeaderFileExtensions.push_back( "h++" );
75 this->HeaderFileExtensions.push_back( "hm" );
76 this->HeaderFileExtensions.push_back( "hpp" );
77 this->HeaderFileExtensions.push_back( "hxx" );
78 this->HeaderFileExtensions.push_back( "in" );
79 this->HeaderFileExtensions.push_back( "txx" );
81 this->DefineFlags = " ";
82 this->LocalGenerator = 0;
84 #if defined(CMAKE_BUILD_WITH_CMAKE)
85 this->AddSourceGroup("", "^.*$");
86 this->AddSourceGroup
87 ("Source Files",
88 "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat)$");
89 this->AddSourceGroup("Header Files",
90 "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
91 this->AddSourceGroup("CMake Rules", "\\.rule$");
92 this->AddSourceGroup("Resources", "\\.plist$");
93 #endif
94 this->AddDefaultDefinitions();
95 this->Initialize();
96 this->PreOrder = false;
99 cmMakefile::cmMakefile(const cmMakefile& mf)
101 this->Prefix = mf.Prefix;
102 this->AuxSourceDirectories = mf.AuxSourceDirectories;
103 this->cmStartDirectory = mf.cmStartDirectory;
104 this->StartOutputDirectory = mf.StartOutputDirectory;
105 this->cmHomeDirectory = mf.cmHomeDirectory;
106 this->HomeOutputDirectory = mf.HomeOutputDirectory;
107 this->cmCurrentListFile = mf.cmCurrentListFile;
108 this->ProjectName = mf.ProjectName;
109 this->Targets = mf.Targets;
110 this->SourceFiles = mf.SourceFiles;
111 this->Tests = mf.Tests;
112 this->IncludeDirectories = mf.IncludeDirectories;
113 this->LinkDirectories = mf.LinkDirectories;
114 this->SystemIncludeDirectories = mf.SystemIncludeDirectories;
115 this->ListFiles = mf.ListFiles;
116 this->OutputFiles = mf.OutputFiles;
117 this->LinkLibraries = mf.LinkLibraries;
118 this->InstallGenerators = mf.InstallGenerators;
119 this->IncludeFileRegularExpression = mf.IncludeFileRegularExpression;
120 this->ComplainFileRegularExpression = mf.ComplainFileRegularExpression;
121 this->SourceFileExtensions = mf.SourceFileExtensions;
122 this->HeaderFileExtensions = mf.HeaderFileExtensions;
123 this->DefineFlags = mf.DefineFlags;
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();
153 unsigned int cmMakefile::GetCacheMajorVersion()
155 return this->GetCacheManager()->GetCacheMajorVersion();
158 unsigned int cmMakefile::GetCacheMinorVersion()
160 return this->GetCacheManager()->GetCacheMinorVersion();
163 bool cmMakefile::NeedCacheCompatibility(int major, int minor)
165 return this->GetCacheManager()->NeedCacheCompatibility(major, minor);
168 cmMakefile::~cmMakefile()
170 for(std::vector<cmInstallGenerator*>::iterator
171 i = this->InstallGenerators.begin();
172 i != this->InstallGenerators.end(); ++i)
174 delete *i;
176 for(std::vector<cmSourceFile*>::iterator i = this->SourceFiles.begin();
177 i != this->SourceFiles.end(); ++i)
179 delete *i;
181 for(std::vector<cmTest*>::iterator i = this->Tests.begin();
182 i != this->Tests.end(); ++i)
184 delete *i;
186 for(std::vector<cmTarget*>::iterator
187 i = this->ImportedTargetsOwned.begin();
188 i != this->ImportedTargetsOwned.end(); ++i)
190 delete *i;
192 for(unsigned int i=0; i < this->UsedCommands.size(); i++)
194 delete this->UsedCommands[i];
196 for(DataMapType::const_iterator d = this->DataMap.begin();
197 d != this->DataMap.end(); ++d)
199 if(d->second)
201 delete d->second;
204 std::list<cmFunctionBlocker *>::iterator pos;
205 for (pos = this->FunctionBlockers.begin();
206 pos != this->FunctionBlockers.end(); ++pos)
208 cmFunctionBlocker* b = *pos;
209 delete b;
211 this->FunctionBlockers.clear();
212 if (this->PolicyStack.size() != 1)
214 cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
215 " popped properly");
219 void cmMakefile::PrintStringVector(const char* s,
220 const std::vector<std::string>& v) const
222 std::cout << s << ": ( \n";
223 for(std::vector<std::string>::const_iterator i = v.begin();
224 i != v.end(); ++i)
226 std::cout << (*i).c_str() << " ";
228 std::cout << " )\n";
231 void cmMakefile
232 ::PrintStringVector(const char* s,
233 const std::vector<std::pair<cmStdString, bool> >& v) const
235 std::cout << s << ": ( \n";
236 for(std::vector<std::pair<cmStdString, bool> >::const_iterator i
237 = v.begin(); i != v.end(); ++i)
239 std::cout << i->first.c_str() << " " << i->second;
241 std::cout << " )\n";
245 // call print on all the classes in the makefile
246 void cmMakefile::Print()
248 // print the class lists
249 std::cout << "classes:\n";
251 std::cout << " this->Targets: ";
252 for (cmTargets::iterator l = this->Targets.begin();
253 l != this->Targets.end(); l++)
255 std::cout << l->first << std::endl;
258 std::cout << " this->StartOutputDirectory; " <<
259 this->StartOutputDirectory.c_str() << std::endl;
260 std::cout << " this->HomeOutputDirectory; " <<
261 this->HomeOutputDirectory.c_str() << std::endl;
262 std::cout << " this->cmStartDirectory; " <<
263 this->cmStartDirectory.c_str() << std::endl;
264 std::cout << " this->cmHomeDirectory; " <<
265 this->cmHomeDirectory.c_str() << std::endl;
266 std::cout << " this->ProjectName; "
267 << this->ProjectName.c_str() << std::endl;
268 this->PrintStringVector("this->IncludeDirectories;",
269 this->IncludeDirectories);
270 this->PrintStringVector("this->LinkDirectories", this->LinkDirectories);
271 #if defined(CMAKE_BUILD_WITH_CMAKE)
272 for( std::vector<cmSourceGroup>::const_iterator i =
273 this->SourceGroups.begin(); i != this->SourceGroups.end(); ++i)
275 std::cout << "Source Group: " << i->GetName() << std::endl;
277 #endif
280 bool cmMakefile::CommandExists(const char* name) const
282 return this->GetCMakeInstance()->CommandExists(name);
285 //----------------------------------------------------------------------------
286 void cmMakefile::IssueError(std::string const& msg) const
288 this->IssueMessage(msg, true);
291 //----------------------------------------------------------------------------
292 void cmMakefile::IssueWarning(std::string const& msg) const
294 this->IssueMessage(msg, false);
297 //----------------------------------------------------------------------------
298 void cmMakefile::IssueMessage(std::string const& text, bool isError) const
300 cmOStringStream msg;
302 // Construct the message header.
303 if(isError)
305 msg << "CMake Error:";
307 else
309 msg << "CMake Warning:";
312 // Add the immediate context.
313 CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
314 if(i != this->CallStack.rend())
316 if(isError)
318 (*i).Status->SetNestedError(true);
320 cmListFileContext const& lfc = *(*i).Context;
322 << " at "
323 << this->LocalGenerator->Convert(lfc.FilePath.c_str(),
324 cmLocalGenerator::HOME)
325 << ":" << lfc.Line << " " << lfc.Name;
326 ++i;
328 else if(!this->ListFileStack.empty())
330 // We are processing the project but are not currently executing a
331 // command. Add whatever context information we have.
332 if(this->LocalGenerator->GetParent())
334 msg << " in directory "
335 << this->LocalGenerator->Convert(this->GetCurrentDirectory(),
336 cmLocalGenerator::HOME);
338 else
340 msg << " in top-level directory";
344 // Add the message text.
346 msg << " {\n";
347 cmDocumentationFormatterText formatter;
348 formatter.SetIndent(" ");
349 formatter.PrintFormatted(msg, text.c_str());
350 msg << "}";
353 // Add the rest of the context.
354 if(i != this->CallStack.rend())
356 msg << " with call stack {\n";
357 while(i != this->CallStack.rend())
359 cmListFileContext const& lfc = *(*i).Context;
360 msg << " "
361 << this->LocalGenerator->Convert(lfc.FilePath.c_str(),
362 cmLocalGenerator::HOME)
363 << ":" << lfc.Line << " " << lfc.Name << "\n";
364 ++i;
366 msg << "}\n";
368 else
370 msg << "\n";
373 // Output the message.
374 if(isError)
376 cmSystemTools::SetErrorOccured();
377 cmSystemTools::Message(msg.str().c_str(), "Error");
379 else
381 cmSystemTools::Message(msg.str().c_str(), "Warning");
385 //----------------------------------------------------------------------------
386 // Helper class to make sure the call stack is valid.
387 class cmMakefileCall
389 public:
390 cmMakefileCall(cmMakefile* mf,
391 cmListFileContext const& lfc,
392 cmExecutionStatus& status): Makefile(mf)
394 cmMakefile::CallStackEntry entry = {&lfc, &status};
395 this->Makefile->CallStack.push_back(entry);
397 ~cmMakefileCall()
399 this->Makefile->CallStack.pop_back();
401 private:
402 cmMakefile* Makefile;
405 //----------------------------------------------------------------------------
406 bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
407 cmExecutionStatus &status)
409 bool result = true;
411 // quick return if blocked
412 if(this->IsFunctionBlocked(lff,status))
414 // No error.
415 return result;
418 std::string name = lff.Name;
420 // Place this call on the call stack.
421 cmMakefileCall stack_manager(this, lff, status);
422 static_cast<void>(stack_manager);
424 // Lookup the command prototype.
425 if(cmCommand* proto = this->GetCMakeInstance()->GetCommand(name.c_str()))
427 // Clone the prototype.
428 cmsys::auto_ptr<cmCommand> pcmd(proto->Clone());
429 pcmd->SetMakefile(this);
431 // Decide whether to invoke the command.
432 if(pcmd->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() &&
433 (!this->GetCMakeInstance()->GetScriptMode() || pcmd->IsScriptable()))
435 // Try invoking the command.
436 if(!pcmd->InvokeInitialPass(lff.Arguments,status) ||
437 status.GetNestedError())
439 if(!status.GetNestedError())
441 // The command invocation requested that we report an error.
442 this->IssueError(pcmd->GetError());
444 result = false;
445 if ( this->GetCMakeInstance()->GetScriptMode() )
447 cmSystemTools::SetFatalErrorOccured();
450 else
452 // use the command
453 this->UsedCommands.push_back(pcmd.release());
456 else if ( this->GetCMakeInstance()->GetScriptMode()
457 && !pcmd->IsScriptable() )
459 std::string error = "Command ";
460 error += pcmd->GetName();
461 error += "() is not scriptable";
462 this->IssueError(error);
463 result = false;
464 cmSystemTools::SetFatalErrorOccured();
467 else
469 if(!cmSystemTools::GetFatalErrorOccured())
471 std::string error = "Unknown CMake command \"";
472 error += lff.Name;
473 error += "\".";
474 this->IssueError(error);
475 result = false;
476 cmSystemTools::SetFatalErrorOccured();
480 return result;
483 // Parse the given CMakeLists.txt file executing all commands
485 bool cmMakefile::ReadListFile(const char* filename_in,
486 const char *external_in,
487 std::string* fullPath)
489 std::string currentParentFile
490 = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
491 std::string currentFile
492 = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
493 this->AddDefinition("CMAKE_PARENT_LIST_FILE", filename_in);
495 // used to watch for blockers going out of scope
496 // e.g. mismatched IF statement
497 std::set<cmFunctionBlocker *> originalBlockers;
499 const char* external = 0;
500 std::string external_abs;
502 const char* filename = filename_in;
503 std::string filename_abs;
505 if (external_in)
507 external_abs =
508 cmSystemTools::CollapseFullPath(external_in,
509 this->cmStartDirectory.c_str());
510 external = external_abs.c_str();
511 if (filename_in)
513 filename_abs =
514 cmSystemTools::CollapseFullPath(filename_in,
515 this->cmStartDirectory.c_str());
516 filename = filename_abs.c_str();
520 // keep track of the current file being read
521 if (filename)
523 if(this->cmCurrentListFile != filename)
525 this->cmCurrentListFile = filename;
527 // loop over current function blockers and record them
528 std::list<cmFunctionBlocker *>::iterator pos;
529 for (pos = this->FunctionBlockers.begin();
530 pos != this->FunctionBlockers.end(); ++pos)
532 originalBlockers.insert(*pos);
536 // Now read the input file
537 const char *filenametoread= filename;
539 if( external)
541 filenametoread= external;
544 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
546 // try to see if the list file is the top most
547 // list file for a project, and if it is, then it
548 // must have a project command. If there is not
549 // one, then cmake will provide one via the
550 // cmListFileCache class.
551 bool requireProjectCommand = false;
552 if(!external && this->cmStartDirectory == this->cmHomeDirectory)
554 if(cmSystemTools::LowerCase(
555 cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt")
557 requireProjectCommand = true;
561 // push the listfile onto the stack
562 this->ListFileStack.push_back(filenametoread);
563 if(fullPath!=0)
565 *fullPath=filenametoread;
567 cmListFile cacheFile;
568 if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
570 // pop the listfile off the stack
571 this->ListFileStack.pop_back();
572 if(fullPath!=0)
574 *fullPath = "";
576 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
577 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
578 return false;
580 // add this list file to the list of dependencies
581 this->ListFiles.push_back( filenametoread);
582 bool endScopeNicely = filename? true: false;
583 const size_t numberFunctions = cacheFile.Functions.size();
584 for(size_t i =0; i < numberFunctions; ++i)
586 cmExecutionStatus status;
587 this->ExecuteCommand(cacheFile.Functions[i],status);
588 if (status.GetReturnInvoked() ||
589 cmSystemTools::GetFatalErrorOccured() )
591 // Exit early from processing this file.
592 endScopeNicely = false;
593 break;
597 // send scope ended to and function blockers
598 if (endScopeNicely)
600 // loop over all function blockers to see if any block this command
601 std::list<cmFunctionBlocker *>::iterator pos;
602 for (pos = this->FunctionBlockers.begin();
603 pos != this->FunctionBlockers.end(); ++pos)
605 // if this blocker was not in the original then send a
606 // scope ended message
607 if (originalBlockers.find(*pos) == originalBlockers.end())
609 (*pos)->ScopeEnded(*this);
614 // If this is the directory-level CMakeLists.txt file then enforce
615 // policy stack depth.
616 if(this->ListFileStack.size() == 1)
618 while(this->PolicyStack.size() > 1)
620 if(endScopeNicely)
622 this->IssueError("cmake_policy PUSH without matching POP");
624 this->PopPolicy(false);
628 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
629 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
631 // pop the listfile off the stack
632 this->ListFileStack.pop_back();
634 return true;
638 void cmMakefile::AddCommand(cmCommand* wg)
640 this->GetCMakeInstance()->AddCommand(wg);
643 // Set the make file
644 void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
646 this->LocalGenerator = lg;
649 bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
650 unsigned int minor,
651 unsigned int patch)
653 if(this->LocalGenerator)
655 return
656 this->LocalGenerator->NeedBackwardsCompatibility(major, minor, patch);
658 else
660 return false;
664 void cmMakefile::FinalPass()
666 // do all the variable expansions here
667 this->ExpandVariables();
669 // give all the commands a chance to do something
670 // after the file has been parsed before generation
671 for(std::vector<cmCommand*>::iterator i = this->UsedCommands.begin();
672 i != this->UsedCommands.end(); ++i)
674 (*i)->FinalPass();
679 // Generate the output file
680 void cmMakefile::ConfigureFinalPass()
682 this->FinalPass();
683 const char* oldValue
684 = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
685 if (oldValue && atof(oldValue) <= 1.2)
687 cmSystemTools::Error("You have requested backwards compatibility "
688 "with CMake version 1.2 or earlier. This version "
689 "of CMake only supports backwards compatibility "
690 "with CMake 1.4 or later. For compatibility with "
691 "1.2 or earlier please use CMake 2.0");
693 for (cmTargets::iterator l = this->Targets.begin();
694 l != this->Targets.end(); l++)
696 l->second.AnalyzeLibDependencies(*this);
700 //----------------------------------------------------------------------------
701 void
702 cmMakefile::AddCustomCommandToTarget(const char* target,
703 const std::vector<std::string>& depends,
704 const cmCustomCommandLines& commandLines,
705 cmTarget::CustomCommandType type,
706 const char* comment,
707 const char* workingDir,
708 bool escapeOldStyle)
710 // Find the target to which to add the custom command.
711 cmTargets::iterator ti = this->Targets.find(target);
712 if(ti != this->Targets.end())
714 // Add the command to the appropriate build step for the target.
715 std::vector<std::string> no_output;
716 cmCustomCommand cc(no_output, depends, commandLines, comment, workingDir);
717 cc.SetEscapeOldStyle(escapeOldStyle);
718 switch(type)
720 case cmTarget::PRE_BUILD:
721 ti->second.GetPreBuildCommands().push_back(cc);
722 break;
723 case cmTarget::PRE_LINK:
724 ti->second.GetPreLinkCommands().push_back(cc);
725 break;
726 case cmTarget::POST_BUILD:
727 ti->second.GetPostBuildCommands().push_back(cc);
728 break;
733 //----------------------------------------------------------------------------
734 void
735 cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
736 const std::vector<std::string>& depends,
737 const char* main_dependency,
738 const cmCustomCommandLines& commandLines,
739 const char* comment,
740 const char* workingDir,
741 bool replace,
742 bool escapeOldStyle)
744 // Make sure there is at least one output.
745 if(outputs.empty())
747 cmSystemTools::Error("Attempt to add a custom rule with no output!");
748 return;
751 // Choose a source file on which to store the custom command.
752 cmSourceFile* file = 0;
753 if(main_dependency && main_dependency[0])
755 // The main dependency was specified. Use it unless a different
756 // custom command already used it.
757 file = this->GetSource(main_dependency);
758 if(file && file->GetCustomCommand() && !replace)
760 // The main dependency already has a custom command.
761 if(commandLines == file->GetCustomCommand()->GetCommandLines())
763 // The existing custom command is identical. Silently ignore
764 // the duplicate.
765 return;
767 else
769 // The existing custom command is different. We need to
770 // generate a rule file for this new command.
771 file = 0;
774 else
776 // The main dependency does not have a custom command or we are
777 // allowed to replace it. Use it to store the command.
778 file = this->GetOrCreateSource(main_dependency);
782 // Generate a rule file if the main dependency is not available.
783 if(!file)
785 // Construct a rule file associated with the first output produced.
786 std::string outName = outputs[0];
787 outName += ".rule";
789 // Check if the rule file already exists.
790 file = this->GetSource(outName.c_str());
791 if(file && file->GetCustomCommand() && !replace)
793 // The rule file already exists.
794 if(commandLines != file->GetCustomCommand()->GetCommandLines())
796 cmSystemTools::Error("Attempt to add a custom rule to output \"",
797 outName.c_str(),
798 "\" which already has a custom rule.");
800 return;
803 // Create a cmSourceFile for the rule file.
804 file = this->GetOrCreateSource(outName.c_str(), true);
807 // Always create the output sources and mark them generated.
808 for(std::vector<std::string>::const_iterator o = outputs.begin();
809 o != outputs.end(); ++o)
811 if(cmSourceFile* out = this->GetOrCreateSource(o->c_str(), true))
813 out->SetProperty("GENERATED", "1");
817 // Construct a complete list of dependencies.
818 std::vector<std::string> depends2(depends);
819 if(main_dependency && main_dependency[0])
821 depends2.push_back(main_dependency);
824 // Attach the custom command to the file.
825 if(file)
827 cmCustomCommand* cc =
828 new cmCustomCommand(outputs, depends2, commandLines,
829 comment, workingDir);
830 cc->SetEscapeOldStyle(escapeOldStyle);
831 file->SetCustomCommand(cc);
835 //----------------------------------------------------------------------------
836 void
837 cmMakefile::AddCustomCommandToOutput(const char* output,
838 const std::vector<std::string>& depends,
839 const char* main_dependency,
840 const cmCustomCommandLines& commandLines,
841 const char* comment,
842 const char* workingDir,
843 bool replace,
844 bool escapeOldStyle)
846 std::vector<std::string> outputs;
847 outputs.push_back(output);
848 this->AddCustomCommandToOutput(outputs, depends, main_dependency,
849 commandLines, comment, workingDir,
850 replace, escapeOldStyle);
853 //----------------------------------------------------------------------------
854 void
855 cmMakefile::AddCustomCommandOldStyle(const char* target,
856 const std::vector<std::string>& outputs,
857 const std::vector<std::string>& depends,
858 const char* source,
859 const cmCustomCommandLines& commandLines,
860 const char* comment)
862 // Translate the old-style signature to one of the new-style
863 // signatures.
864 if(strcmp(source, target) == 0)
866 // In the old-style signature if the source and target were the
867 // same then it added a post-build rule to the target. Preserve
868 // this behavior.
869 this->AddCustomCommandToTarget(target, depends, commandLines,
870 cmTarget::POST_BUILD, comment, 0);
871 return;
874 // Each output must get its own copy of this rule.
875 cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|"
876 "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
877 "hm|hpp|hxx|in|txx|inl)$");
878 for(std::vector<std::string>::const_iterator oi = outputs.begin();
879 oi != outputs.end(); ++oi)
881 // Get the name of this output.
882 const char* output = oi->c_str();
884 // Choose whether to use a main dependency.
885 if(sourceFiles.find(source))
887 // The source looks like a real file. Use it as the main dependency.
888 this->AddCustomCommandToOutput(output, depends, source,
889 commandLines, comment, 0);
891 else
893 // The source may not be a real file. Do not use a main dependency.
894 const char* no_main_dependency = 0;
895 std::vector<std::string> depends2 = depends;
896 depends2.push_back(source);
897 this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
898 commandLines, comment, 0);
901 // If the rule was added to the source (and not a .rule file),
902 // then add the source to the target to make sure the rule is
903 // included.
904 std::string sname = output;
905 sname += ".rule";
906 if(!this->GetSource(sname.c_str()))
908 if (this->Targets.find(target) != this->Targets.end())
910 this->Targets[target].AddSource(source);
912 else
914 cmSystemTools::Error("Attempt to add a custom rule to a target "
915 "that does not exist yet for target ", target);
916 return;
922 //----------------------------------------------------------------------------
923 void cmMakefile::AddUtilityCommand(const char* utilityName,
924 bool excludeFromAll,
925 const std::vector<std::string>& depends,
926 const char* workingDirectory,
927 const char* command,
928 const char* arg1,
929 const char* arg2,
930 const char* arg3,
931 const char* arg4)
933 // Construct the command line for the custom command.
934 cmCustomCommandLine commandLine;
935 commandLine.push_back(command);
936 if(arg1)
938 commandLine.push_back(arg1);
940 if(arg2)
942 commandLine.push_back(arg2);
944 if(arg3)
946 commandLine.push_back(arg3);
948 if(arg4)
950 commandLine.push_back(arg4);
952 cmCustomCommandLines commandLines;
953 commandLines.push_back(commandLine);
955 // Call the real signature of this method.
956 this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
957 depends, commandLines);
960 //----------------------------------------------------------------------------
961 void cmMakefile::AddUtilityCommand(const char* utilityName,
962 bool excludeFromAll,
963 const char* workingDirectory,
964 const std::vector<std::string>& depends,
965 const cmCustomCommandLines& commandLines,
966 bool escapeOldStyle, const char* comment)
968 // Create a target instance for this utility.
969 cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
970 if (excludeFromAll)
972 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
974 if(!comment)
976 // Use an empty comment to avoid generation of default comment.
977 comment = "";
980 // Store the custom command in the target.
981 std::string force = this->GetStartOutputDirectory();
982 force += cmake::GetCMakeFilesDirectory();
983 force += "/";
984 force += utilityName;
985 const char* no_main_dependency = 0;
986 bool no_replace = false;
987 this->AddCustomCommandToOutput(force.c_str(), depends,
988 no_main_dependency,
989 commandLines, comment,
990 workingDirectory, no_replace,
991 escapeOldStyle);
992 cmSourceFile* sf = target->AddSource(force.c_str());
994 // The output is not actually created so mark it symbolic.
995 if(sf)
997 sf->SetProperty("SYMBOLIC", "1");
999 else
1001 cmSystemTools::Error("Could not get source file entry for ",
1002 force.c_str());
1006 void cmMakefile::AddDefineFlag(const char* flag)
1008 if (!flag)
1010 return;
1013 // If this is really a definition, update COMPILE_DEFINITIONS.
1014 if(this->ParseDefineFlag(flag, false))
1016 return;
1019 // remove any \n\r
1020 std::string ret = flag;
1021 std::string::size_type pos = 0;
1022 while((pos = ret.find('\n', pos)) != std::string::npos)
1024 ret[pos] = ' ';
1025 pos++;
1027 pos = 0;
1028 while((pos = ret.find('\r', pos)) != std::string::npos)
1030 ret[pos] = ' ';
1031 pos++;
1034 this->DefineFlags += " ";
1035 this->DefineFlags += ret;
1039 void cmMakefile::RemoveDefineFlag(const char* flag)
1041 // Check the length of the flag to remove.
1042 std::string::size_type len = strlen(flag);
1043 if(len < 1)
1045 return;
1048 // If this is really a definition, update COMPILE_DEFINITIONS.
1049 if(this->ParseDefineFlag(flag, true))
1051 return;
1054 // Remove all instances of the flag that are surrounded by
1055 // whitespace or the beginning/end of the string.
1056 for(std::string::size_type lpos = this->DefineFlags.find(flag, 0);
1057 lpos != std::string::npos; lpos = this->DefineFlags.find(flag, lpos))
1059 std::string::size_type rpos = lpos + len;
1060 if((lpos <= 0 || isspace(this->DefineFlags[lpos-1])) &&
1061 (rpos >= this->DefineFlags.size() || isspace(this->DefineFlags[rpos])))
1063 this->DefineFlags.erase(lpos, len);
1065 else
1067 ++lpos;
1072 bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
1074 // Create a regular expression to match valid definitions.
1075 // Definitions with non-trivial values must not be matched because
1076 // escaping them could break compatibility with escapes added by
1077 // users.
1078 static cmsys::RegularExpression
1079 regex("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=[A-Za-z0-9_.]+)?$");
1081 // Make sure the definition matches.
1082 if(!regex.find(def.c_str()))
1084 return false;
1087 // VS6 IDE does not support definitions with values.
1088 if((strcmp(this->LocalGenerator->GetGlobalGenerator()->GetName(),
1089 "Visual Studio 6") == 0) &&
1090 (def.find("=") != def.npos))
1092 return false;
1095 // Get the definition part after the flag.
1096 const char* define = def.c_str() + 2;
1098 if(remove)
1100 if(const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS"))
1102 // Expand the list.
1103 std::vector<std::string> defs;
1104 cmSystemTools::ExpandListArgument(cdefs, defs);
1106 // Recompose the list without the definition.
1107 std::string ndefs;
1108 const char* sep = "";
1109 for(std::vector<std::string>::const_iterator di = defs.begin();
1110 di != defs.end(); ++di)
1112 if(*di != define)
1114 ndefs += sep;
1115 sep = ";";
1116 ndefs += *di;
1120 // Store the new list.
1121 this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
1124 else
1126 // Append the definition to the directory property.
1127 this->AppendProperty("COMPILE_DEFINITIONS", define);
1130 return true;
1133 void cmMakefile::AddLinkLibrary(const char* lib,
1134 cmTarget::LinkLibraryType llt)
1136 cmTarget::LibraryID tmp;
1137 tmp.first = lib;
1138 tmp.second = llt;
1139 this->LinkLibraries.push_back(tmp);
1142 void cmMakefile::AddLinkLibraryForTarget(const char *target,
1143 const char* lib,
1144 cmTarget::LinkLibraryType llt)
1146 cmTargets::iterator i = this->Targets.find(target);
1147 if ( i != this->Targets.end())
1149 cmTarget* tgt =
1150 this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib);
1151 if(tgt)
1153 // CMake versions below 2.4 allowed linking to modules.
1154 bool allowModules = this->NeedBackwardsCompatibility(2,3);
1155 // if it is not a static or shared library then you can not link to it
1156 if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
1157 (tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
1158 tgt->IsExecutableWithExports()))
1160 cmOStringStream e;
1161 e << "Attempt to add link target " << lib << " of type: "
1162 << cmTarget::TargetTypeNames[static_cast<int>(tgt->GetType())]
1163 << "\nto target " << target
1164 << ". One can only link to STATIC or SHARED libraries, or "
1165 << "to executables with the ENABLE_EXPORTS property set.";
1166 // in older versions of cmake linking to modules was allowed
1167 if( tgt->GetType() == cmTarget::MODULE_LIBRARY )
1169 e <<
1170 "\nTo allow linking of modules set "
1171 "CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower\n";
1173 // if no modules are allowed then this is always an error
1174 if(!allowModules ||
1175 // if we allow modules but the type is not a module then it is
1176 // still an error
1177 (allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY))
1179 cmSystemTools::Error(e.str().c_str());
1183 i->second.AddLinkLibrary( *this, target, lib, llt );
1185 else
1187 cmOStringStream e;
1188 e << "Attempt to add link library \""
1189 << lib << "\" to target \""
1190 << target << "\" which is not built by this project.";
1191 cmSystemTools::Error(e.str().c_str());
1195 void cmMakefile::AddLinkDirectoryForTarget(const char *target,
1196 const char* d)
1198 cmTargets::iterator i = this->Targets.find(target);
1199 if ( i != this->Targets.end())
1201 i->second.AddLinkDirectory( d );
1203 else
1205 cmSystemTools::Error
1206 ("Attempt to add link directories to non-existant target: ",
1207 target, " for directory ", d);
1211 void cmMakefile::AddLinkLibrary(const char* lib)
1213 this->AddLinkLibrary(lib,cmTarget::GENERAL);
1216 void cmMakefile::AddLinkDirectory(const char* dir)
1218 // Don't add a link directory that is already present. Yes, this
1219 // linear search results in n^2 behavior, but n won't be getting
1220 // much bigger than 20. We cannot use a set because of order
1221 // dependency of the link search path.
1223 if(!dir)
1225 return;
1227 // remove trailing slashes
1228 if(dir[strlen(dir)-1] == '/')
1230 std::string newdir = dir;
1231 newdir = newdir.substr(0, newdir.size()-1);
1232 if(std::find(this->LinkDirectories.begin(),
1233 this->LinkDirectories.end(),
1234 newdir.c_str()) == this->LinkDirectories.end())
1236 this->LinkDirectories.push_back(newdir);
1239 else
1241 if(std::find(this->LinkDirectories.begin(),
1242 this->LinkDirectories.end(), dir)
1243 == this->LinkDirectories.end())
1245 this->LinkDirectories.push_back(dir);
1250 void cmMakefile::InitializeFromParent()
1252 cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
1254 // copy the definitions
1255 this->DefinitionStack.front() = parent->DefinitionStack.back();
1257 // copy include paths
1258 this->IncludeDirectories = parent->IncludeDirectories;
1259 this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
1261 // define flags
1262 this->DefineFlags = parent->DefineFlags;
1264 // compile definitions property and per-config versions
1266 this->SetProperty("COMPILE_DEFINITIONS",
1267 parent->GetProperty("COMPILE_DEFINITIONS"));
1268 std::vector<std::string> configs;
1269 if(const char* configTypes =
1270 this->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
1272 cmSystemTools::ExpandListArgument(configTypes, configs);
1274 else if(const char* buildType =
1275 this->GetDefinition("CMAKE_BUILD_TYPE"))
1277 configs.push_back(buildType);
1279 for(std::vector<std::string>::const_iterator ci = configs.begin();
1280 ci != configs.end(); ++ci)
1282 std::string defPropName = "COMPILE_DEFINITIONS_";
1283 defPropName += cmSystemTools::UpperCase(*ci);
1284 this->SetProperty(defPropName.c_str(),
1285 parent->GetProperty(defPropName.c_str()));
1289 // link libraries
1290 this->LinkLibraries = parent->LinkLibraries;
1292 // link directories
1293 this->LinkDirectories = parent->LinkDirectories;
1295 // the initial project name
1296 this->ProjectName = parent->ProjectName;
1298 // Copy include regular expressions.
1299 this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
1300 this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
1302 // Imported targets.
1303 this->ImportedTargets = parent->ImportedTargets;
1306 void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
1308 // copy our variables from the child makefile
1309 lg2->GetMakefile()->InitializeFromParent();
1310 lg2->GetMakefile()->MakeStartDirectoriesCurrent();
1311 if (this->GetCMakeInstance()->GetDebugOutput())
1313 std::string msg=" Entering ";
1314 msg += lg2->GetMakefile()->GetCurrentDirectory();
1315 cmSystemTools::Message(msg.c_str());
1317 // finally configure the subdir
1318 lg2->Configure();
1319 if (this->GetCMakeInstance()->GetDebugOutput())
1321 std::string msg=" Returning to ";
1322 msg += this->GetCurrentDirectory();
1323 cmSystemTools::Message(msg.c_str());
1327 void cmMakefile::AddSubDirectory(const char* sub,
1328 bool excludeFromAll, bool preorder)
1330 // the source path must be made full if it isn't already
1331 std::string srcPath = sub;
1332 if (!cmSystemTools::FileIsFullPath(srcPath.c_str()))
1334 srcPath = this->GetCurrentDirectory();
1335 srcPath += "/";
1336 srcPath += sub;
1339 // binary path must be made full if it isn't already
1340 std::string binPath = sub;
1341 if (!cmSystemTools::FileIsFullPath(binPath.c_str()))
1343 binPath = this->GetCurrentOutputDirectory();
1344 binPath += "/";
1345 binPath += sub;
1349 this->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
1350 excludeFromAll, preorder, false);
1354 void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
1355 bool excludeFromAll, bool preorder,
1356 bool immediate)
1358 std::vector<cmLocalGenerator *>& children =
1359 this->LocalGenerator->GetChildren();
1360 // has this directory already been added? If so error
1361 unsigned int i;
1362 for (i = 0; i < children.size(); ++i)
1364 if (srcPath == children[i]->GetMakefile()->GetStartDirectory())
1366 cmSystemTools::Error
1367 ("Attempt to add subdirectory multiple times for directory.\n",
1368 srcPath);
1369 return;
1373 // create a new local generator and set its parent
1374 cmLocalGenerator *lg2 =
1375 this->LocalGenerator->GetGlobalGenerator()->CreateLocalGenerator();
1376 lg2->SetParent(this->LocalGenerator);
1377 this->LocalGenerator->GetGlobalGenerator()->AddLocalGenerator(lg2);
1379 // set the subdirs start dirs
1380 lg2->GetMakefile()->SetStartDirectory(srcPath);
1381 lg2->GetMakefile()->SetStartOutputDirectory(binPath);
1382 if(excludeFromAll)
1384 lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1386 lg2->GetMakefile()->SetPreOrder(preorder);
1388 if (immediate)
1390 this->ConfigureSubDirectory(lg2);
1394 void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
1396 // if there is a newline then break it into multiple arguments
1397 if (!inc)
1399 return;
1402 // Don't add an include directory that is already present. Yes,
1403 // this linear search results in n^2 behavior, but n won't be
1404 // getting much bigger than 20. We cannot use a set because of
1405 // order dependency of the include path.
1406 std::vector<std::string>::iterator i =
1407 std::find(this->IncludeDirectories.begin(),
1408 this->IncludeDirectories.end(), inc);
1409 if(i == this->IncludeDirectories.end())
1411 if (before)
1413 // WARNING: this *is* expensive (linear time) since it's a vector
1414 this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
1416 else
1418 this->IncludeDirectories.push_back(inc);
1421 else
1423 if(before)
1425 // if this before and already in the path then remove it
1426 this->IncludeDirectories.erase(i);
1427 // WARNING: this *is* expensive (linear time) since it's a vector
1428 this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
1433 //----------------------------------------------------------------------------
1434 void cmMakefile::AddSystemIncludeDirectory(const char* dir)
1436 this->SystemIncludeDirectories.insert(dir);
1439 //----------------------------------------------------------------------------
1440 bool cmMakefile::IsSystemIncludeDirectory(const char* dir)
1442 return (this->SystemIncludeDirectories.find(dir) !=
1443 this->SystemIncludeDirectories.end());
1446 void cmMakefile::AddDefinition(const char* name, const char* value)
1448 if (!value )
1450 return;
1453 #ifdef CMAKE_STRICT
1454 if (this->GetCMakeInstance())
1456 this->GetCMakeInstance()->
1457 RecordPropertyAccess(name,cmProperty::VARIABLE);
1459 #endif
1461 this->TemporaryDefinitionKey = name;
1462 this->DefinitionStack.back()[this->TemporaryDefinitionKey] = value;
1464 #ifdef CMAKE_BUILD_WITH_CMAKE
1465 cmVariableWatch* vv = this->GetVariableWatch();
1466 if ( vv )
1468 vv->VariableAccessed(this->TemporaryDefinitionKey,
1469 cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1470 value,
1471 this);
1473 #endif
1477 void cmMakefile::AddCacheDefinition(const char* name, const char* value,
1478 const char* doc,
1479 cmCacheManager::CacheEntryType type)
1481 const char* val = value;
1482 cmCacheManager::CacheIterator it =
1483 this->GetCacheManager()->GetCacheIterator(name);
1484 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1485 it.Initialized())
1487 val = it.GetValue();
1488 if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH )
1490 std::vector<std::string>::size_type cc;
1491 std::vector<std::string> files;
1492 std::string nvalue = "";
1493 cmSystemTools::ExpandListArgument(val, files);
1494 for ( cc = 0; cc < files.size(); cc ++ )
1496 files[cc] = cmSystemTools::CollapseFullPath(files[cc].c_str());
1497 if ( cc > 0 )
1499 nvalue += ";";
1501 nvalue += files[cc];
1504 this->GetCacheManager()->AddCacheEntry(name, nvalue.c_str(), doc, type);
1505 val = it.GetValue();
1509 this->GetCacheManager()->AddCacheEntry(name, val, doc, type);
1510 // if there was a definition then remove it
1511 this->DefinitionStack.back().erase( DefinitionMap::key_type(name));
1515 void cmMakefile::AddDefinition(const char* name, bool value)
1517 if(value)
1519 this->DefinitionStack.back()
1520 .erase( DefinitionMap::key_type(name));
1521 this->DefinitionStack.back()
1522 .insert(DefinitionMap::value_type(name, "ON"));
1524 else
1526 this->DefinitionStack.back()
1527 .erase( DefinitionMap::key_type(name));
1528 this->DefinitionStack.back()
1529 .insert(DefinitionMap::value_type(name, "OFF"));
1531 #ifdef CMAKE_BUILD_WITH_CMAKE
1532 cmVariableWatch* vv = this->GetVariableWatch();
1533 if ( vv )
1535 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1536 value?"ON":"OFF", this);
1538 #endif
1542 void cmMakefile::AddCacheDefinition(const char* name,
1543 bool value,
1544 const char* doc)
1546 bool val = value;
1547 cmCacheManager::CacheIterator it =
1548 this->GetCacheManager()->GetCacheIterator(name);
1549 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1550 it.Initialized())
1552 val = it.GetValueAsBool();
1554 this->GetCacheManager()->AddCacheEntry(name, val, doc);
1555 this->AddDefinition(name, val);
1558 void cmMakefile::RemoveDefinition(const char* name)
1560 this->DefinitionStack.back().erase(DefinitionMap::key_type(name));
1561 #ifdef CMAKE_BUILD_WITH_CMAKE
1562 cmVariableWatch* vv = this->GetVariableWatch();
1563 if ( vv )
1565 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
1566 0, this);
1568 #endif
1571 void cmMakefile::SetProjectName(const char* p)
1573 this->ProjectName = p;
1577 void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
1579 // for these targets do not add anything
1580 switch(target.GetType())
1582 case cmTarget::UTILITY:
1583 case cmTarget::GLOBAL_TARGET:
1584 return;
1585 default:;
1587 std::vector<std::string>::iterator j;
1588 for(j = this->LinkDirectories.begin();
1589 j != this->LinkDirectories.end(); ++j)
1591 target.AddLinkDirectory(j->c_str());
1593 target.MergeLinkLibraries( *this, name, this->LinkLibraries );
1597 void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
1598 const std::vector<std::string> &srcs,
1599 bool excludeFromAll)
1601 // wrong type ? default to STATIC
1602 if ( (type != cmTarget::STATIC_LIBRARY)
1603 && (type != cmTarget::SHARED_LIBRARY)
1604 && (type != cmTarget::MODULE_LIBRARY))
1606 type = cmTarget::STATIC_LIBRARY;
1609 cmTarget* target = this->AddNewTarget(type, lname);
1610 // Clear its dependencies. Otherwise, dependencies might persist
1611 // over changes in CMakeLists.txt, making the information stale and
1612 // hence useless.
1613 target->ClearDependencyInformation( *this, lname );
1614 if(excludeFromAll)
1616 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1618 target->AddSources(srcs);
1619 this->AddGlobalLinkInformation(lname, *target);
1622 cmTarget* cmMakefile::AddExecutable(const char *exeName,
1623 const std::vector<std::string> &srcs,
1624 bool excludeFromAll)
1626 cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName);
1627 if(excludeFromAll)
1629 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1631 target->AddSources(srcs);
1632 this->AddGlobalLinkInformation(exeName, *target);
1633 return target;
1636 //----------------------------------------------------------------------------
1637 cmTarget*
1638 cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name)
1640 cmTargets::iterator it;
1641 cmTarget target;
1642 target.SetType(type, name);
1643 target.SetMakefile(this);
1644 it=this->Targets.insert(
1645 cmTargets::value_type(target.GetName(), target)).first;
1646 this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it);
1647 return &it->second;
1650 cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
1652 std::string name = cname;
1653 std::string out;
1655 // look through all the source files that have custom commands
1656 // and see if the custom command has the passed source file as an output
1657 // keep in mind the possible .rule extension that may be tacked on
1658 for(std::vector<cmSourceFile*>::const_iterator i =
1659 this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
1661 // does this source file have a custom command?
1662 if ((*i)->GetCustomCommand())
1664 // is the output of the custom command match the source files name
1665 const std::vector<std::string>& outputs =
1666 (*i)->GetCustomCommand()->GetOutputs();
1667 for(std::vector<std::string>::const_iterator o = outputs.begin();
1668 o != outputs.end(); ++o)
1670 out = *o;
1671 std::string::size_type pos = out.rfind(name);
1672 // If the output matches exactly
1673 if (pos != out.npos &&
1674 pos == out.size() - name.size() &&
1675 (pos ==0 || out[pos-1] == '/'))
1677 return *i;
1683 // otherwise return NULL
1684 return 0;
1687 #if defined(CMAKE_BUILD_WITH_CMAKE)
1688 cmSourceGroup* cmMakefile::GetSourceGroup(const std::vector<std::string>&name)
1690 cmSourceGroup* sg = 0;
1692 // first look for source group starting with the same as the one we wants
1693 for (std::vector<cmSourceGroup>::iterator sgIt = this->SourceGroups.begin();
1694 sgIt != this->SourceGroups.end(); ++sgIt)
1697 std::string sgName = sgIt->GetName();
1698 if(sgName == name[0])
1700 sg = &(*sgIt);
1701 break;
1705 if(sg != 0)
1707 // iterate through its children to find match source group
1708 for(unsigned int i=1; i<name.size(); ++i)
1710 sg = sg->lookupChild(name[i].c_str());
1711 if(sg == 0)
1713 break;
1717 return sg;
1720 void cmMakefile::AddSourceGroup(const char* name,
1721 const char* regex)
1723 if (name)
1725 std::vector<std::string> nameVector;
1726 nameVector.push_back(name);
1727 AddSourceGroup(nameVector, regex);
1731 void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
1732 const char* regex)
1734 cmSourceGroup* sg = 0;
1735 std::vector<std::string> currentName;
1736 int i = 0;
1737 const int lastElement = static_cast<int>(name.size()-1);
1738 for(i=lastElement; i>=0; --i)
1740 currentName.assign(name.begin(), name.begin()+i+1);
1741 sg = this->GetSourceGroup(currentName);
1742 if(sg != 0)
1744 break;
1748 // i now contains the index of the last found component
1749 if(i==lastElement)
1751 // group already exists, replace its regular expression
1752 if ( regex )
1754 // We only want to set the regular expression. If there are already
1755 // source files in the group, we don't want to remove them.
1756 sg->SetGroupRegex(regex);
1758 return;
1760 else if(i==-1)
1762 // group does not exists nor belong to any existing group
1763 // add its first component
1764 this->SourceGroups.push_back(cmSourceGroup(name[0].c_str(), regex));
1765 sg = this->GetSourceGroup(currentName);
1766 i = 0; // last component found
1769 // build the whole source group path
1770 for(++i; i<=lastElement; ++i)
1772 sg->AddChild(cmSourceGroup(name[i].c_str(), 0));
1773 sg = sg->lookupChild(name[i].c_str());
1776 sg->SetGroupRegex(regex);
1779 #endif
1781 void cmMakefile::AddExtraDirectory(const char* dir)
1783 this->AuxSourceDirectories.push_back(dir);
1787 // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
1788 // include and library directories.
1790 void cmMakefile::ExpandVariables()
1792 // Now expand variables in the include and link strings
1793 for(std::vector<std::string>::iterator d = this->IncludeDirectories.begin();
1794 d != this->IncludeDirectories.end(); ++d)
1796 this->ExpandVariablesInString(*d, true, true);
1798 for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
1799 d != this->LinkDirectories.end(); ++d)
1801 this->ExpandVariablesInString(*d, true, true);
1803 for(cmTarget::LinkLibraryVectorType::iterator l =
1804 this->LinkLibraries.begin();
1805 l != this->LinkLibraries.end(); ++l)
1807 this->ExpandVariablesInString(l->first, true, true);
1811 bool cmMakefile::IsOn(const char* name) const
1813 const char* value = this->GetDefinition(name);
1814 return cmSystemTools::IsOn(value);
1817 bool cmMakefile::IsSet(const char* name) const
1819 const char* value = this->GetDefinition(name);
1820 if ( !value )
1822 return false;
1825 if ( ! *value )
1827 return false;
1830 if ( cmSystemTools::IsNOTFOUND(value) )
1832 return false;
1835 return true;
1838 bool cmMakefile::CanIWriteThisFile(const char* fileName)
1840 if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
1842 return true;
1844 // If we are doing an in-source build, than the test will always fail
1845 if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
1846 this->GetHomeOutputDirectory()) )
1848 if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
1850 return false;
1852 return true;
1855 // Check if this is subdirectory of the source tree but not a
1856 // subdirectory of a build tree
1857 if ( cmSystemTools::IsSubDirectory(fileName,
1858 this->GetHomeDirectory()) &&
1859 !cmSystemTools::IsSubDirectory(fileName,
1860 this->GetHomeOutputDirectory()) )
1862 return false;
1864 return true;
1867 const char* cmMakefile::GetRequiredDefinition(const char* name) const
1869 const char* ret = this->GetDefinition(name);
1870 if(!ret)
1872 cmSystemTools::Error("Error required internal CMake variable not "
1873 "set, cmake may be not be built correctly.\n",
1874 "Missing variable is:\n",
1875 name);
1876 return "";
1878 return ret;
1881 bool cmMakefile::IsDefinitionSet(const char* name) const
1883 const char* def = 0;
1884 DefinitionMap::const_iterator pos =
1885 this->DefinitionStack.back().find(name);
1886 if(pos != this->DefinitionStack.back().end())
1888 def = (*pos).second.c_str();
1890 else
1892 def = this->GetCacheManager()->GetCacheValue(name);
1894 #ifdef CMAKE_BUILD_WITH_CMAKE
1895 if(cmVariableWatch* vv = this->GetVariableWatch())
1897 if(!def)
1899 vv->VariableAccessed
1900 (name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS,
1901 def, this);
1904 #endif
1905 return def?true:false;
1908 const char* cmMakefile::GetDefinition(const char* name) const
1910 #ifdef CMAKE_STRICT
1911 if (this->GetCMakeInstance())
1913 this->GetCMakeInstance()->
1914 RecordPropertyAccess(name,cmProperty::VARIABLE);
1916 #endif
1917 const char* def = 0;
1918 DefinitionMap::const_iterator pos =
1919 this->DefinitionStack.back().find(name);
1920 if(pos != this->DefinitionStack.back().end())
1922 def = (*pos).second.c_str();
1924 else
1926 def = this->GetCacheManager()->GetCacheValue(name);
1928 #ifdef CMAKE_BUILD_WITH_CMAKE
1929 cmVariableWatch* vv = this->GetVariableWatch();
1930 if ( vv )
1932 if ( def )
1934 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
1935 def, this);
1937 else
1939 // are unknown access allowed
1940 DefinitionMap::const_iterator pos2 =
1941 this->DefinitionStack.back()
1942 .find("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
1943 if (pos2 != this->DefinitionStack.back().end() &&
1944 cmSystemTools::IsOn((*pos2).second.c_str()))
1946 vv->VariableAccessed(name,
1947 cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, def, this);
1949 else
1951 vv->VariableAccessed(name,
1952 cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
1956 #endif
1957 return def;
1960 const char* cmMakefile::GetSafeDefinition(const char* def) const
1962 const char* ret = this->GetDefinition(def);
1963 if(!ret)
1965 return "";
1967 return ret;
1970 std::vector<std::string> cmMakefile
1971 ::GetDefinitions(int cacheonly /* = 0 */) const
1973 std::map<cmStdString, int> definitions;
1974 if ( !cacheonly )
1976 DefinitionMap::const_iterator it;
1977 for ( it = this->DefinitionStack.back().begin();
1978 it != this->DefinitionStack.back().end(); it ++ )
1980 definitions[it->first] = 1;
1983 cmCacheManager::CacheIterator cit =
1984 this->GetCacheManager()->GetCacheIterator();
1985 for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
1987 definitions[cit.GetName()] = 1;
1990 std::vector<std::string> res;
1992 std::map<cmStdString, int>::iterator fit;
1993 for ( fit = definitions.begin(); fit != definitions.end(); fit ++ )
1995 res.push_back(fit->first);
1997 return res;
2001 const char *cmMakefile::ExpandVariablesInString(std::string& source)
2003 return this->ExpandVariablesInString(source, false, false);
2006 const char *cmMakefile::ExpandVariablesInString(std::string& source,
2007 bool escapeQuotes,
2008 bool noEscapes,
2009 bool atOnly,
2010 const char* filename,
2011 long line,
2012 bool removeEmpty,
2013 bool replaceAt)
2015 if ( source.empty() || source.find_first_of("$@\\") == source.npos)
2017 return source.c_str();
2020 // Special-case the @ONLY mode.
2021 if(atOnly)
2023 if(!noEscapes || !removeEmpty || !replaceAt)
2025 // This case should never be called. At-only is for
2026 // configure-file/string which always does no escapes.
2027 abort();
2030 // Store an original copy of the input.
2031 std::string input = source;
2033 // Start with empty output.
2034 source = "";
2036 // Look for one @VAR@ at a time.
2037 const char* in = input.c_str();
2038 while(this->cmAtVarRegex.find(in))
2040 // Get the range of the string to replace.
2041 const char* first = in + this->cmAtVarRegex.start();
2042 const char* last = in + this->cmAtVarRegex.end();
2044 // Store the unchanged part of the string now.
2045 source.append(in, first-in);
2047 // Lookup the definition of VAR.
2048 std::string var(first+1, last-first-2);
2049 if(const char* val = this->GetDefinition(var.c_str()))
2051 // Store the value in the output escaping as requested.
2052 if(escapeQuotes)
2054 source.append(cmSystemTools::EscapeQuotes(val));
2056 else
2058 source.append(val);
2062 // Continue looking for @VAR@ further along the string.
2063 in = last;
2066 // Append the rest of the unchanged part of the string.
2067 source.append(in);
2069 return source.c_str();
2072 // This method replaces ${VAR} and @VAR@ where VAR is looked up
2073 // with GetDefinition(), if not found in the map, nothing is expanded.
2074 // It also supports the $ENV{VAR} syntax where VAR is looked up in
2075 // the current environment variables.
2077 cmCommandArgumentParserHelper parser;
2078 parser.SetMakefile(this);
2079 parser.SetLineFile(line, filename);
2080 parser.SetEscapeQuotes(escapeQuotes);
2081 parser.SetNoEscapeMode(noEscapes);
2082 parser.SetReplaceAtSyntax(replaceAt);
2083 parser.SetRemoveEmpty(removeEmpty);
2084 int res = parser.ParseString(source.c_str(), 0);
2085 if ( res )
2087 source = parser.GetResult();
2089 else
2091 cmOStringStream error;
2092 error << "Syntax error in cmake code at\n"
2093 << (filename?filename:"(no filename given)")
2094 << ":" << line << ":\n"
2095 << parser.GetError() << ", when parsing string \""
2096 << source.c_str() << "\"";
2097 if(this->NeedBackwardsCompatibility(2,0))
2099 cmSystemTools::Error(error.str().c_str());
2100 cmSystemTools::SetFatalErrorOccured();
2101 return source.c_str();
2103 else
2105 cmSystemTools::Message(error.str().c_str());
2108 return source.c_str();
2111 void cmMakefile::RemoveVariablesInString(std::string& source,
2112 bool atOnly) const
2114 if(!atOnly)
2116 cmsys::RegularExpression var("(\\${[A-Za-z_0-9]*})");
2117 while (var.find(source))
2119 source.erase(var.start(),var.end() - var.start());
2123 if(!atOnly)
2125 cmsys::RegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
2126 while (varb.find(source))
2128 source.erase(varb.start(),varb.end() - varb.start());
2131 cmsys::RegularExpression var2("(@[A-Za-z_0-9]*@)");
2132 while (var2.find(source))
2134 source.erase(var2.start(),var2.end() - var2.start());
2139 * Add the default definitions to the makefile. These values must not
2140 * be dependent on anything that isn't known when this cmMakefile instance
2141 * is constructed.
2143 void cmMakefile::AddDefaultDefinitions()
2145 /* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set.
2146 With CMake must separate between target and host platform. In most cases
2147 the tests for WIN32, UNIX and APPLE will be for the target system, so an
2148 additional set of variables for the host system is required ->
2149 CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE.
2150 WIN32, UNIX and APPLE are now set in the platform files in
2151 Modules/Platforms/.
2152 To keep cmake scripts (-P) and custom language and compiler modules
2153 working, these variables are still also set here in this place, but they
2154 will be reset in CMakeSystemSpecificInformation.cmake before the platform
2155 files are executed. */
2156 #if defined(_WIN32) || defined(__CYGWIN__)
2157 this->AddDefinition("WIN32", "1");
2158 this->AddDefinition("CMAKE_HOST_WIN32", "1");
2159 #else
2160 this->AddDefinition("UNIX", "1");
2161 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2162 #endif
2163 // Cygwin is more like unix so enable the unix commands
2164 #if defined(__CYGWIN__)
2165 this->AddDefinition("UNIX", "1");
2166 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2167 #endif
2168 #if defined(__APPLE__)
2169 this->AddDefinition("APPLE", "1");
2170 this->AddDefinition("CMAKE_HOST_APPLE", "1");
2171 #endif
2173 char temp[1024];
2174 sprintf(temp, "%d", cmVersion::GetMinorVersion());
2175 this->AddDefinition("CMAKE_MINOR_VERSION", temp);
2176 sprintf(temp, "%d", cmVersion::GetMajorVersion());
2177 this->AddDefinition("CMAKE_MAJOR_VERSION", temp);
2178 sprintf(temp, "%d", cmVersion::GetPatchVersion());
2179 this->AddDefinition("CMAKE_PATCH_VERSION", temp);
2181 this->AddDefinition("CMAKE_FILES_DIRECTORY",
2182 cmake::GetCMakeFilesDirectory());
2185 #if defined(CMAKE_BUILD_WITH_CMAKE)
2187 * Find a source group whose regular expression matches the filename
2188 * part of the given source name. Search backward through the list of
2189 * source groups, and take the first matching group found. This way
2190 * non-inherited SOURCE_GROUP commands will have precedence over
2191 * inherited ones.
2193 cmSourceGroup&
2194 cmMakefile::FindSourceGroup(const char* source,
2195 std::vector<cmSourceGroup> &groups)
2197 // First search for a group that lists the file explicitly.
2198 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2199 sg != groups.rend(); ++sg)
2201 cmSourceGroup *result = sg->MatchChildrenFiles(source);
2202 if(result)
2204 return *result;
2208 // Now search for a group whose regex matches the file.
2209 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2210 sg != groups.rend(); ++sg)
2212 cmSourceGroup *result = sg->MatchChildrenRegex(source);
2213 if(result)
2215 return *result;
2220 // Shouldn't get here, but just in case, return the default group.
2221 return groups.front();
2223 #endif
2225 bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
2226 cmExecutionStatus &status)
2228 // if there are no blockers get out of here
2229 if (this->FunctionBlockers.begin() == this->FunctionBlockers.end())
2231 return false;
2234 // loop over all function blockers to see if any block this command
2235 // evaluate in reverse, this is critical for balanced IF statements etc
2236 std::list<cmFunctionBlocker *>::reverse_iterator pos;
2237 for (pos = this->FunctionBlockers.rbegin();
2238 pos != this->FunctionBlockers.rend(); ++pos)
2240 if((*pos)->IsFunctionBlocked(lff, *this, status))
2242 return true;
2246 return false;
2249 void cmMakefile::ExpandArguments(
2250 std::vector<cmListFileArgument> const& inArgs,
2251 std::vector<std::string>& outArgs)
2253 std::vector<cmListFileArgument>::const_iterator i;
2254 std::string value;
2255 outArgs.reserve(inArgs.size());
2256 for(i = inArgs.begin(); i != inArgs.end(); ++i)
2258 // Expand the variables in the argument.
2259 value = i->Value;
2260 this->ExpandVariablesInString(value, false, false, false,
2261 i->FilePath, i->Line,
2262 false, true);
2264 // If the argument is quoted, it should be one argument.
2265 // Otherwise, it may be a list of arguments.
2266 if(i->Quoted)
2268 outArgs.push_back(value);
2270 else
2272 cmSystemTools::ExpandListArgument(value, outArgs);
2277 void cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
2279 // loop over all function blockers to see if any block this command
2280 std::list<cmFunctionBlocker *>::reverse_iterator pos;
2281 for (pos = this->FunctionBlockers.rbegin();
2282 pos != this->FunctionBlockers.rend(); ++pos)
2284 if ((*pos)->ShouldRemove(lff, *this))
2286 cmFunctionBlocker* b = *pos;
2287 this->FunctionBlockers.remove(b);
2288 delete b;
2289 break;
2293 return;
2296 void cmMakefile::SetHomeDirectory(const char* dir)
2298 this->cmHomeDirectory = dir;
2299 cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
2300 this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
2301 if ( !this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR") )
2303 this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", this->GetHomeDirectory());
2307 void cmMakefile::SetHomeOutputDirectory(const char* lib)
2309 this->HomeOutputDirectory = lib;
2310 cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
2311 this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
2312 if ( !this->GetDefinition("CMAKE_CURRENT_BINARY_DIR") )
2314 this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
2315 this->GetHomeOutputDirectory());
2321 * Register the given cmData instance with its own name.
2323 void cmMakefile::RegisterData(cmData* data)
2325 std::string name = data->GetName();
2326 DataMapType::const_iterator d = this->DataMap.find(name);
2327 if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
2329 delete d->second;
2331 this->DataMap[name] = data;
2336 * Register the given cmData instance with the given name. This can be used
2337 * to register a NULL pointer.
2339 void cmMakefile::RegisterData(const char* name, cmData* data)
2341 DataMapType::const_iterator d = this->DataMap.find(name);
2342 if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
2344 delete d->second;
2346 this->DataMap[name] = data;
2351 * Lookup a cmData instance previously registered with the given name. If
2352 * the instance cannot be found, return NULL.
2354 cmData* cmMakefile::LookupData(const char* name) const
2356 DataMapType::const_iterator d = this->DataMap.find(name);
2357 if(d != this->DataMap.end())
2359 return d->second;
2361 else
2363 return 0;
2367 //----------------------------------------------------------------------------
2368 cmSourceFile* cmMakefile::GetSource(const char* sourceName)
2370 cmSourceFileLocation sfl(this, sourceName);
2371 for(std::vector<cmSourceFile*>::const_iterator
2372 sfi = this->SourceFiles.begin();
2373 sfi != this->SourceFiles.end(); ++sfi)
2375 cmSourceFile* sf = *sfi;
2376 if(sf->Matches(sfl))
2378 return sf;
2381 return 0;
2384 //----------------------------------------------------------------------------
2385 cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
2386 bool generated)
2388 if(cmSourceFile* esf = this->GetSource(sourceName))
2390 return esf;
2392 else
2394 cmSourceFile* sf = new cmSourceFile(this, sourceName);
2395 if(generated)
2397 sf->SetProperty("GENERATED", "1");
2399 this->SourceFiles.push_back(sf);
2400 return sf;
2404 void cmMakefile::EnableLanguage(std::vector<std::string> const & lang,
2405 bool optional)
2407 this->AddDefinition("CMAKE_CFG_INTDIR",
2408 this->LocalGenerator->GetGlobalGenerator()->GetCMakeCFGInitDirectory());
2409 this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this,
2410 optional);
2413 void cmMakefile::ExpandSourceListArguments(
2414 std::vector<std::string> const& arguments,
2415 std::vector<std::string>& newargs, unsigned int /* start */)
2417 // now expand the args
2418 unsigned int i;
2419 for(i = 0; i < arguments.size(); ++i)
2421 // List expansion will have been done already.
2422 newargs.push_back(arguments[i]);
2426 int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
2427 const char *projectName, const char *targetName,
2428 const std::vector<std::string> *cmakeArgs,
2429 std::string *output)
2431 // does the binary directory exist ? If not create it...
2432 if (!cmSystemTools::FileIsDirectory(bindir))
2434 cmSystemTools::MakeDirectory(bindir);
2437 // change to the tests directory and run cmake
2438 // use the cmake object instead of calling cmake
2439 std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
2440 cmSystemTools::ChangeDirectory(bindir);
2442 // make sure the same generator is used
2443 // use this program as the cmake to be run, it should not
2444 // be run that way but the cmake object requires a vailid path
2445 std::string cmakeCommand = this->GetDefinition("CMAKE_COMMAND");
2446 cmake cm;
2447 cm.SetIsInTryCompile(true);
2448 cmGlobalGenerator *gg = cm.CreateGlobalGenerator
2449 (this->LocalGenerator->GetGlobalGenerator()->GetName());
2450 if (!gg)
2452 cmSystemTools::Error(
2453 "Internal CMake error, TryCompile bad GlobalGenerator");
2454 // return to the original directory
2455 cmSystemTools::ChangeDirectory(cwd.c_str());
2456 return 1;
2458 cm.SetGlobalGenerator(gg);
2460 // do a configure
2461 cm.SetHomeDirectory(srcdir);
2462 cm.SetHomeOutputDirectory(bindir);
2463 cm.SetStartDirectory(srcdir);
2464 cm.SetStartOutputDirectory(bindir);
2465 cm.SetCMakeCommand(cmakeCommand.c_str());
2466 cm.LoadCache();
2467 // if cmake args were provided then pass them in
2468 if (cmakeArgs)
2470 cm.SetCacheArgs(*cmakeArgs);
2472 // to save time we pass the EnableLanguage info directly
2473 gg->EnableLanguagesFromGenerator
2474 (this->LocalGenerator->GetGlobalGenerator());
2476 if (cm.Configure() != 0)
2478 cmSystemTools::Error(
2479 "Internal CMake error, TryCompile configure of cmake failed");
2480 // return to the original directory
2481 cmSystemTools::ChangeDirectory(cwd.c_str());
2482 return 1;
2485 if (cm.Generate() != 0)
2487 cmSystemTools::Error(
2488 "Internal CMake error, TryCompile generation of cmake failed");
2489 // return to the original directory
2490 cmSystemTools::ChangeDirectory(cwd.c_str());
2491 return 1;
2494 // finally call the generator to actually build the resulting project
2495 int ret =
2496 this->LocalGenerator->GetGlobalGenerator()->TryCompile(srcdir,bindir,
2497 projectName,
2498 targetName,
2499 output,
2500 this);
2502 cmSystemTools::ChangeDirectory(cwd.c_str());
2503 return ret;
2506 cmake *cmMakefile::GetCMakeInstance() const
2508 if ( this->LocalGenerator && this->LocalGenerator->GetGlobalGenerator() )
2510 return this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
2512 return 0;
2515 #ifdef CMAKE_BUILD_WITH_CMAKE
2516 cmVariableWatch *cmMakefile::GetVariableWatch() const
2518 if ( this->GetCMakeInstance() &&
2519 this->GetCMakeInstance()->GetVariableWatch() )
2521 return this->GetCMakeInstance()->GetVariableWatch();
2523 return 0;
2525 #endif
2527 void cmMakefile::AddMacro(const char* name, const char* signature)
2529 if ( !name || !signature )
2531 return;
2533 this->MacrosMap[name] = signature;
2536 void cmMakefile::GetListOfMacros(std::string& macros)
2538 StringStringMap::iterator it;
2539 macros = "";
2540 int cc = 0;
2541 for ( it = this->MacrosMap.begin(); it != this->MacrosMap.end(); ++it )
2543 if ( cc > 0 )
2545 macros += ";";
2547 macros += it->first;
2548 cc ++;
2552 cmCacheManager *cmMakefile::GetCacheManager() const
2554 return this->GetCMakeInstance()->GetCacheManager();
2557 void cmMakefile::DisplayStatus(const char* message, float s)
2559 this->GetLocalGenerator()->GetGlobalGenerator()
2560 ->GetCMakeInstance()->UpdateProgress(message, s);
2563 std::string cmMakefile::GetModulesFile(const char* filename)
2565 std::vector<std::string> modulePath;
2566 const char* def = this->GetDefinition("CMAKE_MODULE_PATH");
2567 if(def)
2569 cmSystemTools::ExpandListArgument(def, modulePath);
2572 // Also search in the standard modules location.
2573 def = this->GetDefinition("CMAKE_ROOT");
2574 if(def)
2576 std::string rootModules = def;
2577 rootModules += "/Modules";
2578 modulePath.push_back(rootModules);
2580 //std::string Look through the possible module directories.
2581 for(std::vector<std::string>::iterator i = modulePath.begin();
2582 i != modulePath.end(); ++i)
2584 std::string itempl = *i;
2585 cmSystemTools::ConvertToUnixSlashes(itempl);
2586 itempl += "/";
2587 itempl += filename;
2588 if(cmSystemTools::FileExists(itempl.c_str()))
2590 return itempl;
2593 return "";
2596 void cmMakefile::ConfigureString(const std::string& input,
2597 std::string& output, bool atOnly,
2598 bool escapeQuotes)
2600 // Split input to handle one line at a time.
2601 std::string::const_iterator lineStart = input.begin();
2602 while(lineStart != input.end())
2604 // Find the end of this line.
2605 std::string::const_iterator lineEnd = lineStart;
2606 while(lineEnd != input.end() && *lineEnd != '\n')
2608 ++lineEnd;
2611 // Copy the line.
2612 std::string line(lineStart, lineEnd);
2614 // Skip the newline character.
2615 bool haveNewline = (lineEnd != input.end());
2616 if(haveNewline)
2618 ++lineEnd;
2621 // Replace #cmakedefine instances.
2622 if(this->cmDefineRegex.find(line))
2624 const char* def =
2625 this->GetDefinition(this->cmDefineRegex.match(1).c_str());
2626 if(!cmSystemTools::IsOff(def))
2628 cmSystemTools::ReplaceString(line, "#cmakedefine", "#define");
2629 output += line;
2631 else
2633 output += "/* #undef ";
2634 output += this->cmDefineRegex.match(1);
2635 output += " */";
2638 else if(this->cmDefine01Regex.find(line))
2640 const char* def =
2641 this->GetDefinition(this->cmDefine01Regex.match(1).c_str());
2642 cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define");
2643 output += line;
2644 if(!cmSystemTools::IsOff(def))
2646 output += " 1";
2648 else
2650 output += " 0";
2653 else
2655 output += line;
2658 if(haveNewline)
2660 output += "\n";
2663 // Move to the next line.
2664 lineStart = lineEnd;
2667 // Perform variable replacements.
2668 this->ExpandVariablesInString(output, escapeQuotes, true,
2669 atOnly, 0, -1, true);
2672 int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
2673 bool copyonly, bool atOnly, bool escapeQuotes)
2675 int res = 1;
2676 if ( !this->CanIWriteThisFile(outfile) )
2678 cmSystemTools::Error("Attempt to write file: ",
2679 outfile, " into a source directory.");
2680 return 0;
2682 if ( !cmSystemTools::FileExists(infile) )
2684 cmSystemTools::Error("File ", infile, " does not exist.");
2685 return 0;
2687 std::string soutfile = outfile;
2688 std::string sinfile = infile;
2689 this->AddCMakeDependFile(infile);
2690 cmSystemTools::ConvertToUnixSlashes(soutfile);
2691 mode_t perm = 0;
2692 cmSystemTools::GetPermissions(sinfile.c_str(), perm);
2693 std::string::size_type pos = soutfile.rfind('/');
2694 if(pos != std::string::npos)
2696 std::string path = soutfile.substr(0, pos);
2697 cmSystemTools::MakeDirectory(path.c_str());
2700 if(copyonly)
2702 if ( !cmSystemTools::CopyFileIfDifferent(sinfile.c_str(),
2703 soutfile.c_str()))
2705 return 0;
2708 else
2710 std::string tempOutputFile = soutfile;
2711 tempOutputFile += ".tmp";
2712 std::ofstream fout(tempOutputFile.c_str());
2713 if(!fout)
2715 cmSystemTools::Error(
2716 "Could not open file for write in copy operation ",
2717 tempOutputFile.c_str());
2718 cmSystemTools::ReportLastSystemError("");
2719 return 0;
2721 std::ifstream fin(sinfile.c_str());
2722 if(!fin)
2724 cmSystemTools::Error("Could not open file for read in copy operation ",
2725 sinfile.c_str());
2726 return 0;
2729 // now copy input to output and expand variables in the
2730 // input file at the same time
2731 std::string inLine;
2732 std::string outLine;
2733 while( cmSystemTools::GetLineFromStream(fin, inLine) )
2735 outLine = "";
2736 this->ConfigureString(inLine, outLine, atOnly, escapeQuotes);
2737 fout << outLine.c_str() << "\n";
2739 // close the files before attempting to copy
2740 fin.close();
2741 fout.close();
2742 if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
2743 soutfile.c_str()) )
2745 res = 0;
2747 else
2749 cmSystemTools::SetPermissions(soutfile.c_str(), perm);
2751 cmSystemTools::RemoveFile(tempOutputFile.c_str());
2753 return res;
2756 void cmMakefile::AddWrittenFile(const char* file)
2757 { this->GetCMakeInstance()->AddWrittenFile(file); }
2759 bool cmMakefile::HasWrittenFile(const char* file)
2760 { return this->GetCMakeInstance()->HasWrittenFile(file); }
2762 bool cmMakefile::CheckInfiniteLoops()
2764 std::vector<std::string>::iterator it;
2765 for ( it = this->ListFiles.begin();
2766 it != this->ListFiles.end();
2767 ++ it )
2769 if ( this->HasWrittenFile(it->c_str()) )
2771 cmOStringStream str;
2772 str << "File " << it->c_str() <<
2773 " is written by WRITE_FILE (or FILE WRITE) command and should "
2774 "not be used as input to CMake. Please use CONFIGURE_FILE to "
2775 "be safe. Refer to the note next to FILE WRITE command.";
2776 cmSystemTools::Error(str.str().c_str());
2777 return false;
2780 return true;
2783 void cmMakefile::SetProperty(const char* prop, const char* value)
2785 if (!prop)
2787 return;
2790 // handle special props
2791 std::string propname = prop;
2792 if ( propname == "INCLUDE_DIRECTORIES" )
2794 std::vector<std::string> varArgsExpanded;
2795 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2796 this->SetIncludeDirectories(varArgsExpanded);
2797 return;
2800 if ( propname == "LINK_DIRECTORIES" )
2802 std::vector<std::string> varArgsExpanded;
2803 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2804 this->SetLinkDirectories(varArgsExpanded);
2805 return;
2808 if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
2810 this->SetIncludeRegularExpression(value);
2811 return;
2814 if ( propname == "ADDITIONAL_MAKE_CLEAN_FILES" )
2816 // This property is not inherrited
2817 if ( strcmp(this->GetCurrentDirectory(),
2818 this->GetStartDirectory()) != 0 )
2820 return;
2824 this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
2827 void cmMakefile::AppendProperty(const char* prop, const char* value)
2829 if (!prop)
2831 return;
2834 // handle special props
2835 std::string propname = prop;
2836 if ( propname == "INCLUDE_DIRECTORIES" )
2838 std::vector<std::string> varArgsExpanded;
2839 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2840 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
2841 vi != varArgsExpanded.end(); ++vi)
2843 this->AddIncludeDirectory(vi->c_str());
2845 return;
2848 if ( propname == "LINK_DIRECTORIES" )
2850 std::vector<std::string> varArgsExpanded;
2851 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2852 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
2853 vi != varArgsExpanded.end(); ++vi)
2855 this->AddLinkDirectory(vi->c_str());
2857 return;
2860 this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY);
2863 const char *cmMakefile::GetPropertyOrDefinition(const char* prop)
2865 const char *ret = this->GetProperty(prop, cmProperty::DIRECTORY);
2866 if (!ret)
2868 ret = this->GetDefinition(prop);
2870 return ret;
2873 const char *cmMakefile::GetProperty(const char* prop)
2875 return this->GetProperty(prop, cmProperty::DIRECTORY);
2878 const char *cmMakefile::GetProperty(const char* prop,
2879 cmProperty::ScopeType scope)
2881 // watch for specific properties
2882 static std::string output;
2883 output = "";
2884 if (!strcmp("PARENT_DIRECTORY",prop))
2886 output = this->LocalGenerator->GetParent()
2887 ->GetMakefile()->GetStartDirectory();
2888 return output.c_str();
2890 else if (!strcmp("INCLUDE_REGULAR_EXPRESSION",prop) )
2892 output = this->GetIncludeRegularExpression();
2893 return output.c_str();
2895 else if (!strcmp("LISTFILE_STACK",prop))
2897 for (std::deque<cmStdString>::iterator i = this->ListFileStack.begin();
2898 i != this->ListFileStack.end(); ++i)
2900 if (i != this->ListFileStack.begin())
2902 output += ";";
2904 output += *i;
2906 return output.c_str();
2908 else if (!strcmp("VARIABLES",prop) || !strcmp("CACHE_VARIABLES",prop))
2910 int cacheonly = 0;
2911 if ( !strcmp("CACHE_VARIABLES",prop) )
2913 cacheonly = 1;
2915 std::vector<std::string> vars = this->GetDefinitions(cacheonly);
2916 for (unsigned int cc = 0; cc < vars.size(); cc ++ )
2918 if ( cc > 0 )
2920 output += ";";
2922 output += vars[cc];
2924 return output.c_str();
2926 else if (!strcmp("MACROS",prop))
2928 this->GetListOfMacros(output);
2929 return output.c_str();
2931 else if (!strcmp("DEFINITIONS",prop))
2933 output = this->GetDefineFlags();
2934 return output.c_str();
2936 else if (!strcmp("INCLUDE_DIRECTORIES",prop) )
2938 cmOStringStream str;
2939 for (std::vector<std::string>::const_iterator
2940 it = this->GetIncludeDirectories().begin();
2941 it != this->GetIncludeDirectories().end();
2942 ++ it )
2944 if ( it != this->GetIncludeDirectories().begin())
2946 str << ";";
2948 str << it->c_str();
2950 output = str.str();
2951 return output.c_str();
2953 else if (!strcmp("LINK_DIRECTORIES",prop))
2955 cmOStringStream str;
2956 for (std::vector<std::string>::const_iterator
2957 it = this->GetLinkDirectories().begin();
2958 it != this->GetLinkDirectories().end();
2959 ++ it )
2961 if ( it != this->GetLinkDirectories().begin())
2963 str << ";";
2965 str << it->c_str();
2967 output = str.str();
2968 return output.c_str();
2971 bool chain = false;
2972 const char *retVal =
2973 this->Properties.GetPropertyValue(prop, scope, chain);
2974 if (chain)
2976 if(this->LocalGenerator->GetParent())
2978 return this->LocalGenerator->GetParent()->GetMakefile()->
2979 GetProperty(prop, scope);
2981 return this->GetCMakeInstance()->GetProperty(prop,scope);
2984 return retVal;
2987 bool cmMakefile::GetPropertyAsBool(const char* prop)
2989 return cmSystemTools::IsOn(this->GetProperty(prop));
2993 cmTarget* cmMakefile::FindTarget(const char* name)
2995 cmTargets& tgts = this->GetTargets();
2997 cmTargets::iterator i = tgts.find ( name );
2998 if ( i != tgts.end() )
3000 return &i->second;
3003 return 0;
3006 cmTest* cmMakefile::CreateTest(const char* testName)
3008 if ( !testName )
3010 return 0;
3012 cmTest* test = this->GetTest(testName);
3013 if ( test )
3015 return test;
3017 test = new cmTest;
3018 test->SetName(testName);
3019 test->SetMakefile(this);
3020 this->Tests.push_back(test);
3021 return test;
3024 cmTest* cmMakefile::GetTest(const char* testName) const
3026 if ( !testName )
3028 return 0;
3030 std::vector<cmTest*>::const_iterator it;
3031 for ( it = this->Tests.begin(); it != this->Tests.end(); ++ it )
3033 if ( strcmp((*it)->GetName(), testName) == 0 )
3035 return *it;
3038 return 0;
3041 const std::vector<cmTest*> *cmMakefile::GetTests() const
3043 return &this->Tests;
3046 std::vector<cmTest*> *cmMakefile::GetTests()
3048 return &this->Tests;
3051 std::string cmMakefile::GetListFileStack()
3053 cmOStringStream tmp;
3054 size_t depth = this->ListFileStack.size();
3055 if (depth > 0)
3057 std::deque<cmStdString>::iterator it = this->ListFileStack.end();
3060 if (depth != this->ListFileStack.size())
3062 tmp << "\n ";
3064 --it;
3065 tmp << "[";
3066 tmp << depth;
3067 tmp << "]\t";
3068 tmp << *it;
3069 depth--;
3071 while (it != this->ListFileStack.begin());
3073 return tmp.str();
3077 void cmMakefile::PushScope()
3079 // Get the index of the next stack entry.
3080 std::vector<DefinitionMap>::size_type index = this->DefinitionStack.size();
3082 // Allocate a new stack entry.
3083 this->DefinitionStack.push_back(DefinitionMap());
3085 // Copy the previous top to the new top.
3086 this->DefinitionStack[index] = this->DefinitionStack[index-1];
3089 void cmMakefile::PopScope()
3091 this->DefinitionStack.pop_back();
3094 void cmMakefile::RaiseScope(const char *var, const char *varDef)
3096 if (!var || !strlen(var))
3098 return;
3101 // multiple scopes in this directory?
3102 if (this->DefinitionStack.size() > 1)
3104 if(varDef)
3106 this->DefinitionStack[this->DefinitionStack.size()-2][var] = varDef;
3108 else
3110 this->DefinitionStack[this->DefinitionStack.size()-2].erase(var);
3113 // otherwise do the parent (if one exists)
3114 else if (this->LocalGenerator->GetParent())
3116 cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
3117 if (parent)
3119 if(varDef)
3121 parent->AddDefinition(var,varDef);
3123 else
3125 parent->RemoveDefinition(var);
3132 // define properties
3133 void cmMakefile::DefineProperties(cmake *cm)
3135 cm->DefineProperty
3136 ("ADDITIONAL_MAKE_CLEAN_FILES", cmProperty::DIRECTORY,
3137 "Additional files to clean during the make clean stage.",
3138 "A list of files that will be cleaned as a part of the "
3139 "\"make clean\" stage. ");
3141 cm->DefineProperty
3142 ("CLEAN_NO_CUSTOM", cmProperty::DIRECTORY,
3143 "Should the output of custom commands be left.",
3144 "If this is true then the outputs of custom commands for this "
3145 "directory will not be removed during the \"make clean\" stage. ");
3147 cm->DefineProperty
3148 ("LISTFILE_STACK", cmProperty::DIRECTORY,
3149 "The current stack of listfiles being processed.",
3150 "This property is mainly useful when trying to debug errors "
3151 "in your CMake scripts. It returns a list of what list files "
3152 "are currently being processed, in order. So if one listfile "
3153 "does an INCLUDE command then that is effectively pushing "
3154 "the included listfile onto the stack.");
3156 cm->DefineProperty
3157 ("TEST_INCLUDE_FILE", cmProperty::DIRECTORY,
3158 "A cmake file that will be included when ctest is run.",
3159 "If you specify TEST_INCLUDE_FILE, that file will be "
3160 "included and processed when ctest is run on the directory.");
3162 cm->DefineProperty
3163 ("COMPILE_DEFINITIONS", cmProperty::DIRECTORY,
3164 "Preprocessor definitions for compiling a directory's sources.",
3165 "The COMPILE_DEFINITIONS property may be set to a list of preprocessor "
3166 "definitions using the syntax VAR or VAR=value. Function-style "
3167 "definitions are not supported. CMake will automatically escape "
3168 "the value correctly for the native build system (note that CMake "
3169 "language syntax may require escapes to specify some values). "
3170 "This property may be set on a per-configuration basis using the name "
3171 "COMPILE_DEFINITIONS_<CONFIG> where <CONFIG> is an upper-case name "
3172 "(ex. \"COMPILE_DEFINITIONS_DEBUG\"). "
3173 "This property will be initialized in each directory by its value "
3174 "in the directory's parent.\n"
3175 "CMake will automatically drop some definitions that "
3176 "are not supported by the native build tool. "
3177 "The VS6 IDE does not support definitions with values "
3178 "(but NMake does).\n"
3179 "Dislaimer: Most native build tools have poor support for escaping "
3180 "certain values. CMake has work-arounds for many cases but some "
3181 "values may just not be possible to pass correctly. If a value "
3182 "does not seem to be escaped correctly, do not attempt to "
3183 "work-around the problem by adding escape sequences to the value. "
3184 "Your work-around may break in a future version of CMake that "
3185 "has improved escape support. Instead consider defining the macro "
3186 "in a (configured) header file. Then report the limitation.");
3188 cm->DefineProperty
3189 ("COMPILE_DEFINITIONS_<CONFIG>", cmProperty::DIRECTORY,
3190 "Per-configuration preprocessor definitions in a directory.",
3191 "This is the configuration-specific version of COMPILE_DEFINITIONS. "
3192 "This property will be initialized in each directory by its value "
3193 "in the directory's parent.\n");
3195 cm->DefineProperty
3196 ("EXCLUDE_FROM_ALL", cmProperty::DIRECTORY,
3197 "Exclude the directory from the all target of its parent.",
3198 "A property on a directory that indicates if its targets are excluded "
3199 "from the default build target. If it is not, then with a Makefile "
3200 "for example typing make will cause the targets to be built. "
3201 "The same concept applies to the default build of other generators.",
3202 false);
3205 //----------------------------------------------------------------------------
3206 cmTarget*
3207 cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type)
3209 // Create the target.
3210 cmsys::auto_ptr<cmTarget> target(new cmTarget);
3211 target->SetType(type, name);
3212 target->SetMakefile(this);
3213 target->MarkAsImported();
3215 // Add to the set of available imported targets.
3216 this->ImportedTargets[name] = target.get();
3218 // Transfer ownership to this cmMakefile object.
3219 this->ImportedTargetsOwned.push_back(target.get());
3220 return target.release();
3223 //----------------------------------------------------------------------------
3224 cmTarget* cmMakefile::FindTargetToUse(const char* name)
3226 // Look for an imported target. These take priority because they
3227 // are more local in scope and do not have to be globally unique.
3228 std::map<cmStdString, cmTarget*>::const_iterator
3229 imported = this->ImportedTargets.find(name);
3230 if(imported != this->ImportedTargets.end())
3232 return imported->second;
3235 // Look for a target built in this project.
3236 return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name);
3239 //----------------------------------------------------------------------------
3240 bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
3241 bool isCustom)
3243 if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
3245 // The name given conflicts with an existing target. Produce an
3246 // error in a compatible way.
3247 if(existing->IsImported())
3249 // Imported targets were not supported in previous versions.
3250 // This is new code, so we can make it an error.
3251 cmOStringStream e;
3252 e << "cannot create target \"" << name
3253 << "\" because an imported target with the same name already exists.";
3254 msg = e.str();
3255 return false;
3257 else
3259 // target names must be globally unique
3260 switch (this->GetPolicyStatus(cmPolicies::CMP_0002))
3262 case cmPolicies::WARN:
3263 this->IssueWarning(this->GetPolicies()->
3264 GetPolicyWarning(cmPolicies::CMP_0002));
3265 case cmPolicies::OLD:
3266 return true;
3267 case cmPolicies::REQUIRED_IF_USED:
3268 case cmPolicies::REQUIRED_ALWAYS:
3269 this->IssueError(
3270 this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP_0002)
3272 return true;
3273 case cmPolicies::NEW:
3274 break;
3277 // The conflict is with a non-imported target.
3278 // Allow this if the user has requested support.
3279 cmake* cm =
3280 this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
3281 if(isCustom && existing->GetType() == cmTarget::UTILITY &&
3282 this != existing->GetMakefile() &&
3283 cm->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
3285 return true;
3288 // Produce an error that tells the user how to work around the
3289 // problem.
3290 cmOStringStream e;
3291 e << "cannot create target \"" << name
3292 << "\" because another target with the same name already exists. "
3293 << "The existing target is ";
3294 switch(existing->GetType())
3296 case cmTarget::EXECUTABLE:
3297 e << "an executable ";
3298 break;
3299 case cmTarget::STATIC_LIBRARY:
3300 e << "a static library ";
3301 break;
3302 case cmTarget::SHARED_LIBRARY:
3303 e << "a shared library ";
3304 break;
3305 case cmTarget::MODULE_LIBRARY:
3306 e << "a module library ";
3307 break;
3308 case cmTarget::UTILITY:
3309 e << "a custom target ";
3310 break;
3311 default: break;
3313 e << "created in source directory \""
3314 << existing->GetMakefile()->GetCurrentDirectory() << "\". "
3315 << "See documentation for policy CMP_0002 for more details.";
3316 msg = e.str();
3317 return false;
3320 return true;
3323 cmPolicies::PolicyStatus cmMakefile
3324 ::GetPolicyStatus(cmPolicies::PolicyID id)
3326 cmPolicies::PolicyStatus status = cmPolicies::REQUIRED_IF_USED;
3327 PolicyMap::iterator mappos;
3328 int vecpos;
3329 bool done = false;
3331 // check our policy stack first
3332 for (vecpos = static_cast<int>(this->PolicyStack.size()) - 1;
3333 vecpos >= 0 && !done; vecpos--)
3335 mappos = this->PolicyStack[vecpos].find(id);
3336 if (mappos != this->PolicyStack[vecpos].end())
3338 status = mappos->second;
3339 done = true;
3343 // if not found then
3344 if (!done)
3346 // pass the buck to our parent if we have one
3347 if (this->LocalGenerator->GetParent())
3349 cmMakefile *parent =
3350 this->LocalGenerator->GetParent()->GetMakefile();
3351 return parent->GetPolicyStatus(id);
3353 // otherwise use the default
3354 else
3356 status = this->GetPolicies()->GetPolicyStatus(id);
3360 // warn if we see a REQUIRED_IF_USED above a OLD or WARN
3361 if (!this->GetPolicies()->IsValidUsedPolicyStatus(id,status))
3363 return cmPolicies::REQUIRED_IF_USED;
3366 return status;
3369 bool cmMakefile::SetPolicy(const char *id,
3370 cmPolicies::PolicyStatus status)
3372 cmPolicies::PolicyID pid;
3373 if (!this->GetPolicies()->GetPolicyID(id, /* out */ pid))
3375 cmSystemTools::Error("Invalid policy string used. Invalid string was "
3376 , id);
3377 return false;
3379 return this->SetPolicy(pid,status);
3382 bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
3383 cmPolicies::PolicyStatus status)
3385 // setting a REQUIRED_ALWAYS policy to WARN or OLD is an insta error
3386 if (this->GetPolicies()->
3387 IsValidPolicyStatus(id,status))
3389 this->PolicyStack.back()[id] = status;
3391 // Special hook for presenting compatibility variable as soon as
3392 // the user requests it.
3393 if(id == cmPolicies::CMP_0001 &&
3394 (status == cmPolicies::WARN || status == cmPolicies::OLD))
3396 if(!(this->GetCacheManager()
3397 ->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
3399 // Set it to 2.4 because that is the last version where the
3400 // variable had meaning.
3401 this->AddCacheDefinition
3402 ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
3403 "For backwards compatibility, what version of CMake "
3404 "commands and "
3405 "syntax should this version of CMake try to support.",
3406 cmCacheManager::STRING);
3410 return true;
3412 return false;
3415 bool cmMakefile::PushPolicy()
3417 // Allocate a new stack entry.
3418 this->PolicyStack.push_back(PolicyMap());
3419 return true;
3422 bool cmMakefile::PopPolicy(bool reportError)
3424 if(this->PolicyStack.size() == 1)
3426 if(reportError)
3428 cmSystemTools::Error("Attempt to pop the policy stack past "
3429 "it's beginning.");
3431 return false;
3433 this->PolicyStack.pop_back();
3434 return true;
3437 bool cmMakefile::SetPolicyVersion(const char *version)
3439 return this->GetCMakeInstance()->GetPolicies()->
3440 ApplyPolicyVersion(this,version);
3443 cmPolicies *cmMakefile::GetPolicies()
3445 if (!this->GetCMakeInstance())
3447 return 0;
3449 return this->GetCMakeInstance()->GetPolicies();