Initial commit.
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmMakefile.cxx
blobebbabf0c24af80c5492ca651f58b2938b9befc7f
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmMakefile.cxx,v $
5 Language: C++
6 Date: $Date: 2008/01/30 13:37:38 $
7 Version: $Revision: 1.432 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmMakefile.h"
18 #include "cmVersion.h"
19 #include "cmCommand.h"
20 #include "cmSourceFile.h"
21 #include "cmSourceFileLocation.h"
22 #include "cmSystemTools.h"
23 #include "cmGlobalGenerator.h"
24 #include "cmLocalGenerator.h"
25 #include "cmCommands.h"
26 #include "cmCacheManager.h"
27 #include "cmFunctionBlocker.h"
28 #include "cmListFileCache.h"
29 #include "cmCommandArgumentParserHelper.h"
30 #include "cmTest.h"
31 #ifdef CMAKE_BUILD_WITH_CMAKE
32 # include "cmVariableWatch.h"
33 #endif
34 #include "cmInstallGenerator.h"
35 #include "cmake.h"
36 #include <stdlib.h> // required for atoi
38 #include <cmsys/RegularExpression.hxx>
40 #include <cmsys/auto_ptr.hxx>
42 #include <ctype.h> // for isspace
44 // default is not to be building executables
45 cmMakefile::cmMakefile()
47 this->DefinitionStack.push_back(DefinitionMap());
49 // Setup the default include file regular expression (match everything).
50 this->IncludeFileRegularExpression = "^.*$";
51 // Setup the default include complaint regular expression (match nothing).
52 this->ComplainFileRegularExpression = "^$";
53 // Source and header file extensions that we can handle
55 // Set up a list of source and header extensions
56 // these are used to find files when the extension
57 // is not given
58 // The "c" extension MUST precede the "C" extension.
59 this->SourceFileExtensions.push_back( "c" );
60 this->SourceFileExtensions.push_back( "C" );
62 this->SourceFileExtensions.push_back( "c++" );
63 this->SourceFileExtensions.push_back( "cc" );
64 this->SourceFileExtensions.push_back( "cpp" );
65 this->SourceFileExtensions.push_back( "cxx" );
66 this->SourceFileExtensions.push_back( "m" );
67 this->SourceFileExtensions.push_back( "M" );
68 this->SourceFileExtensions.push_back( "mm" );
70 this->HeaderFileExtensions.push_back( "h" );
71 this->HeaderFileExtensions.push_back( "hh" );
72 this->HeaderFileExtensions.push_back( "h++" );
73 this->HeaderFileExtensions.push_back( "hm" );
74 this->HeaderFileExtensions.push_back( "hpp" );
75 this->HeaderFileExtensions.push_back( "hxx" );
76 this->HeaderFileExtensions.push_back( "in" );
77 this->HeaderFileExtensions.push_back( "txx" );
79 this->DefineFlags = " ";
80 this->LocalGenerator = 0;
82 #if defined(CMAKE_BUILD_WITH_CMAKE)
83 this->AddSourceGroup("", "^.*$");
84 this->AddSourceGroup
85 ("Source Files",
86 "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat)$");
87 this->AddSourceGroup("Header Files",
88 "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
89 this->AddSourceGroup("CMake Rules", "\\.rule$");
90 this->AddSourceGroup("Resources", "\\.plist$");
91 #endif
92 this->AddDefaultDefinitions();
93 this->Initialize();
94 this->PreOrder = false;
97 cmMakefile::cmMakefile(const cmMakefile& mf)
99 this->Prefix = mf.Prefix;
100 this->AuxSourceDirectories = mf.AuxSourceDirectories;
101 this->cmStartDirectory = mf.cmStartDirectory;
102 this->StartOutputDirectory = mf.StartOutputDirectory;
103 this->cmHomeDirectory = mf.cmHomeDirectory;
104 this->HomeOutputDirectory = mf.HomeOutputDirectory;
105 this->cmCurrentListFile = mf.cmCurrentListFile;
106 this->ProjectName = mf.ProjectName;
107 this->Targets = mf.Targets;
108 this->SourceFiles = mf.SourceFiles;
109 this->Tests = mf.Tests;
110 this->IncludeDirectories = mf.IncludeDirectories;
111 this->LinkDirectories = mf.LinkDirectories;
112 this->SystemIncludeDirectories = mf.SystemIncludeDirectories;
113 this->ListFiles = mf.ListFiles;
114 this->OutputFiles = mf.OutputFiles;
115 this->LinkLibraries = mf.LinkLibraries;
116 this->InstallGenerators = mf.InstallGenerators;
117 this->IncludeFileRegularExpression = mf.IncludeFileRegularExpression;
118 this->ComplainFileRegularExpression = mf.ComplainFileRegularExpression;
119 this->SourceFileExtensions = mf.SourceFileExtensions;
120 this->HeaderFileExtensions = mf.HeaderFileExtensions;
121 this->DefineFlags = mf.DefineFlags;
123 #if defined(CMAKE_BUILD_WITH_CMAKE)
124 this->SourceGroups = mf.SourceGroups;
125 #endif
127 this->DefinitionStack.push_back(mf.DefinitionStack.back());
128 this->LocalGenerator = mf.LocalGenerator;
129 this->FunctionBlockers = mf.FunctionBlockers;
130 this->DataMap = mf.DataMap;
131 this->MacrosMap = mf.MacrosMap;
132 this->SubDirectoryOrder = mf.SubDirectoryOrder;
133 this->TemporaryDefinitionKey = mf.TemporaryDefinitionKey;
134 this->Properties = mf.Properties;
135 this->PreOrder = mf.PreOrder;
136 this->ListFileStack = mf.ListFileStack;
137 this->Initialize();
140 //----------------------------------------------------------------------------
141 void cmMakefile::Initialize()
143 this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
144 this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
145 this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
148 unsigned int cmMakefile::GetCacheMajorVersion()
150 return this->GetCacheManager()->GetCacheMajorVersion();
153 unsigned int cmMakefile::GetCacheMinorVersion()
155 return this->GetCacheManager()->GetCacheMinorVersion();
158 bool cmMakefile::NeedCacheCompatibility(int major, int minor)
160 return this->GetCacheManager()->NeedCacheCompatibility(major, minor);
163 cmMakefile::~cmMakefile()
165 for(std::vector<cmInstallGenerator*>::iterator
166 i = this->InstallGenerators.begin();
167 i != this->InstallGenerators.end(); ++i)
169 delete *i;
171 for(std::vector<cmSourceFile*>::iterator i = this->SourceFiles.begin();
172 i != this->SourceFiles.end(); ++i)
174 delete *i;
176 for(std::vector<cmTest*>::iterator i = this->Tests.begin();
177 i != this->Tests.end(); ++i)
179 delete *i;
181 for(std::vector<cmTarget*>::iterator
182 i = this->ImportedTargetsOwned.begin();
183 i != this->ImportedTargetsOwned.end(); ++i)
185 delete *i;
187 for(unsigned int i=0; i < this->UsedCommands.size(); i++)
189 delete this->UsedCommands[i];
191 for(DataMapType::const_iterator d = this->DataMap.begin();
192 d != this->DataMap.end(); ++d)
194 if(d->second)
196 delete d->second;
199 std::list<cmFunctionBlocker *>::iterator pos;
200 for (pos = this->FunctionBlockers.begin();
201 pos != this->FunctionBlockers.end(); ++pos)
203 cmFunctionBlocker* b = *pos;
204 delete b;
206 this->FunctionBlockers.clear();
209 void cmMakefile::PrintStringVector(const char* s,
210 const std::vector<std::string>& v) const
212 std::cout << s << ": ( \n";
213 for(std::vector<std::string>::const_iterator i = v.begin();
214 i != v.end(); ++i)
216 std::cout << (*i).c_str() << " ";
218 std::cout << " )\n";
221 void cmMakefile
222 ::PrintStringVector(const char* s,
223 const std::vector<std::pair<cmStdString, bool> >& v) const
225 std::cout << s << ": ( \n";
226 for(std::vector<std::pair<cmStdString, bool> >::const_iterator i
227 = v.begin(); i != v.end(); ++i)
229 std::cout << i->first.c_str() << " " << i->second;
231 std::cout << " )\n";
235 // call print on all the classes in the makefile
236 void cmMakefile::Print()
238 // print the class lists
239 std::cout << "classes:\n";
241 std::cout << " this->Targets: ";
242 for (cmTargets::iterator l = this->Targets.begin();
243 l != this->Targets.end(); l++)
245 std::cout << l->first << std::endl;
248 std::cout << " this->StartOutputDirectory; " <<
249 this->StartOutputDirectory.c_str() << std::endl;
250 std::cout << " this->HomeOutputDirectory; " <<
251 this->HomeOutputDirectory.c_str() << std::endl;
252 std::cout << " this->cmStartDirectory; " <<
253 this->cmStartDirectory.c_str() << std::endl;
254 std::cout << " this->cmHomeDirectory; " <<
255 this->cmHomeDirectory.c_str() << std::endl;
256 std::cout << " this->ProjectName; "
257 << this->ProjectName.c_str() << std::endl;
258 this->PrintStringVector("this->IncludeDirectories;",
259 this->IncludeDirectories);
260 this->PrintStringVector("this->LinkDirectories", this->LinkDirectories);
261 #if defined(CMAKE_BUILD_WITH_CMAKE)
262 for( std::vector<cmSourceGroup>::const_iterator i =
263 this->SourceGroups.begin(); i != this->SourceGroups.end(); ++i)
265 std::cout << "Source Group: " << i->GetName() << std::endl;
267 #endif
270 bool cmMakefile::CommandExists(const char* name) const
272 return this->GetCMakeInstance()->CommandExists(name);
275 bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
276 cmExecutionStatus &status)
278 bool result = true;
280 // quick return if blocked
281 if(this->IsFunctionBlocked(lff,status))
283 // No error.
284 return result;
287 std::string name = lff.Name;
289 // execute the command
290 cmCommand *rm =
291 this->GetCMakeInstance()->GetCommand(name.c_str());
292 if(rm)
294 const char* versionValue
295 = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
296 int major = 0;
297 int minor = 0;
298 if ( versionValue )
300 sscanf(versionValue, "%d.%d", &major, &minor);
302 if ( rm->IsDeprecated(major, minor) )
304 cmOStringStream error;
305 error << "Error in cmake code at\n"
306 << lff.FilePath << ":" << lff.Line << ":\n"
307 << rm->GetError() << std::endl
308 << " Called from: " << this->GetListFileStack().c_str();
309 cmSystemTools::Error(error.str().c_str());
310 return false;
312 cmCommand* usedCommand = rm->Clone();
313 usedCommand->SetMakefile(this);
314 bool keepCommand = false;
315 if(usedCommand->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() &&
316 (!this->GetCMakeInstance()->GetScriptMode() ||
317 usedCommand->IsScriptable()))
319 if(!usedCommand->InvokeInitialPass(lff.Arguments,status))
321 cmOStringStream error;
322 error << "Error in cmake code at\n"
323 << lff.FilePath << ":" << lff.Line << ":\n"
324 << usedCommand->GetError() << std::endl
325 << " Called from: " << this->GetListFileStack().c_str();
326 cmSystemTools::Error(error.str().c_str());
327 result = false;
328 if ( this->GetCMakeInstance()->GetScriptMode() )
330 cmSystemTools::SetFatalErrorOccured();
333 else
335 // use the command
336 keepCommand = true;
337 this->UsedCommands.push_back(usedCommand);
340 else if ( this->GetCMakeInstance()->GetScriptMode()
341 && !usedCommand->IsScriptable() )
343 cmOStringStream error;
344 error << "Error in cmake code at\n"
345 << lff.FilePath << ":" << lff.Line << ":\n"
346 << "Command " << usedCommand->GetName()
347 << "() is not scriptable" << std::endl;
348 cmSystemTools::Error(error.str().c_str());
349 result = false;
350 cmSystemTools::SetFatalErrorOccured();
352 // if the Cloned command was not used
353 // then delete it
354 if(!keepCommand)
356 delete usedCommand;
359 else
361 if(!cmSystemTools::GetFatalErrorOccured())
363 cmOStringStream error;
364 error << "Error in cmake code at\n"
365 << lff.FilePath << ":" << lff.Line << ":\n"
366 << "Unknown CMake command \"" << lff.Name.c_str() << "\".";
367 cmSystemTools::Error(error.str().c_str());
368 result = false;
369 cmSystemTools::SetFatalErrorOccured();
373 return result;
376 // Parse the given CMakeLists.txt file executing all commands
378 bool cmMakefile::ReadListFile(const char* filename_in,
379 const char *external_in,
380 std::string* fullPath)
382 std::string currentParentFile
383 = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
384 std::string currentFile
385 = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
386 this->AddDefinition("CMAKE_PARENT_LIST_FILE", filename_in);
388 // used to watch for blockers going out of scope
389 // e.g. mismatched IF statement
390 std::set<cmFunctionBlocker *> originalBlockers;
392 const char* external = 0;
393 std::string external_abs;
395 const char* filename = filename_in;
396 std::string filename_abs;
398 if (external_in)
400 external_abs =
401 cmSystemTools::CollapseFullPath(external_in,
402 this->cmStartDirectory.c_str());
403 external = external_abs.c_str();
404 if (filename_in)
406 filename_abs =
407 cmSystemTools::CollapseFullPath(filename_in,
408 this->cmStartDirectory.c_str());
409 filename = filename_abs.c_str();
413 // keep track of the current file being read
414 if (filename)
416 if(this->cmCurrentListFile != filename)
418 this->cmCurrentListFile = filename;
420 // loop over current function blockers and record them
421 std::list<cmFunctionBlocker *>::iterator pos;
422 for (pos = this->FunctionBlockers.begin();
423 pos != this->FunctionBlockers.end(); ++pos)
425 originalBlockers.insert(*pos);
429 // Now read the input file
430 const char *filenametoread= filename;
432 if( external)
434 filenametoread= external;
437 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
439 // try to see if the list file is the top most
440 // list file for a project, and if it is, then it
441 // must have a project command. If there is not
442 // one, then cmake will provide one via the
443 // cmListFileCache class.
444 bool requireProjectCommand = false;
445 if(!external && this->cmStartDirectory == this->cmHomeDirectory)
447 if(cmSystemTools::LowerCase(
448 cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt")
450 requireProjectCommand = true;
454 // push the listfile onto the stack
455 this->ListFileStack.push_back(filenametoread);
456 if(fullPath!=0)
458 *fullPath=filenametoread;
460 cmListFile cacheFile;
461 if( !cacheFile.ParseFile(filenametoread, requireProjectCommand) )
463 // pop the listfile off the stack
464 this->ListFileStack.pop_back();
465 if(fullPath!=0)
467 *fullPath = "";
469 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
470 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
471 return false;
473 // add this list file to the list of dependencies
474 this->ListFiles.push_back( filenametoread);
475 const size_t numberFunctions = cacheFile.Functions.size();
476 for(size_t i =0; i < numberFunctions; ++i)
478 cmExecutionStatus status;
479 this->ExecuteCommand(cacheFile.Functions[i],status);
480 if (status.GetReturnInvoked() ||
481 cmSystemTools::GetFatalErrorOccured() )
483 // pop the listfile off the stack
484 this->ListFileStack.pop_back();
485 this->AddDefinition("CMAKE_PARENT_LIST_FILE",
486 currentParentFile.c_str());
487 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
488 return true;
492 // send scope ended to and function blockers
493 if (filename)
495 // loop over all function blockers to see if any block this command
496 std::list<cmFunctionBlocker *>::iterator pos;
497 for (pos = this->FunctionBlockers.begin();
498 pos != this->FunctionBlockers.end(); ++pos)
500 // if this blocker was not in the original then send a
501 // scope ended message
502 if (originalBlockers.find(*pos) == originalBlockers.end())
504 (*pos)->ScopeEnded(*this);
509 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
510 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
512 // pop the listfile off the stack
513 this->ListFileStack.pop_back();
515 return true;
519 void cmMakefile::AddCommand(cmCommand* wg)
521 this->GetCMakeInstance()->AddCommand(wg);
524 // Set the make file
525 void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
527 this->LocalGenerator = lg;
530 void cmMakefile::FinalPass()
532 // do all the variable expansions here
533 this->ExpandVariables();
535 // give all the commands a chance to do something
536 // after the file has been parsed before generation
537 for(std::vector<cmCommand*>::iterator i = this->UsedCommands.begin();
538 i != this->UsedCommands.end(); ++i)
540 (*i)->FinalPass();
545 // Generate the output file
546 void cmMakefile::ConfigureFinalPass()
548 this->FinalPass();
549 const char* oldValue
550 = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
551 if (oldValue && atof(oldValue) <= 1.2)
553 cmSystemTools::Error("You have requested backwards compatibility "
554 "with CMake version 1.2 or earlier. This version "
555 "of CMake only supports backwards compatibility "
556 "with CMake 1.4 or later. For compatibility with "
557 "1.2 or earlier please use CMake 2.0");
559 for (cmTargets::iterator l = this->Targets.begin();
560 l != this->Targets.end(); l++)
562 l->second.AnalyzeLibDependencies(*this);
566 //----------------------------------------------------------------------------
567 void
568 cmMakefile::AddCustomCommandToTarget(const char* target,
569 const std::vector<std::string>& depends,
570 const cmCustomCommandLines& commandLines,
571 cmTarget::CustomCommandType type,
572 const char* comment,
573 const char* workingDir,
574 bool escapeOldStyle)
576 // Find the target to which to add the custom command.
577 cmTargets::iterator ti = this->Targets.find(target);
578 if(ti != this->Targets.end())
580 // Add the command to the appropriate build step for the target.
581 std::vector<std::string> no_output;
582 cmCustomCommand cc(no_output, depends, commandLines, comment, workingDir);
583 cc.SetEscapeOldStyle(escapeOldStyle);
584 switch(type)
586 case cmTarget::PRE_BUILD:
587 ti->second.GetPreBuildCommands().push_back(cc);
588 break;
589 case cmTarget::PRE_LINK:
590 ti->second.GetPreLinkCommands().push_back(cc);
591 break;
592 case cmTarget::POST_BUILD:
593 ti->second.GetPostBuildCommands().push_back(cc);
594 break;
599 //----------------------------------------------------------------------------
600 void
601 cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
602 const std::vector<std::string>& depends,
603 const char* main_dependency,
604 const cmCustomCommandLines& commandLines,
605 const char* comment,
606 const char* workingDir,
607 bool replace,
608 bool escapeOldStyle)
610 // Make sure there is at least one output.
611 if(outputs.empty())
613 cmSystemTools::Error("Attempt to add a custom rule with no output!");
614 return;
617 // Choose a source file on which to store the custom command.
618 cmSourceFile* file = 0;
619 if(main_dependency && main_dependency[0])
621 // The main dependency was specified. Use it unless a different
622 // custom command already used it.
623 file = this->GetSource(main_dependency);
624 if(file && file->GetCustomCommand() && !replace)
626 // The main dependency already has a custom command.
627 if(commandLines == file->GetCustomCommand()->GetCommandLines())
629 // The existing custom command is identical. Silently ignore
630 // the duplicate.
631 return;
633 else
635 // The existing custom command is different. We need to
636 // generate a rule file for this new command.
637 file = 0;
640 else
642 // The main dependency does not have a custom command or we are
643 // allowed to replace it. Use it to store the command.
644 file = this->GetOrCreateSource(main_dependency);
648 // Generate a rule file if the main dependency is not available.
649 if(!file)
651 // Construct a rule file associated with the first output produced.
652 std::string outName = outputs[0];
653 outName += ".rule";
655 // Check if the rule file already exists.
656 file = this->GetSource(outName.c_str());
657 if(file && file->GetCustomCommand() && !replace)
659 // The rule file already exists.
660 if(commandLines != file->GetCustomCommand()->GetCommandLines())
662 cmSystemTools::Error("Attempt to add a custom rule to output \"",
663 outName.c_str(),
664 "\" which already has a custom rule.");
666 return;
669 // Create a cmSourceFile for the rule file.
670 file = this->GetOrCreateSource(outName.c_str(), true);
673 // Always create the output sources and mark them generated.
674 for(std::vector<std::string>::const_iterator o = outputs.begin();
675 o != outputs.end(); ++o)
677 if(cmSourceFile* out = this->GetOrCreateSource(o->c_str(), true))
679 out->SetProperty("GENERATED", "1");
683 // Construct a complete list of dependencies.
684 std::vector<std::string> depends2(depends);
685 if(main_dependency && main_dependency[0])
687 depends2.push_back(main_dependency);
690 // Attach the custom command to the file.
691 if(file)
693 cmCustomCommand* cc =
694 new cmCustomCommand(outputs, depends2, commandLines,
695 comment, workingDir);
696 cc->SetEscapeOldStyle(escapeOldStyle);
697 file->SetCustomCommand(cc);
701 //----------------------------------------------------------------------------
702 void
703 cmMakefile::AddCustomCommandToOutput(const char* output,
704 const std::vector<std::string>& depends,
705 const char* main_dependency,
706 const cmCustomCommandLines& commandLines,
707 const char* comment,
708 const char* workingDir,
709 bool replace,
710 bool escapeOldStyle)
712 std::vector<std::string> outputs;
713 outputs.push_back(output);
714 this->AddCustomCommandToOutput(outputs, depends, main_dependency,
715 commandLines, comment, workingDir,
716 replace, escapeOldStyle);
719 //----------------------------------------------------------------------------
720 void
721 cmMakefile::AddCustomCommandOldStyle(const char* target,
722 const std::vector<std::string>& outputs,
723 const std::vector<std::string>& depends,
724 const char* source,
725 const cmCustomCommandLines& commandLines,
726 const char* comment)
728 // Translate the old-style signature to one of the new-style
729 // signatures.
730 if(strcmp(source, target) == 0)
732 // In the old-style signature if the source and target were the
733 // same then it added a post-build rule to the target. Preserve
734 // this behavior.
735 this->AddCustomCommandToTarget(target, depends, commandLines,
736 cmTarget::POST_BUILD, comment, 0);
737 return;
740 // Each output must get its own copy of this rule.
741 cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|"
742 "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
743 "hm|hpp|hxx|in|txx|inl)$");
744 for(std::vector<std::string>::const_iterator oi = outputs.begin();
745 oi != outputs.end(); ++oi)
747 // Get the name of this output.
748 const char* output = oi->c_str();
750 // Choose whether to use a main dependency.
751 if(sourceFiles.find(source))
753 // The source looks like a real file. Use it as the main dependency.
754 this->AddCustomCommandToOutput(output, depends, source,
755 commandLines, comment, 0);
757 else
759 // The source may not be a real file. Do not use a main dependency.
760 const char* no_main_dependency = 0;
761 std::vector<std::string> depends2 = depends;
762 depends2.push_back(source);
763 this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
764 commandLines, comment, 0);
767 // If the rule was added to the source (and not a .rule file),
768 // then add the source to the target to make sure the rule is
769 // included.
770 std::string sname = output;
771 sname += ".rule";
772 if(!this->GetSource(sname.c_str()))
774 if (this->Targets.find(target) != this->Targets.end())
776 this->Targets[target].AddSource(source);
778 else
780 cmSystemTools::Error("Attempt to add a custom rule to a target "
781 "that does not exist yet for target ", target);
782 return;
788 //----------------------------------------------------------------------------
789 void cmMakefile::AddUtilityCommand(const char* utilityName,
790 bool excludeFromAll,
791 const std::vector<std::string>& depends,
792 const char* workingDirectory,
793 const char* command,
794 const char* arg1,
795 const char* arg2,
796 const char* arg3,
797 const char* arg4)
799 // Construct the command line for the custom command.
800 cmCustomCommandLine commandLine;
801 commandLine.push_back(command);
802 if(arg1)
804 commandLine.push_back(arg1);
806 if(arg2)
808 commandLine.push_back(arg2);
810 if(arg3)
812 commandLine.push_back(arg3);
814 if(arg4)
816 commandLine.push_back(arg4);
818 cmCustomCommandLines commandLines;
819 commandLines.push_back(commandLine);
821 // Call the real signature of this method.
822 this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
823 depends, commandLines);
826 //----------------------------------------------------------------------------
827 void cmMakefile::AddUtilityCommand(const char* utilityName,
828 bool excludeFromAll,
829 const char* workingDirectory,
830 const std::vector<std::string>& depends,
831 const cmCustomCommandLines& commandLines,
832 bool escapeOldStyle, const char* comment)
834 // Create a target instance for this utility.
835 cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
836 if (excludeFromAll)
838 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
840 if(!comment)
842 // Use an empty comment to avoid generation of default comment.
843 comment = "";
846 // Store the custom command in the target.
847 std::string force = this->GetStartOutputDirectory();
848 force += cmake::GetCMakeFilesDirectory();
849 force += "/";
850 force += utilityName;
851 const char* no_main_dependency = 0;
852 bool no_replace = false;
853 this->AddCustomCommandToOutput(force.c_str(), depends,
854 no_main_dependency,
855 commandLines, comment,
856 workingDirectory, no_replace,
857 escapeOldStyle);
858 cmSourceFile* sf = target->AddSource(force.c_str());
860 // The output is not actually created so mark it symbolic.
861 if(sf)
863 sf->SetProperty("SYMBOLIC", "1");
865 else
867 cmSystemTools::Error("Could not get source file entry for ",
868 force.c_str());
872 void cmMakefile::AddDefineFlag(const char* flag)
874 if (!flag)
876 return;
879 // If this is really a definition, update COMPILE_DEFINITIONS.
880 if(this->ParseDefineFlag(flag, false))
882 return;
885 // remove any \n\r
886 std::string ret = flag;
887 std::string::size_type pos = 0;
888 while((pos = ret.find('\n', pos)) != std::string::npos)
890 ret[pos] = ' ';
891 pos++;
893 pos = 0;
894 while((pos = ret.find('\r', pos)) != std::string::npos)
896 ret[pos] = ' ';
897 pos++;
900 this->DefineFlags += " ";
901 this->DefineFlags += ret;
905 void cmMakefile::RemoveDefineFlag(const char* flag)
907 // Check the length of the flag to remove.
908 std::string::size_type len = strlen(flag);
909 if(len < 1)
911 return;
914 // If this is really a definition, update COMPILE_DEFINITIONS.
915 if(this->ParseDefineFlag(flag, true))
917 return;
920 // Remove all instances of the flag that are surrounded by
921 // whitespace or the beginning/end of the string.
922 for(std::string::size_type lpos = this->DefineFlags.find(flag, 0);
923 lpos != std::string::npos; lpos = this->DefineFlags.find(flag, lpos))
925 std::string::size_type rpos = lpos + len;
926 if((lpos <= 0 || isspace(this->DefineFlags[lpos-1])) &&
927 (rpos >= this->DefineFlags.size() || isspace(this->DefineFlags[rpos])))
929 this->DefineFlags.erase(lpos, len);
931 else
933 ++lpos;
938 bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
940 // Create a regular expression to match valid definitions.
941 // Definitions with non-trivial values must not be matched because
942 // escaping them could break compatibility with escapes added by
943 // users.
944 static cmsys::RegularExpression
945 regex("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=[A-Za-z0-9_.]+)?$");
947 // Make sure the definition matches.
948 if(!regex.find(def.c_str()))
950 return false;
953 // VS6 IDE does not support definitions with values.
954 if((strcmp(this->LocalGenerator->GetGlobalGenerator()->GetName(),
955 "Visual Studio 6") == 0) &&
956 (def.find("=") != def.npos))
958 return false;
961 // Get the definition part after the flag.
962 const char* define = def.c_str() + 2;
964 if(remove)
966 if(const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS"))
968 // Expand the list.
969 std::vector<std::string> defs;
970 cmSystemTools::ExpandListArgument(cdefs, defs);
972 // Recompose the list without the definition.
973 std::string ndefs;
974 const char* sep = "";
975 for(std::vector<std::string>::const_iterator di = defs.begin();
976 di != defs.end(); ++di)
978 if(*di != define)
980 ndefs += sep;
981 sep = ";";
982 ndefs += *di;
986 // Store the new list.
987 this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
990 else
992 // Append the definition to the directory property.
993 this->AppendProperty("COMPILE_DEFINITIONS", define);
996 return true;
999 void cmMakefile::AddLinkLibrary(const char* lib,
1000 cmTarget::LinkLibraryType llt)
1002 cmTarget::LibraryID tmp;
1003 tmp.first = lib;
1004 tmp.second = llt;
1005 this->LinkLibraries.push_back(tmp);
1008 void cmMakefile::AddLinkLibraryForTarget(const char *target,
1009 const char* lib,
1010 cmTarget::LinkLibraryType llt)
1012 cmTargets::iterator i = this->Targets.find(target);
1013 if ( i != this->Targets.end())
1015 cmTarget* tgt =
1016 this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib);
1017 if(tgt)
1019 bool allowModules = true;
1020 const char* versionValue
1021 = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
1022 if (versionValue && (atof(versionValue) >= 2.4) )
1024 allowModules = false;
1026 // if it is not a static or shared library then you can not link to it
1027 if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
1028 (tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
1029 tgt->IsExecutableWithExports()))
1031 cmOStringStream e;
1032 e << "Attempt to add link target " << lib << " of type: "
1033 << cmTarget::TargetTypeNames[static_cast<int>(tgt->GetType())]
1034 << "\nto target " << target
1035 << ". One can only link to STATIC or SHARED libraries, or "
1036 << "to executables with the ENABLE_EXPORTS property set.";
1037 // in older versions of cmake linking to modules was allowed
1038 if( tgt->GetType() == cmTarget::MODULE_LIBRARY )
1040 e <<
1041 "\nTo allow linking of modules set "
1042 "CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower\n";
1044 // if no modules are allowed then this is always an error
1045 if(!allowModules ||
1046 // if we allow modules but the type is not a module then it is
1047 // still an error
1048 (allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY))
1050 cmSystemTools::Error(e.str().c_str());
1054 i->second.AddLinkLibrary( *this, target, lib, llt );
1056 else
1058 cmOStringStream e;
1059 e << "Attempt to add link library \""
1060 << lib << "\" to target \""
1061 << target << "\" which is not built by this project.";
1062 cmSystemTools::Error(e.str().c_str());
1066 void cmMakefile::AddLinkDirectoryForTarget(const char *target,
1067 const char* d)
1069 cmTargets::iterator i = this->Targets.find(target);
1070 if ( i != this->Targets.end())
1072 i->second.AddLinkDirectory( d );
1074 else
1076 cmSystemTools::Error
1077 ("Attempt to add link directories to non-existant target: ",
1078 target, " for directory ", d);
1082 void cmMakefile::AddLinkLibrary(const char* lib)
1084 this->AddLinkLibrary(lib,cmTarget::GENERAL);
1087 void cmMakefile::AddLinkDirectory(const char* dir)
1089 // Don't add a link directory that is already present. Yes, this
1090 // linear search results in n^2 behavior, but n won't be getting
1091 // much bigger than 20. We cannot use a set because of order
1092 // dependency of the link search path.
1094 if(!dir)
1096 return;
1098 // remove trailing slashes
1099 if(dir[strlen(dir)-1] == '/')
1101 std::string newdir = dir;
1102 newdir = newdir.substr(0, newdir.size()-1);
1103 if(std::find(this->LinkDirectories.begin(),
1104 this->LinkDirectories.end(),
1105 newdir.c_str()) == this->LinkDirectories.end())
1107 this->LinkDirectories.push_back(newdir);
1110 else
1112 if(std::find(this->LinkDirectories.begin(),
1113 this->LinkDirectories.end(), dir)
1114 == this->LinkDirectories.end())
1116 this->LinkDirectories.push_back(dir);
1121 void cmMakefile::InitializeFromParent()
1123 cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
1125 // copy the definitions
1126 this->DefinitionStack.front() = parent->DefinitionStack.back();
1128 // copy include paths
1129 this->IncludeDirectories = parent->IncludeDirectories;
1130 this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
1132 // define flags
1133 this->DefineFlags = parent->DefineFlags;
1135 // compile definitions property and per-config versions
1137 this->SetProperty("COMPILE_DEFINITIONS",
1138 parent->GetProperty("COMPILE_DEFINITIONS"));
1139 std::vector<std::string> configs;
1140 if(const char* configTypes =
1141 this->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
1143 cmSystemTools::ExpandListArgument(configTypes, configs);
1145 else if(const char* buildType =
1146 this->GetDefinition("CMAKE_BUILD_TYPE"))
1148 configs.push_back(buildType);
1150 for(std::vector<std::string>::const_iterator ci = configs.begin();
1151 ci != configs.end(); ++ci)
1153 std::string defPropName = "COMPILE_DEFINITIONS_";
1154 defPropName += cmSystemTools::UpperCase(*ci);
1155 this->SetProperty(defPropName.c_str(),
1156 parent->GetProperty(defPropName.c_str()));
1160 // link libraries
1161 this->LinkLibraries = parent->LinkLibraries;
1163 // link directories
1164 this->LinkDirectories = parent->LinkDirectories;
1166 // the initial project name
1167 this->ProjectName = parent->ProjectName;
1169 // Copy include regular expressions.
1170 this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
1171 this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
1173 // Imported targets.
1174 this->ImportedTargets = parent->ImportedTargets;
1177 void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
1179 // copy our variables from the child makefile
1180 lg2->GetMakefile()->InitializeFromParent();
1181 lg2->GetMakefile()->MakeStartDirectoriesCurrent();
1182 if (this->GetCMakeInstance()->GetDebugOutput())
1184 std::string msg=" Entering ";
1185 msg += lg2->GetMakefile()->GetCurrentDirectory();
1186 cmSystemTools::Message(msg.c_str());
1188 // finally configure the subdir
1189 lg2->Configure();
1190 if (this->GetCMakeInstance()->GetDebugOutput())
1192 std::string msg=" Returning to ";
1193 msg += this->GetCurrentDirectory();
1194 cmSystemTools::Message(msg.c_str());
1198 void cmMakefile::AddSubDirectory(const char* sub,
1199 bool excludeFromAll, bool preorder)
1201 // the source path must be made full if it isn't already
1202 std::string srcPath = sub;
1203 if (!cmSystemTools::FileIsFullPath(srcPath.c_str()))
1205 srcPath = this->GetCurrentDirectory();
1206 srcPath += "/";
1207 srcPath += sub;
1210 // binary path must be made full if it isn't already
1211 std::string binPath = sub;
1212 if (!cmSystemTools::FileIsFullPath(binPath.c_str()))
1214 binPath = this->GetCurrentOutputDirectory();
1215 binPath += "/";
1216 binPath += sub;
1220 this->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
1221 excludeFromAll, preorder, false);
1225 void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
1226 bool excludeFromAll, bool preorder,
1227 bool immediate)
1229 std::vector<cmLocalGenerator *>& children =
1230 this->LocalGenerator->GetChildren();
1231 // has this directory already been added? If so error
1232 unsigned int i;
1233 for (i = 0; i < children.size(); ++i)
1235 if (srcPath == children[i]->GetMakefile()->GetStartDirectory())
1237 cmSystemTools::Error
1238 ("Attempt to add subdirectory multiple times for directory.\n",
1239 srcPath);
1240 return;
1244 // create a new local generator and set its parent
1245 cmLocalGenerator *lg2 =
1246 this->LocalGenerator->GetGlobalGenerator()->CreateLocalGenerator();
1247 lg2->SetParent(this->LocalGenerator);
1248 this->LocalGenerator->GetGlobalGenerator()->AddLocalGenerator(lg2);
1250 // set the subdirs start dirs
1251 lg2->GetMakefile()->SetStartDirectory(srcPath);
1252 lg2->GetMakefile()->SetStartOutputDirectory(binPath);
1253 if(excludeFromAll)
1255 lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1257 lg2->GetMakefile()->SetPreOrder(preorder);
1259 if (immediate)
1261 this->ConfigureSubDirectory(lg2);
1265 void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
1267 // if there is a newline then break it into multiple arguments
1268 if (!inc)
1270 return;
1273 // Don't add an include directory that is already present. Yes,
1274 // this linear search results in n^2 behavior, but n won't be
1275 // getting much bigger than 20. We cannot use a set because of
1276 // order dependency of the include path.
1277 std::vector<std::string>::iterator i =
1278 std::find(this->IncludeDirectories.begin(),
1279 this->IncludeDirectories.end(), inc);
1280 if(i == this->IncludeDirectories.end())
1282 if (before)
1284 // WARNING: this *is* expensive (linear time) since it's a vector
1285 this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
1287 else
1289 this->IncludeDirectories.push_back(inc);
1292 else
1294 if(before)
1296 // if this before and already in the path then remove it
1297 this->IncludeDirectories.erase(i);
1298 // WARNING: this *is* expensive (linear time) since it's a vector
1299 this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc);
1304 //----------------------------------------------------------------------------
1305 void cmMakefile::AddSystemIncludeDirectory(const char* dir)
1307 this->SystemIncludeDirectories.insert(dir);
1310 //----------------------------------------------------------------------------
1311 bool cmMakefile::IsSystemIncludeDirectory(const char* dir)
1313 return (this->SystemIncludeDirectories.find(dir) !=
1314 this->SystemIncludeDirectories.end());
1317 void cmMakefile::AddDefinition(const char* name, const char* value)
1319 if (!value )
1321 return;
1324 #ifdef CMAKE_STRICT
1325 if (this->GetCMakeInstance())
1327 this->GetCMakeInstance()->
1328 RecordPropertyAccess(name,cmProperty::VARIABLE);
1330 #endif
1332 this->TemporaryDefinitionKey = name;
1333 this->DefinitionStack.back()[this->TemporaryDefinitionKey] = value;
1335 #ifdef CMAKE_BUILD_WITH_CMAKE
1336 cmVariableWatch* vv = this->GetVariableWatch();
1337 if ( vv )
1339 vv->VariableAccessed(this->TemporaryDefinitionKey,
1340 cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1341 value,
1342 this);
1344 #endif
1348 void cmMakefile::AddCacheDefinition(const char* name, const char* value,
1349 const char* doc,
1350 cmCacheManager::CacheEntryType type)
1352 const char* val = value;
1353 cmCacheManager::CacheIterator it =
1354 this->GetCacheManager()->GetCacheIterator(name);
1355 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1356 it.Initialized())
1358 val = it.GetValue();
1359 if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH )
1361 std::vector<std::string>::size_type cc;
1362 std::vector<std::string> files;
1363 std::string nvalue = "";
1364 cmSystemTools::ExpandListArgument(val, files);
1365 for ( cc = 0; cc < files.size(); cc ++ )
1367 files[cc] = cmSystemTools::CollapseFullPath(files[cc].c_str());
1368 if ( cc > 0 )
1370 nvalue += ";";
1372 nvalue += files[cc];
1375 this->GetCacheManager()->AddCacheEntry(name, nvalue.c_str(), doc, type);
1376 val = it.GetValue();
1380 this->GetCacheManager()->AddCacheEntry(name, val, doc, type);
1381 // if there was a definition then remove it
1382 this->DefinitionStack.back().erase( DefinitionMap::key_type(name));
1386 void cmMakefile::AddDefinition(const char* name, bool value)
1388 if(value)
1390 this->DefinitionStack.back()
1391 .erase( DefinitionMap::key_type(name));
1392 this->DefinitionStack.back()
1393 .insert(DefinitionMap::value_type(name, "ON"));
1395 else
1397 this->DefinitionStack.back()
1398 .erase( DefinitionMap::key_type(name));
1399 this->DefinitionStack.back()
1400 .insert(DefinitionMap::value_type(name, "OFF"));
1402 #ifdef CMAKE_BUILD_WITH_CMAKE
1403 cmVariableWatch* vv = this->GetVariableWatch();
1404 if ( vv )
1406 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
1407 value?"ON":"OFF", this);
1409 #endif
1413 void cmMakefile::AddCacheDefinition(const char* name,
1414 bool value,
1415 const char* doc)
1417 bool val = value;
1418 cmCacheManager::CacheIterator it =
1419 this->GetCacheManager()->GetCacheIterator(name);
1420 if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
1421 it.Initialized())
1423 val = it.GetValueAsBool();
1425 this->GetCacheManager()->AddCacheEntry(name, val, doc);
1426 this->AddDefinition(name, val);
1429 void cmMakefile::RemoveDefinition(const char* name)
1431 this->DefinitionStack.back().erase(DefinitionMap::key_type(name));
1432 #ifdef CMAKE_BUILD_WITH_CMAKE
1433 cmVariableWatch* vv = this->GetVariableWatch();
1434 if ( vv )
1436 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
1437 0, this);
1439 #endif
1442 void cmMakefile::SetProjectName(const char* p)
1444 this->ProjectName = p;
1448 void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
1450 // for these targets do not add anything
1451 switch(target.GetType())
1453 case cmTarget::UTILITY:
1454 case cmTarget::GLOBAL_TARGET:
1455 return;
1456 default:;
1458 std::vector<std::string>::iterator j;
1459 for(j = this->LinkDirectories.begin();
1460 j != this->LinkDirectories.end(); ++j)
1462 target.AddLinkDirectory(j->c_str());
1464 target.MergeLinkLibraries( *this, name, this->LinkLibraries );
1468 void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
1469 const std::vector<std::string> &srcs,
1470 bool excludeFromAll)
1472 // wrong type ? default to STATIC
1473 if ( (type != cmTarget::STATIC_LIBRARY)
1474 && (type != cmTarget::SHARED_LIBRARY)
1475 && (type != cmTarget::MODULE_LIBRARY))
1477 type = cmTarget::STATIC_LIBRARY;
1480 cmTarget* target = this->AddNewTarget(type, lname);
1481 // Clear its dependencies. Otherwise, dependencies might persist
1482 // over changes in CMakeLists.txt, making the information stale and
1483 // hence useless.
1484 target->ClearDependencyInformation( *this, lname );
1485 if(excludeFromAll)
1487 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1489 target->AddSources(srcs);
1490 this->AddGlobalLinkInformation(lname, *target);
1493 cmTarget* cmMakefile::AddExecutable(const char *exeName,
1494 const std::vector<std::string> &srcs,
1495 bool excludeFromAll)
1497 cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName);
1498 if(excludeFromAll)
1500 target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1502 target->AddSources(srcs);
1503 this->AddGlobalLinkInformation(exeName, *target);
1504 return target;
1507 //----------------------------------------------------------------------------
1508 cmTarget*
1509 cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name)
1511 cmTargets::iterator it;
1512 cmTarget target;
1513 target.SetType(type, name);
1514 target.SetMakefile(this);
1515 it=this->Targets.insert(
1516 cmTargets::value_type(target.GetName(), target)).first;
1517 this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it);
1518 return &it->second;
1521 cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
1523 std::string name = cname;
1524 std::string out;
1526 // look through all the source files that have custom commands
1527 // and see if the custom command has the passed source file as an output
1528 // keep in mind the possible .rule extension that may be tacked on
1529 for(std::vector<cmSourceFile*>::const_iterator i =
1530 this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
1532 // does this source file have a custom command?
1533 if ((*i)->GetCustomCommand())
1535 // is the output of the custom command match the source files name
1536 const std::vector<std::string>& outputs =
1537 (*i)->GetCustomCommand()->GetOutputs();
1538 for(std::vector<std::string>::const_iterator o = outputs.begin();
1539 o != outputs.end(); ++o)
1541 out = *o;
1542 std::string::size_type pos = out.rfind(name);
1543 // If the output matches exactly
1544 if (pos != out.npos &&
1545 pos == out.size() - name.size() &&
1546 (pos ==0 || out[pos-1] == '/'))
1548 return *i;
1554 // otherwise return NULL
1555 return 0;
1558 #if defined(CMAKE_BUILD_WITH_CMAKE)
1559 cmSourceGroup* cmMakefile::GetSourceGroup(const std::vector<std::string>&name)
1561 cmSourceGroup* sg = 0;
1563 // first look for source group starting with the same as the one we wants
1564 for (std::vector<cmSourceGroup>::iterator sgIt = this->SourceGroups.begin();
1565 sgIt != this->SourceGroups.end(); ++sgIt)
1568 std::string sgName = sgIt->GetName();
1569 if(sgName == name[0])
1571 sg = &(*sgIt);
1572 break;
1576 if(sg != 0)
1578 // iterate through its children to find match source group
1579 for(unsigned int i=1; i<name.size(); ++i)
1581 sg = sg->lookupChild(name[i].c_str());
1582 if(sg == 0)
1584 break;
1588 return sg;
1591 void cmMakefile::AddSourceGroup(const char* name,
1592 const char* regex)
1594 if (name)
1596 std::vector<std::string> nameVector;
1597 nameVector.push_back(name);
1598 AddSourceGroup(nameVector, regex);
1602 void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
1603 const char* regex)
1605 cmSourceGroup* sg = 0;
1606 std::vector<std::string> currentName;
1607 int i = 0;
1608 const int lastElement = static_cast<int>(name.size()-1);
1609 for(i=lastElement; i>=0; --i)
1611 currentName.assign(name.begin(), name.begin()+i+1);
1612 sg = this->GetSourceGroup(currentName);
1613 if(sg != 0)
1615 break;
1619 // i now contains the index of the last found component
1620 if(i==lastElement)
1622 // group already exists, replace its regular expression
1623 if ( regex )
1625 // We only want to set the regular expression. If there are already
1626 // source files in the group, we don't want to remove them.
1627 sg->SetGroupRegex(regex);
1629 return;
1631 else if(i==-1)
1633 // group does not exists nor belong to any existing group
1634 // add its first component
1635 this->SourceGroups.push_back(cmSourceGroup(name[0].c_str(), regex));
1636 sg = this->GetSourceGroup(currentName);
1637 i = 0; // last component found
1640 // build the whole source group path
1641 for(++i; i<=lastElement; ++i)
1643 sg->AddChild(cmSourceGroup(name[i].c_str(), 0));
1644 sg = sg->lookupChild(name[i].c_str());
1647 sg->SetGroupRegex(regex);
1650 #endif
1652 void cmMakefile::AddExtraDirectory(const char* dir)
1654 this->AuxSourceDirectories.push_back(dir);
1658 // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
1659 // include and library directories.
1661 void cmMakefile::ExpandVariables()
1663 // Now expand variables in the include and link strings
1664 for(std::vector<std::string>::iterator d = this->IncludeDirectories.begin();
1665 d != this->IncludeDirectories.end(); ++d)
1667 this->ExpandVariablesInString(*d, true, true);
1669 for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
1670 d != this->LinkDirectories.end(); ++d)
1672 this->ExpandVariablesInString(*d, true, true);
1674 for(cmTarget::LinkLibraryVectorType::iterator l =
1675 this->LinkLibraries.begin();
1676 l != this->LinkLibraries.end(); ++l)
1678 this->ExpandVariablesInString(l->first, true, true);
1682 bool cmMakefile::IsOn(const char* name) const
1684 const char* value = this->GetDefinition(name);
1685 return cmSystemTools::IsOn(value);
1688 bool cmMakefile::IsSet(const char* name) const
1690 const char* value = this->GetDefinition(name);
1691 if ( !value )
1693 return false;
1696 if ( ! *value )
1698 return false;
1701 if ( cmSystemTools::IsNOTFOUND(value) )
1703 return false;
1706 return true;
1709 bool cmMakefile::CanIWriteThisFile(const char* fileName)
1711 if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
1713 return true;
1715 // If we are doing an in-source build, than the test will always fail
1716 if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
1717 this->GetHomeOutputDirectory()) )
1719 if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
1721 return false;
1723 return true;
1726 // Check if this is subdirectory of the source tree but not a
1727 // subdirectory of a build tree
1728 if ( cmSystemTools::IsSubDirectory(fileName,
1729 this->GetHomeDirectory()) &&
1730 !cmSystemTools::IsSubDirectory(fileName,
1731 this->GetHomeOutputDirectory()) )
1733 return false;
1735 return true;
1738 const char* cmMakefile::GetRequiredDefinition(const char* name) const
1740 const char* ret = this->GetDefinition(name);
1741 if(!ret)
1743 cmSystemTools::Error("Error required internal CMake variable not "
1744 "set, cmake may be not be built correctly.\n",
1745 "Missing variable is:\n",
1746 name);
1747 return "";
1749 return ret;
1752 bool cmMakefile::IsDefinitionSet(const char* name) const
1754 const char* def = 0;
1755 DefinitionMap::const_iterator pos =
1756 this->DefinitionStack.back().find(name);
1757 if(pos != this->DefinitionStack.back().end())
1759 def = (*pos).second.c_str();
1761 else
1763 def = this->GetCacheManager()->GetCacheValue(name);
1765 #ifdef CMAKE_BUILD_WITH_CMAKE
1766 if(cmVariableWatch* vv = this->GetVariableWatch())
1768 if(!def)
1770 vv->VariableAccessed
1771 (name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS,
1772 def, this);
1775 #endif
1776 return def?true:false;
1779 const char* cmMakefile::GetDefinition(const char* name) const
1781 #ifdef CMAKE_STRICT
1782 if (this->GetCMakeInstance())
1784 this->GetCMakeInstance()->
1785 RecordPropertyAccess(name,cmProperty::VARIABLE);
1787 #endif
1788 const char* def = 0;
1789 DefinitionMap::const_iterator pos =
1790 this->DefinitionStack.back().find(name);
1791 if(pos != this->DefinitionStack.back().end())
1793 def = (*pos).second.c_str();
1795 else
1797 def = this->GetCacheManager()->GetCacheValue(name);
1799 #ifdef CMAKE_BUILD_WITH_CMAKE
1800 cmVariableWatch* vv = this->GetVariableWatch();
1801 if ( vv )
1803 if ( def )
1805 vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
1806 def, this);
1808 else
1810 // are unknown access allowed
1811 DefinitionMap::const_iterator pos2 =
1812 this->DefinitionStack.back()
1813 .find("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
1814 if (pos2 != this->DefinitionStack.back().end() &&
1815 cmSystemTools::IsOn((*pos2).second.c_str()))
1817 vv->VariableAccessed(name,
1818 cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, def, this);
1820 else
1822 vv->VariableAccessed(name,
1823 cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
1827 #endif
1828 return def;
1831 const char* cmMakefile::GetSafeDefinition(const char* def) const
1833 const char* ret = this->GetDefinition(def);
1834 if(!ret)
1836 return "";
1838 return ret;
1841 std::vector<std::string> cmMakefile
1842 ::GetDefinitions(int cacheonly /* = 0 */) const
1844 std::map<cmStdString, int> definitions;
1845 if ( !cacheonly )
1847 DefinitionMap::const_iterator it;
1848 for ( it = this->DefinitionStack.back().begin();
1849 it != this->DefinitionStack.back().end(); it ++ )
1851 definitions[it->first] = 1;
1854 cmCacheManager::CacheIterator cit =
1855 this->GetCacheManager()->GetCacheIterator();
1856 for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
1858 definitions[cit.GetName()] = 1;
1861 std::vector<std::string> res;
1863 std::map<cmStdString, int>::iterator fit;
1864 for ( fit = definitions.begin(); fit != definitions.end(); fit ++ )
1866 res.push_back(fit->first);
1868 return res;
1872 const char *cmMakefile::ExpandVariablesInString(std::string& source)
1874 return this->ExpandVariablesInString(source, false, false);
1877 const char *cmMakefile::ExpandVariablesInString(std::string& source,
1878 bool escapeQuotes,
1879 bool noEscapes,
1880 bool atOnly,
1881 const char* filename,
1882 long line,
1883 bool removeEmpty,
1884 bool replaceAt)
1886 if ( source.empty() || source.find_first_of("$@\\") == source.npos)
1888 return source.c_str();
1891 // Special-case the @ONLY mode.
1892 if(atOnly)
1894 if(!noEscapes || !removeEmpty || !replaceAt)
1896 // This case should never be called. At-only is for
1897 // configure-file/string which always does no escapes.
1898 abort();
1901 // Store an original copy of the input.
1902 std::string input = source;
1904 // Start with empty output.
1905 source = "";
1907 // Look for one @VAR@ at a time.
1908 const char* in = input.c_str();
1909 while(this->cmAtVarRegex.find(in))
1911 // Get the range of the string to replace.
1912 const char* first = in + this->cmAtVarRegex.start();
1913 const char* last = in + this->cmAtVarRegex.end();
1915 // Store the unchanged part of the string now.
1916 source.append(in, first-in);
1918 // Lookup the definition of VAR.
1919 std::string var(first+1, last-first-2);
1920 if(const char* val = this->GetDefinition(var.c_str()))
1922 // Store the value in the output escaping as requested.
1923 if(escapeQuotes)
1925 source.append(cmSystemTools::EscapeQuotes(val));
1927 else
1929 source.append(val);
1933 // Continue looking for @VAR@ further along the string.
1934 in = last;
1937 // Append the rest of the unchanged part of the string.
1938 source.append(in);
1940 return source.c_str();
1943 // This method replaces ${VAR} and @VAR@ where VAR is looked up
1944 // with GetDefinition(), if not found in the map, nothing is expanded.
1945 // It also supports the $ENV{VAR} syntax where VAR is looked up in
1946 // the current environment variables.
1948 cmCommandArgumentParserHelper parser;
1949 parser.SetMakefile(this);
1950 parser.SetLineFile(line, filename);
1951 parser.SetEscapeQuotes(escapeQuotes);
1952 parser.SetNoEscapeMode(noEscapes);
1953 parser.SetReplaceAtSyntax(replaceAt);
1954 parser.SetRemoveEmpty(removeEmpty);
1955 int res = parser.ParseString(source.c_str(), 0);
1956 if ( res )
1958 source = parser.GetResult();
1960 else
1962 cmOStringStream error;
1963 error << "Syntax error in cmake code at\n"
1964 << (filename?filename:"(no filename given)")
1965 << ":" << line << ":\n"
1966 << parser.GetError() << ", when parsing string \""
1967 << source.c_str() << "\"";
1968 const char* versionValue
1969 = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
1970 int major = 0;
1971 int minor = 0;
1972 if ( versionValue )
1974 sscanf(versionValue, "%d.%d", &major, &minor);
1976 if ( major < 2 || major == 2 && minor < 1 )
1978 cmSystemTools::Error(error.str().c_str());
1979 cmSystemTools::SetFatalErrorOccured();
1980 return source.c_str();
1982 else
1984 cmSystemTools::Message(error.str().c_str());
1987 return source.c_str();
1990 void cmMakefile::RemoveVariablesInString(std::string& source,
1991 bool atOnly) const
1993 if(!atOnly)
1995 cmsys::RegularExpression var("(\\${[A-Za-z_0-9]*})");
1996 while (var.find(source))
1998 source.erase(var.start(),var.end() - var.start());
2002 if(!atOnly)
2004 cmsys::RegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
2005 while (varb.find(source))
2007 source.erase(varb.start(),varb.end() - varb.start());
2010 cmsys::RegularExpression var2("(@[A-Za-z_0-9]*@)");
2011 while (var2.find(source))
2013 source.erase(var2.start(),var2.end() - var2.start());
2018 * Add the default definitions to the makefile. These values must not
2019 * be dependent on anything that isn't known when this cmMakefile instance
2020 * is constructed.
2022 void cmMakefile::AddDefaultDefinitions()
2024 /* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set.
2025 With CMake must separate between target and host platform. In most cases
2026 the tests for WIN32, UNIX and APPLE will be for the target system, so an
2027 additional set of variables for the host system is required ->
2028 CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE.
2029 WIN32, UNIX and APPLE are now set in the platform files in
2030 Modules/Platforms/.
2031 To keep cmake scripts (-P) and custom language and compiler modules
2032 working, these variables are still also set here in this place, but they
2033 will be reset in CMakeSystemSpecificInformation.cmake before the platform
2034 files are executed. */
2035 #if defined(_WIN32) || defined(__CYGWIN__)
2036 this->AddDefinition("WIN32", "1");
2037 this->AddDefinition("CMAKE_HOST_WIN32", "1");
2038 #else
2039 this->AddDefinition("UNIX", "1");
2040 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2041 #endif
2042 // Cygwin is more like unix so enable the unix commands
2043 #if defined(__CYGWIN__)
2044 this->AddDefinition("UNIX", "1");
2045 this->AddDefinition("CMAKE_HOST_UNIX", "1");
2046 #endif
2047 #if defined(__APPLE__)
2048 this->AddDefinition("APPLE", "1");
2049 this->AddDefinition("CMAKE_HOST_APPLE", "1");
2050 #endif
2052 char temp[1024];
2053 sprintf(temp, "%d", cmVersion::GetMinorVersion());
2054 this->AddDefinition("CMAKE_MINOR_VERSION", temp);
2055 sprintf(temp, "%d", cmVersion::GetMajorVersion());
2056 this->AddDefinition("CMAKE_MAJOR_VERSION", temp);
2057 sprintf(temp, "%d", cmVersion::GetPatchVersion());
2058 this->AddDefinition("CMAKE_PATCH_VERSION", temp);
2060 this->AddDefinition("CMAKE_FILES_DIRECTORY",
2061 cmake::GetCMakeFilesDirectory());
2064 #if defined(CMAKE_BUILD_WITH_CMAKE)
2066 * Find a source group whose regular expression matches the filename
2067 * part of the given source name. Search backward through the list of
2068 * source groups, and take the first matching group found. This way
2069 * non-inherited SOURCE_GROUP commands will have precedence over
2070 * inherited ones.
2072 cmSourceGroup&
2073 cmMakefile::FindSourceGroup(const char* source,
2074 std::vector<cmSourceGroup> &groups)
2076 // First search for a group that lists the file explicitly.
2077 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2078 sg != groups.rend(); ++sg)
2080 cmSourceGroup *result = sg->MatchChildrenFiles(source);
2081 if(result)
2083 return *result;
2087 // Now search for a group whose regex matches the file.
2088 for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
2089 sg != groups.rend(); ++sg)
2091 cmSourceGroup *result = sg->MatchChildrenRegex(source);
2092 if(result)
2094 return *result;
2099 // Shouldn't get here, but just in case, return the default group.
2100 return groups.front();
2102 #endif
2104 bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
2105 cmExecutionStatus &status)
2107 // if there are no blockers get out of here
2108 if (this->FunctionBlockers.begin() == this->FunctionBlockers.end())
2110 return false;
2113 // loop over all function blockers to see if any block this command
2114 // evaluate in reverse, this is critical for balanced IF statements etc
2115 std::list<cmFunctionBlocker *>::reverse_iterator pos;
2116 for (pos = this->FunctionBlockers.rbegin();
2117 pos != this->FunctionBlockers.rend(); ++pos)
2119 if((*pos)->IsFunctionBlocked(lff, *this, status))
2121 return true;
2125 return false;
2128 void cmMakefile::ExpandArguments(
2129 std::vector<cmListFileArgument> const& inArgs,
2130 std::vector<std::string>& outArgs)
2132 std::vector<cmListFileArgument>::const_iterator i;
2133 std::string value;
2134 outArgs.reserve(inArgs.size());
2135 for(i = inArgs.begin(); i != inArgs.end(); ++i)
2137 // Expand the variables in the argument.
2138 value = i->Value;
2139 this->ExpandVariablesInString(value, false, false, false,
2140 i->FilePath, i->Line,
2141 false, true);
2143 // If the argument is quoted, it should be one argument.
2144 // Otherwise, it may be a list of arguments.
2145 if(i->Quoted)
2147 outArgs.push_back(value);
2149 else
2151 cmSystemTools::ExpandListArgument(value, outArgs);
2156 void cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
2158 // loop over all function blockers to see if any block this command
2159 std::list<cmFunctionBlocker *>::reverse_iterator pos;
2160 for (pos = this->FunctionBlockers.rbegin();
2161 pos != this->FunctionBlockers.rend(); ++pos)
2163 if ((*pos)->ShouldRemove(lff, *this))
2165 cmFunctionBlocker* b = *pos;
2166 this->FunctionBlockers.remove(b);
2167 delete b;
2168 break;
2172 return;
2175 void cmMakefile::SetHomeDirectory(const char* dir)
2177 this->cmHomeDirectory = dir;
2178 cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
2179 this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
2180 if ( !this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR") )
2182 this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", this->GetHomeDirectory());
2186 void cmMakefile::SetHomeOutputDirectory(const char* lib)
2188 this->HomeOutputDirectory = lib;
2189 cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
2190 this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
2191 if ( !this->GetDefinition("CMAKE_CURRENT_BINARY_DIR") )
2193 this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
2194 this->GetHomeOutputDirectory());
2200 * Register the given cmData instance with its own name.
2202 void cmMakefile::RegisterData(cmData* data)
2204 std::string name = data->GetName();
2205 DataMapType::const_iterator d = this->DataMap.find(name);
2206 if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
2208 delete d->second;
2210 this->DataMap[name] = data;
2215 * Register the given cmData instance with the given name. This can be used
2216 * to register a NULL pointer.
2218 void cmMakefile::RegisterData(const char* name, cmData* data)
2220 DataMapType::const_iterator d = this->DataMap.find(name);
2221 if((d != this->DataMap.end()) && (d->second != 0) && (d->second != data))
2223 delete d->second;
2225 this->DataMap[name] = data;
2230 * Lookup a cmData instance previously registered with the given name. If
2231 * the instance cannot be found, return NULL.
2233 cmData* cmMakefile::LookupData(const char* name) const
2235 DataMapType::const_iterator d = this->DataMap.find(name);
2236 if(d != this->DataMap.end())
2238 return d->second;
2240 else
2242 return 0;
2246 //----------------------------------------------------------------------------
2247 cmSourceFile* cmMakefile::GetSource(const char* sourceName)
2249 cmSourceFileLocation sfl(this, sourceName);
2250 for(std::vector<cmSourceFile*>::const_iterator
2251 sfi = this->SourceFiles.begin();
2252 sfi != this->SourceFiles.end(); ++sfi)
2254 cmSourceFile* sf = *sfi;
2255 if(sf->Matches(sfl))
2257 return sf;
2260 return 0;
2263 //----------------------------------------------------------------------------
2264 cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
2265 bool generated)
2267 if(cmSourceFile* esf = this->GetSource(sourceName))
2269 return esf;
2271 else
2273 cmSourceFile* sf = new cmSourceFile(this, sourceName);
2274 if(generated)
2276 sf->SetProperty("GENERATED", "1");
2278 this->SourceFiles.push_back(sf);
2279 return sf;
2283 void cmMakefile::EnableLanguage(std::vector<std::string> const & lang,
2284 bool optional)
2286 this->AddDefinition("CMAKE_CFG_INTDIR",
2287 this->LocalGenerator->GetGlobalGenerator()->GetCMakeCFGInitDirectory());
2288 this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this,
2289 optional);
2292 void cmMakefile::ExpandSourceListArguments(
2293 std::vector<std::string> const& arguments,
2294 std::vector<std::string>& newargs, unsigned int /* start */)
2296 // now expand the args
2297 unsigned int i;
2298 for(i = 0; i < arguments.size(); ++i)
2300 // List expansion will have been done already.
2301 newargs.push_back(arguments[i]);
2305 int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
2306 const char *projectName, const char *targetName,
2307 const std::vector<std::string> *cmakeArgs,
2308 std::string *output)
2310 // does the binary directory exist ? If not create it...
2311 if (!cmSystemTools::FileIsDirectory(bindir))
2313 cmSystemTools::MakeDirectory(bindir);
2316 // change to the tests directory and run cmake
2317 // use the cmake object instead of calling cmake
2318 std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
2319 cmSystemTools::ChangeDirectory(bindir);
2321 // make sure the same generator is used
2322 // use this program as the cmake to be run, it should not
2323 // be run that way but the cmake object requires a vailid path
2324 std::string cmakeCommand = this->GetDefinition("CMAKE_COMMAND");
2325 cmake cm;
2326 cm.SetIsInTryCompile(true);
2327 cmGlobalGenerator *gg = cm.CreateGlobalGenerator
2328 (this->LocalGenerator->GetGlobalGenerator()->GetName());
2329 if (!gg)
2331 cmSystemTools::Error(
2332 "Internal CMake error, TryCompile bad GlobalGenerator");
2333 // return to the original directory
2334 cmSystemTools::ChangeDirectory(cwd.c_str());
2335 return 1;
2337 cm.SetGlobalGenerator(gg);
2339 // do a configure
2340 cm.SetHomeDirectory(srcdir);
2341 cm.SetHomeOutputDirectory(bindir);
2342 cm.SetStartDirectory(srcdir);
2343 cm.SetStartOutputDirectory(bindir);
2344 cm.SetCMakeCommand(cmakeCommand.c_str());
2345 cm.LoadCache();
2346 // if cmake args were provided then pass them in
2347 if (cmakeArgs)
2349 cm.SetCacheArgs(*cmakeArgs);
2351 // to save time we pass the EnableLanguage info directly
2352 gg->EnableLanguagesFromGenerator
2353 (this->LocalGenerator->GetGlobalGenerator());
2355 if (cm.Configure() != 0)
2357 cmSystemTools::Error(
2358 "Internal CMake error, TryCompile configure of cmake failed");
2359 // return to the original directory
2360 cmSystemTools::ChangeDirectory(cwd.c_str());
2361 return 1;
2364 if (cm.Generate() != 0)
2366 cmSystemTools::Error(
2367 "Internal CMake error, TryCompile generation of cmake failed");
2368 // return to the original directory
2369 cmSystemTools::ChangeDirectory(cwd.c_str());
2370 return 1;
2373 // finally call the generator to actually build the resulting project
2374 int ret =
2375 this->LocalGenerator->GetGlobalGenerator()->TryCompile(srcdir,bindir,
2376 projectName,
2377 targetName,
2378 output,
2379 this);
2381 cmSystemTools::ChangeDirectory(cwd.c_str());
2382 return ret;
2385 cmake *cmMakefile::GetCMakeInstance() const
2387 if ( this->LocalGenerator && this->LocalGenerator->GetGlobalGenerator() )
2389 return this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
2391 return 0;
2394 #ifdef CMAKE_BUILD_WITH_CMAKE
2395 cmVariableWatch *cmMakefile::GetVariableWatch() const
2397 if ( this->GetCMakeInstance() &&
2398 this->GetCMakeInstance()->GetVariableWatch() )
2400 return this->GetCMakeInstance()->GetVariableWatch();
2402 return 0;
2404 #endif
2406 void cmMakefile::AddMacro(const char* name, const char* signature)
2408 if ( !name || !signature )
2410 return;
2412 this->MacrosMap[name] = signature;
2415 void cmMakefile::GetListOfMacros(std::string& macros)
2417 StringStringMap::iterator it;
2418 macros = "";
2419 int cc = 0;
2420 for ( it = this->MacrosMap.begin(); it != this->MacrosMap.end(); ++it )
2422 if ( cc > 0 )
2424 macros += ";";
2426 macros += it->first;
2427 cc ++;
2431 cmCacheManager *cmMakefile::GetCacheManager() const
2433 return this->GetCMakeInstance()->GetCacheManager();
2436 void cmMakefile::DisplayStatus(const char* message, float s)
2438 this->GetLocalGenerator()->GetGlobalGenerator()
2439 ->GetCMakeInstance()->UpdateProgress(message, s);
2442 std::string cmMakefile::GetModulesFile(const char* filename)
2444 std::vector<std::string> modulePath;
2445 const char* def = this->GetDefinition("CMAKE_MODULE_PATH");
2446 if(def)
2448 cmSystemTools::ExpandListArgument(def, modulePath);
2451 // Also search in the standard modules location.
2452 def = this->GetDefinition("CMAKE_ROOT");
2453 if(def)
2455 std::string rootModules = def;
2456 rootModules += "/Modules";
2457 modulePath.push_back(rootModules);
2459 //std::string Look through the possible module directories.
2460 for(std::vector<std::string>::iterator i = modulePath.begin();
2461 i != modulePath.end(); ++i)
2463 std::string itempl = *i;
2464 cmSystemTools::ConvertToUnixSlashes(itempl);
2465 itempl += "/";
2466 itempl += filename;
2467 if(cmSystemTools::FileExists(itempl.c_str()))
2469 return itempl;
2472 return "";
2475 void cmMakefile::ConfigureString(const std::string& input,
2476 std::string& output, bool atOnly,
2477 bool escapeQuotes)
2479 // Split input to handle one line at a time.
2480 std::string::const_iterator lineStart = input.begin();
2481 while(lineStart != input.end())
2483 // Find the end of this line.
2484 std::string::const_iterator lineEnd = lineStart;
2485 while(lineEnd != input.end() && *lineEnd != '\n')
2487 ++lineEnd;
2490 // Copy the line.
2491 std::string line(lineStart, lineEnd);
2493 // Skip the newline character.
2494 bool haveNewline = (lineEnd != input.end());
2495 if(haveNewline)
2497 ++lineEnd;
2500 // Replace #cmakedefine instances.
2501 if(this->cmDefineRegex.find(line))
2503 const char* def =
2504 this->GetDefinition(this->cmDefineRegex.match(1).c_str());
2505 if(!cmSystemTools::IsOff(def))
2507 cmSystemTools::ReplaceString(line, "#cmakedefine", "#define");
2508 output += line;
2510 else
2512 output += "/* #undef ";
2513 output += this->cmDefineRegex.match(1);
2514 output += " */";
2517 else if(this->cmDefine01Regex.find(line))
2519 const char* def =
2520 this->GetDefinition(this->cmDefine01Regex.match(1).c_str());
2521 cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define");
2522 output += line;
2523 if(!cmSystemTools::IsOff(def))
2525 output += " 1";
2527 else
2529 output += " 0";
2532 else
2534 output += line;
2537 if(haveNewline)
2539 output += "\n";
2542 // Move to the next line.
2543 lineStart = lineEnd;
2546 // Perform variable replacements.
2547 this->ExpandVariablesInString(output, escapeQuotes, true,
2548 atOnly, 0, -1, true);
2551 int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
2552 bool copyonly, bool atOnly, bool escapeQuotes)
2554 int res = 1;
2555 if ( !this->CanIWriteThisFile(outfile) )
2557 cmSystemTools::Error("Attempt to write file: ",
2558 outfile, " into a source directory.");
2559 return 0;
2561 if ( !cmSystemTools::FileExists(infile) )
2563 cmSystemTools::Error("File ", infile, " does not exist.");
2564 return 0;
2566 std::string soutfile = outfile;
2567 std::string sinfile = infile;
2568 this->AddCMakeDependFile(infile);
2569 cmSystemTools::ConvertToUnixSlashes(soutfile);
2570 mode_t perm = 0;
2571 cmSystemTools::GetPermissions(sinfile.c_str(), perm);
2572 std::string::size_type pos = soutfile.rfind('/');
2573 if(pos != std::string::npos)
2575 std::string path = soutfile.substr(0, pos);
2576 cmSystemTools::MakeDirectory(path.c_str());
2579 if(copyonly)
2581 if ( !cmSystemTools::CopyFileIfDifferent(sinfile.c_str(),
2582 soutfile.c_str()))
2584 return 0;
2587 else
2589 std::string tempOutputFile = soutfile;
2590 tempOutputFile += ".tmp";
2591 std::ofstream fout(tempOutputFile.c_str());
2592 if(!fout)
2594 cmSystemTools::Error(
2595 "Could not open file for write in copy operation ",
2596 tempOutputFile.c_str());
2597 cmSystemTools::ReportLastSystemError("");
2598 return 0;
2600 std::ifstream fin(sinfile.c_str());
2601 if(!fin)
2603 cmSystemTools::Error("Could not open file for read in copy operation ",
2604 sinfile.c_str());
2605 return 0;
2608 // now copy input to output and expand variables in the
2609 // input file at the same time
2610 std::string inLine;
2611 std::string outLine;
2612 while( cmSystemTools::GetLineFromStream(fin, inLine) )
2614 outLine = "";
2615 this->ConfigureString(inLine, outLine, atOnly, escapeQuotes);
2616 fout << outLine.c_str() << "\n";
2618 // close the files before attempting to copy
2619 fin.close();
2620 fout.close();
2621 if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
2622 soutfile.c_str()) )
2624 res = 0;
2626 else
2628 cmSystemTools::SetPermissions(soutfile.c_str(), perm);
2630 cmSystemTools::RemoveFile(tempOutputFile.c_str());
2632 return res;
2635 void cmMakefile::AddWrittenFile(const char* file)
2636 { this->GetCMakeInstance()->AddWrittenFile(file); }
2638 bool cmMakefile::HasWrittenFile(const char* file)
2639 { return this->GetCMakeInstance()->HasWrittenFile(file); }
2641 bool cmMakefile::CheckInfiniteLoops()
2643 std::vector<std::string>::iterator it;
2644 for ( it = this->ListFiles.begin();
2645 it != this->ListFiles.end();
2646 ++ it )
2648 if ( this->HasWrittenFile(it->c_str()) )
2650 cmOStringStream str;
2651 str << "File " << it->c_str() <<
2652 " is written by WRITE_FILE (or FILE WRITE) command and should "
2653 "not be used as input to CMake. Please use CONFIGURE_FILE to "
2654 "be safe. Refer to the note next to FILE WRITE command.";
2655 cmSystemTools::Error(str.str().c_str());
2656 return false;
2659 return true;
2662 void cmMakefile::SetProperty(const char* prop, const char* value)
2664 if (!prop)
2666 return;
2669 // handle special props
2670 std::string propname = prop;
2671 if ( propname == "INCLUDE_DIRECTORIES" )
2673 std::vector<std::string> varArgsExpanded;
2674 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2675 this->SetIncludeDirectories(varArgsExpanded);
2676 return;
2679 if ( propname == "LINK_DIRECTORIES" )
2681 std::vector<std::string> varArgsExpanded;
2682 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2683 this->SetLinkDirectories(varArgsExpanded);
2684 return;
2687 if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
2689 this->SetIncludeRegularExpression(value);
2690 return;
2693 if ( propname == "ADDITIONAL_MAKE_CLEAN_FILES" )
2695 // This property is not inherrited
2696 if ( strcmp(this->GetCurrentDirectory(),
2697 this->GetStartDirectory()) != 0 )
2699 return;
2703 this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
2706 void cmMakefile::AppendProperty(const char* prop, const char* value)
2708 if (!prop)
2710 return;
2713 // handle special props
2714 std::string propname = prop;
2715 if ( propname == "INCLUDE_DIRECTORIES" )
2717 std::vector<std::string> varArgsExpanded;
2718 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2719 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
2720 vi != varArgsExpanded.end(); ++vi)
2722 this->AddIncludeDirectory(vi->c_str());
2724 return;
2727 if ( propname == "LINK_DIRECTORIES" )
2729 std::vector<std::string> varArgsExpanded;
2730 cmSystemTools::ExpandListArgument(value, varArgsExpanded);
2731 for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
2732 vi != varArgsExpanded.end(); ++vi)
2734 this->AddLinkDirectory(vi->c_str());
2736 return;
2739 this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY);
2742 const char *cmMakefile::GetPropertyOrDefinition(const char* prop)
2744 const char *ret = this->GetProperty(prop, cmProperty::DIRECTORY);
2745 if (!ret)
2747 ret = this->GetDefinition(prop);
2749 return ret;
2752 const char *cmMakefile::GetProperty(const char* prop)
2754 return this->GetProperty(prop, cmProperty::DIRECTORY);
2757 const char *cmMakefile::GetProperty(const char* prop,
2758 cmProperty::ScopeType scope)
2760 // watch for specific properties
2761 static std::string output;
2762 output = "";
2763 if (!strcmp("PARENT_DIRECTORY",prop))
2765 output = this->LocalGenerator->GetParent()
2766 ->GetMakefile()->GetStartDirectory();
2767 return output.c_str();
2769 else if (!strcmp("INCLUDE_REGULAR_EXPRESSION",prop) )
2771 output = this->GetIncludeRegularExpression();
2772 return output.c_str();
2774 else if (!strcmp("LISTFILE_STACK",prop))
2776 for (std::deque<cmStdString>::iterator i = this->ListFileStack.begin();
2777 i != this->ListFileStack.end(); ++i)
2779 if (i != this->ListFileStack.begin())
2781 output += ";";
2783 output += *i;
2785 return output.c_str();
2787 else if (!strcmp("VARIABLES",prop) || !strcmp("CACHE_VARIABLES",prop))
2789 int cacheonly = 0;
2790 if ( !strcmp("CACHE_VARIABLES",prop) )
2792 cacheonly = 1;
2794 std::vector<std::string> vars = this->GetDefinitions(cacheonly);
2795 for (unsigned int cc = 0; cc < vars.size(); cc ++ )
2797 if ( cc > 0 )
2799 output += ";";
2801 output += vars[cc];
2803 return output.c_str();
2805 else if (!strcmp("MACROS",prop))
2807 this->GetListOfMacros(output);
2808 return output.c_str();
2810 else if (!strcmp("DEFINITIONS",prop))
2812 output = this->GetDefineFlags();
2813 return output.c_str();
2815 else if (!strcmp("INCLUDE_DIRECTORIES",prop) )
2817 cmOStringStream str;
2818 for (std::vector<std::string>::const_iterator
2819 it = this->GetIncludeDirectories().begin();
2820 it != this->GetIncludeDirectories().end();
2821 ++ it )
2823 if ( it != this->GetIncludeDirectories().begin())
2825 str << ";";
2827 str << it->c_str();
2829 output = str.str();
2830 return output.c_str();
2832 else if (!strcmp("LINK_DIRECTORIES",prop))
2834 cmOStringStream str;
2835 for (std::vector<std::string>::const_iterator
2836 it = this->GetLinkDirectories().begin();
2837 it != this->GetLinkDirectories().end();
2838 ++ it )
2840 if ( it != this->GetLinkDirectories().begin())
2842 str << ";";
2844 str << it->c_str();
2846 output = str.str();
2847 return output.c_str();
2850 bool chain = false;
2851 const char *retVal =
2852 this->Properties.GetPropertyValue(prop, scope, chain);
2853 if (chain)
2855 if(this->LocalGenerator->GetParent())
2857 return this->LocalGenerator->GetParent()->GetMakefile()->
2858 GetProperty(prop, scope);
2860 return this->GetCMakeInstance()->GetProperty(prop,scope);
2863 return retVal;
2866 bool cmMakefile::GetPropertyAsBool(const char* prop)
2868 return cmSystemTools::IsOn(this->GetProperty(prop));
2872 cmTarget* cmMakefile::FindTarget(const char* name)
2874 cmTargets& tgts = this->GetTargets();
2876 cmTargets::iterator i = tgts.find ( name );
2877 if ( i != tgts.end() )
2879 return &i->second;
2882 return 0;
2885 cmTest* cmMakefile::CreateTest(const char* testName)
2887 if ( !testName )
2889 return 0;
2891 cmTest* test = this->GetTest(testName);
2892 if ( test )
2894 return test;
2896 test = new cmTest;
2897 test->SetName(testName);
2898 test->SetMakefile(this);
2899 this->Tests.push_back(test);
2900 return test;
2903 cmTest* cmMakefile::GetTest(const char* testName) const
2905 if ( !testName )
2907 return 0;
2909 std::vector<cmTest*>::const_iterator it;
2910 for ( it = this->Tests.begin(); it != this->Tests.end(); ++ it )
2912 if ( strcmp((*it)->GetName(), testName) == 0 )
2914 return *it;
2917 return 0;
2920 const std::vector<cmTest*> *cmMakefile::GetTests() const
2922 return &this->Tests;
2925 std::vector<cmTest*> *cmMakefile::GetTests()
2927 return &this->Tests;
2930 std::string cmMakefile::GetListFileStack()
2932 cmOStringStream tmp;
2933 size_t depth = this->ListFileStack.size();
2934 if (depth > 0)
2936 std::deque<cmStdString>::iterator it = this->ListFileStack.end();
2939 if (depth != this->ListFileStack.size())
2941 tmp << "\n ";
2943 --it;
2944 tmp << "[";
2945 tmp << depth;
2946 tmp << "]\t";
2947 tmp << *it;
2948 depth--;
2950 while (it != this->ListFileStack.begin());
2952 return tmp.str();
2956 void cmMakefile::PushScope()
2958 // Get the index of the next stack entry.
2959 std::vector<DefinitionMap>::size_type index = this->DefinitionStack.size();
2961 // Allocate a new stack entry.
2962 this->DefinitionStack.push_back(DefinitionMap());
2964 // Copy the previous top to the new top.
2965 this->DefinitionStack[index] = this->DefinitionStack[index-1];
2968 void cmMakefile::PopScope()
2970 this->DefinitionStack.pop_back();
2973 void cmMakefile::RaiseScope(const char *var, const char *varDef)
2975 if (!var || !strlen(var))
2977 return;
2980 // multiple scopes in this directory?
2981 if (this->DefinitionStack.size() > 1)
2983 if(varDef)
2985 this->DefinitionStack[this->DefinitionStack.size()-2][var] = varDef;
2987 else
2989 this->DefinitionStack[this->DefinitionStack.size()-2].erase(var);
2992 // otherwise do the parent (if one exists)
2993 else if (this->LocalGenerator->GetParent())
2995 cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
2996 if (parent)
2998 if(varDef)
3000 parent->AddDefinition(var,varDef);
3002 else
3004 parent->RemoveDefinition(var);
3011 // define properties
3012 void cmMakefile::DefineProperties(cmake *cm)
3014 cm->DefineProperty
3015 ("ADDITIONAL_MAKE_CLEAN_FILES", cmProperty::DIRECTORY,
3016 "Additional files to clean during the make clean stage.",
3017 "A list of files that will be cleaned as a part of the "
3018 "\"make clean\" stage. ");
3020 cm->DefineProperty
3021 ("CLEAN_NO_CUSTOM", cmProperty::DIRECTORY,
3022 "Should the output of custom commands be left.",
3023 "If this is true then the outputs of custom commands for this "
3024 "directory will not be removed during the \"make clean\" stage. ");
3026 cm->DefineProperty
3027 ("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS", cmProperty::DIRECTORY,
3028 "Allow loops to have non-matching closing statements.",
3029 "If this is set then the closing statement of control "
3030 "structures in CMake will not require an exact match to the "
3031 "opening statement. For example IF(foo) will not require "
3032 "ENDIF(foo) but simple ENDIF() will work.",
3033 true);
3035 cm->DefineProperty
3036 ("LISTFILE_STACK", cmProperty::DIRECTORY,
3037 "The current stack of listfiles being processed.",
3038 "This property is mainly useful when trying to debug errors "
3039 "in your CMake scripts. It returns a list of what list files "
3040 "are currently being processed, in order. So if one listfile "
3041 "does an INCLUDE command then that is effectively pushing "
3042 "the included listfile onto the stack.");
3044 cm->DefineProperty
3045 ("TEST_INCLUDE_FILE", cmProperty::DIRECTORY,
3046 "A cmake file that will be included when ctest is run.",
3047 "If you specify TEST_INCLUDE_FILE, that file will be "
3048 "included and processed when ctest is run on the directory.");
3050 cm->DefineProperty
3051 ("COMPILE_DEFINITIONS", cmProperty::DIRECTORY,
3052 "Preprocessor definitions for compiling a directory's sources.",
3053 "The COMPILE_DEFINITIONS property may be set to a list of preprocessor "
3054 "definitions using the syntax VAR or VAR=value. Function-style "
3055 "definitions are not supported. CMake will automatically escape "
3056 "the value correctly for the native build system (note that CMake "
3057 "language syntax may require escapes to specify some values). "
3058 "This property may be set on a per-configuration basis using the name "
3059 "COMPILE_DEFINITIONS_<CONFIG> where <CONFIG> is an upper-case name "
3060 "(ex. \"COMPILE_DEFINITIONS_DEBUG\"). "
3061 "This property will be initialized in each directory by its value "
3062 "in the directory's parent.\n"
3063 "CMake will automatically drop some definitions that "
3064 "are not supported by the native build tool. "
3065 "The VS6 IDE does not support definitions with values "
3066 "(but NMake does).\n"
3067 "Dislaimer: Most native build tools have poor support for escaping "
3068 "certain values. CMake has work-arounds for many cases but some "
3069 "values may just not be possible to pass correctly. If a value "
3070 "does not seem to be escaped correctly, do not attempt to "
3071 "work-around the problem by adding escape sequences to the value. "
3072 "Your work-around may break in a future version of CMake that "
3073 "has improved escape support. Instead consider defining the macro "
3074 "in a (configured) header file. Then report the limitation.");
3076 cm->DefineProperty
3077 ("COMPILE_DEFINITIONS_<CONFIG>", cmProperty::DIRECTORY,
3078 "Per-configuration preprocessor definitions in a directory.",
3079 "This is the configuration-specific version of COMPILE_DEFINITIONS. "
3080 "This property will be initialized in each directory by its value "
3081 "in the directory's parent.\n");
3083 cm->DefineProperty
3084 ("EXCLUDE_FROM_ALL", cmProperty::DIRECTORY,
3085 "Exclude the directory from the all target of its parent.",
3086 "A property on a directory that indicates if its targets are excluded "
3087 "from the default build target. If it is not, then with a Makefile "
3088 "for example typing make will cause the targets to be built. "
3089 "The same concept applies to the default build of other generators.",
3090 false);
3093 //----------------------------------------------------------------------------
3094 cmTarget*
3095 cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type)
3097 // Create the target.
3098 cmsys::auto_ptr<cmTarget> target(new cmTarget);
3099 target->SetType(type, name);
3100 target->SetMakefile(this);
3101 target->MarkAsImported();
3103 // Add to the set of available imported targets.
3104 this->ImportedTargets[name] = target.get();
3106 // Transfer ownership to this cmMakefile object.
3107 this->ImportedTargetsOwned.push_back(target.get());
3108 return target.release();
3111 //----------------------------------------------------------------------------
3112 cmTarget* cmMakefile::FindTargetToUse(const char* name)
3114 // Look for an imported target. These take priority because they
3115 // are more local in scope and do not have to be globally unique.
3116 std::map<cmStdString, cmTarget*>::const_iterator
3117 imported = this->ImportedTargets.find(name);
3118 if(imported != this->ImportedTargets.end())
3120 return imported->second;
3123 // Look for a target built in this project.
3124 return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name);