1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmMakefile.cxx,v $
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"
31 #ifdef CMAKE_BUILD_WITH_CMAKE
32 # include "cmVariableWatch.h"
34 #include "cmInstallGenerator.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
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("", "^.*$");
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$");
94 this->AddDefaultDefinitions();
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
;
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
;
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.
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
)
176 for(std::vector
<cmSourceFile
*>::iterator i
= this->SourceFiles
.begin();
177 i
!= this->SourceFiles
.end(); ++i
)
181 for(std::vector
<cmTest
*>::iterator i
= this->Tests
.begin();
182 i
!= this->Tests
.end(); ++i
)
186 for(std::vector
<cmTarget
*>::iterator
187 i
= this->ImportedTargetsOwned
.begin();
188 i
!= this->ImportedTargetsOwned
.end(); ++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
)
204 std::list
<cmFunctionBlocker
*>::iterator pos
;
205 for (pos
= this->FunctionBlockers
.begin();
206 pos
!= this->FunctionBlockers
.end(); ++pos
)
208 cmFunctionBlocker
* b
= *pos
;
211 this->FunctionBlockers
.clear();
212 if (this->PolicyStack
.size() != 1)
214 cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
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();
226 std::cout
<< (*i
).c_str() << " ";
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
;
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
;
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
302 // Construct the message header.
305 msg
<< "CMake Error:";
309 msg
<< "CMake Warning:";
312 // Add the immediate context.
313 CallStackType::const_reverse_iterator i
= this->CallStack
.rbegin();
314 if(i
!= this->CallStack
.rend())
318 (*i
).Status
->SetNestedError(true);
320 cmListFileContext
const& lfc
= *(*i
).Context
;
323 << this->LocalGenerator
->Convert(lfc
.FilePath
.c_str(),
324 cmLocalGenerator::HOME
)
325 << ":" << lfc
.Line
<< " " << lfc
.Name
;
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
);
340 msg
<< " in top-level directory";
344 // Add the message text.
347 cmDocumentationFormatterText formatter
;
348 formatter
.SetIndent(" ");
349 formatter
.PrintFormatted(msg
, text
.c_str());
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
;
361 << this->LocalGenerator
->Convert(lfc
.FilePath
.c_str(),
362 cmLocalGenerator::HOME
)
363 << ":" << lfc
.Line
<< " " << lfc
.Name
<< "\n";
373 // Output the message.
376 cmSystemTools::SetErrorOccured();
377 cmSystemTools::Message(msg
.str().c_str(), "Error");
381 cmSystemTools::Message(msg
.str().c_str(), "Warning");
385 //----------------------------------------------------------------------------
386 // Helper class to make sure the call stack is valid.
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
);
399 this->Makefile
->CallStack
.pop_back();
402 cmMakefile
* Makefile
;
405 //----------------------------------------------------------------------------
406 bool cmMakefile::ExecuteCommand(const cmListFileFunction
& lff
,
407 cmExecutionStatus
&status
)
411 // quick return if blocked
412 if(this->IsFunctionBlocked(lff
,status
))
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());
445 if ( this->GetCMakeInstance()->GetScriptMode() )
447 cmSystemTools::SetFatalErrorOccured();
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
);
464 cmSystemTools::SetFatalErrorOccured();
469 if(!cmSystemTools::GetFatalErrorOccured())
471 std::string error
= "Unknown CMake command \"";
474 this->IssueError(error
);
476 cmSystemTools::SetFatalErrorOccured();
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
;
508 cmSystemTools::CollapseFullPath(external_in
,
509 this->cmStartDirectory
.c_str());
510 external
= external_abs
.c_str();
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
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
;
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
);
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();
576 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile
.c_str());
577 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile
.c_str());
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;
597 // send scope ended to and function blockers
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)
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();
638 void cmMakefile::AddCommand(cmCommand
* wg
)
640 this->GetCMakeInstance()->AddCommand(wg
);
644 void cmMakefile::SetLocalGenerator(cmLocalGenerator
* lg
)
646 this->LocalGenerator
= lg
;
649 bool cmMakefile::NeedBackwardsCompatibility(unsigned int major
,
653 if(this->LocalGenerator
)
656 this->LocalGenerator
->NeedBackwardsCompatibility(major
, minor
, patch
);
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
)
679 // Generate the output file
680 void cmMakefile::ConfigureFinalPass()
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 //----------------------------------------------------------------------------
702 cmMakefile::AddCustomCommandToTarget(const char* target
,
703 const std::vector
<std::string
>& depends
,
704 const cmCustomCommandLines
& commandLines
,
705 cmTarget::CustomCommandType type
,
707 const char* workingDir
,
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
);
720 case cmTarget::PRE_BUILD
:
721 ti
->second
.GetPreBuildCommands().push_back(cc
);
723 case cmTarget::PRE_LINK
:
724 ti
->second
.GetPreLinkCommands().push_back(cc
);
726 case cmTarget::POST_BUILD
:
727 ti
->second
.GetPostBuildCommands().push_back(cc
);
733 //----------------------------------------------------------------------------
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
,
740 const char* workingDir
,
744 // Make sure there is at least one output.
747 cmSystemTools::Error("Attempt to add a custom rule with no output!");
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
769 // The existing custom command is different. We need to
770 // generate a rule file for this new command.
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.
785 // Construct a rule file associated with the first output produced.
786 std::string outName
= outputs
[0];
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 \"",
798 "\" which already has a custom rule.");
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.
827 cmCustomCommand
* cc
=
828 new cmCustomCommand(outputs
, depends2
, commandLines
,
829 comment
, workingDir
);
830 cc
->SetEscapeOldStyle(escapeOldStyle
);
831 file
->SetCustomCommand(cc
);
835 //----------------------------------------------------------------------------
837 cmMakefile::AddCustomCommandToOutput(const char* output
,
838 const std::vector
<std::string
>& depends
,
839 const char* main_dependency
,
840 const cmCustomCommandLines
& commandLines
,
842 const char* workingDir
,
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 //----------------------------------------------------------------------------
855 cmMakefile::AddCustomCommandOldStyle(const char* target
,
856 const std::vector
<std::string
>& outputs
,
857 const std::vector
<std::string
>& depends
,
859 const cmCustomCommandLines
& commandLines
,
862 // Translate the old-style signature to one of the new-style
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
869 this->AddCustomCommandToTarget(target
, depends
, commandLines
,
870 cmTarget::POST_BUILD
, comment
, 0);
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);
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
904 std::string sname
= output
;
906 if(!this->GetSource(sname
.c_str()))
908 if (this->Targets
.find(target
) != this->Targets
.end())
910 this->Targets
[target
].AddSource(source
);
914 cmSystemTools::Error("Attempt to add a custom rule to a target "
915 "that does not exist yet for target ", target
);
922 //----------------------------------------------------------------------------
923 void cmMakefile::AddUtilityCommand(const char* utilityName
,
925 const std::vector
<std::string
>& depends
,
926 const char* workingDirectory
,
933 // Construct the command line for the custom command.
934 cmCustomCommandLine commandLine
;
935 commandLine
.push_back(command
);
938 commandLine
.push_back(arg1
);
942 commandLine
.push_back(arg2
);
946 commandLine
.push_back(arg3
);
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
,
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
);
972 target
->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
976 // Use an empty comment to avoid generation of default comment.
980 // Store the custom command in the target.
981 std::string force
= this->GetStartOutputDirectory();
982 force
+= cmake::GetCMakeFilesDirectory();
984 force
+= utilityName
;
985 const char* no_main_dependency
= 0;
986 bool no_replace
= false;
987 this->AddCustomCommandToOutput(force
.c_str(), depends
,
989 commandLines
, comment
,
990 workingDirectory
, no_replace
,
992 cmSourceFile
* sf
= target
->AddSource(force
.c_str());
994 // The output is not actually created so mark it symbolic.
997 sf
->SetProperty("SYMBOLIC", "1");
1001 cmSystemTools::Error("Could not get source file entry for ",
1006 void cmMakefile::AddDefineFlag(const char* flag
)
1013 // If this is really a definition, update COMPILE_DEFINITIONS.
1014 if(this->ParseDefineFlag(flag
, false))
1020 std::string ret
= flag
;
1021 std::string::size_type pos
= 0;
1022 while((pos
= ret
.find('\n', pos
)) != std::string::npos
)
1028 while((pos
= ret
.find('\r', pos
)) != std::string::npos
)
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
);
1048 // If this is really a definition, update COMPILE_DEFINITIONS.
1049 if(this->ParseDefineFlag(flag
, true))
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
);
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
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()))
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
))
1095 // Get the definition part after the flag.
1096 const char* define
= def
.c_str() + 2;
1100 if(const char* cdefs
= this->GetProperty("COMPILE_DEFINITIONS"))
1103 std::vector
<std::string
> defs
;
1104 cmSystemTools::ExpandListArgument(cdefs
, defs
);
1106 // Recompose the list without the definition.
1108 const char* sep
= "";
1109 for(std::vector
<std::string
>::const_iterator di
= defs
.begin();
1110 di
!= defs
.end(); ++di
)
1120 // Store the new list.
1121 this->SetProperty("COMPILE_DEFINITIONS", ndefs
.c_str());
1126 // Append the definition to the directory property.
1127 this->AppendProperty("COMPILE_DEFINITIONS", define
);
1133 void cmMakefile::AddLinkLibrary(const char* lib
,
1134 cmTarget::LinkLibraryType llt
)
1136 cmTarget::LibraryID tmp
;
1139 this->LinkLibraries
.push_back(tmp
);
1142 void cmMakefile::AddLinkLibraryForTarget(const char *target
,
1144 cmTarget::LinkLibraryType llt
)
1146 cmTargets::iterator i
= this->Targets
.find(target
);
1147 if ( i
!= this->Targets
.end())
1150 this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib
);
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()))
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
)
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
1175 // if we allow modules but the type is not a module then it is
1177 (allowModules
&& tgt
->GetType() != cmTarget::MODULE_LIBRARY
))
1179 cmSystemTools::Error(e
.str().c_str());
1183 i
->second
.AddLinkLibrary( *this, target
, lib
, llt
);
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
,
1198 cmTargets::iterator i
= this->Targets
.find(target
);
1199 if ( i
!= this->Targets
.end())
1201 i
->second
.AddLinkDirectory( d
);
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.
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
);
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
;
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()));
1290 this->LinkLibraries
= parent
->LinkLibraries
;
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
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();
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();
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
,
1358 std::vector
<cmLocalGenerator
*>& children
=
1359 this->LocalGenerator
->GetChildren();
1360 // has this directory already been added? If so error
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",
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
);
1384 lg2
->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1386 lg2
->GetMakefile()->SetPreOrder(preorder
);
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
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())
1413 // WARNING: this *is* expensive (linear time) since it's a vector
1414 this->IncludeDirectories
.insert(this->IncludeDirectories
.begin(), inc
);
1418 this->IncludeDirectories
.push_back(inc
);
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
)
1454 if (this->GetCMakeInstance())
1456 this->GetCMakeInstance()->
1457 RecordPropertyAccess(name
,cmProperty::VARIABLE
);
1461 this->TemporaryDefinitionKey
= name
;
1462 this->DefinitionStack
.back()[this->TemporaryDefinitionKey
] = value
;
1464 #ifdef CMAKE_BUILD_WITH_CMAKE
1465 cmVariableWatch
* vv
= this->GetVariableWatch();
1468 vv
->VariableAccessed(this->TemporaryDefinitionKey
,
1469 cmVariableWatch::VARIABLE_MODIFIED_ACCESS
,
1477 void cmMakefile::AddCacheDefinition(const char* name
, const char* value
,
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
) &&
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());
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
)
1519 this->DefinitionStack
.back()
1520 .erase( DefinitionMap::key_type(name
));
1521 this->DefinitionStack
.back()
1522 .insert(DefinitionMap::value_type(name
, "ON"));
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();
1535 vv
->VariableAccessed(name
, cmVariableWatch::VARIABLE_MODIFIED_ACCESS
,
1536 value
?"ON":"OFF", this);
1542 void cmMakefile::AddCacheDefinition(const char* name
,
1547 cmCacheManager::CacheIterator it
=
1548 this->GetCacheManager()->GetCacheIterator(name
);
1549 if(!it
.IsAtEnd() && (it
.GetType() == cmCacheManager::UNINITIALIZED
) &&
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();
1565 vv
->VariableAccessed(name
, cmVariableWatch::VARIABLE_REMOVED_ACCESS
,
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
:
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
1613 target
->ClearDependencyInformation( *this, lname
);
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
);
1629 target
->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1631 target
->AddSources(srcs
);
1632 this->AddGlobalLinkInformation(exeName
, *target
);
1636 //----------------------------------------------------------------------------
1638 cmMakefile::AddNewTarget(cmTarget::TargetType type
, const char* name
)
1640 cmTargets::iterator it
;
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
);
1650 cmSourceFile
*cmMakefile::GetSourceFileWithOutput(const char *cname
)
1652 std::string name
= cname
;
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
)
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] == '/'))
1683 // otherwise return NULL
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])
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());
1720 void cmMakefile::AddSourceGroup(const char* 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
,
1734 cmSourceGroup
* sg
= 0;
1735 std::vector
<std::string
> currentName
;
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
);
1748 // i now contains the index of the last found component
1751 // group already exists, replace its regular expression
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
);
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
);
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
);
1830 if ( cmSystemTools::IsNOTFOUND(value
) )
1838 bool cmMakefile::CanIWriteThisFile(const char* fileName
)
1840 if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
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") )
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()) )
1867 const char* cmMakefile::GetRequiredDefinition(const char* name
) const
1869 const char* ret
= this->GetDefinition(name
);
1872 cmSystemTools::Error("Error required internal CMake variable not "
1873 "set, cmake may be not be built correctly.\n",
1874 "Missing variable is:\n",
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();
1892 def
= this->GetCacheManager()->GetCacheValue(name
);
1894 #ifdef CMAKE_BUILD_WITH_CMAKE
1895 if(cmVariableWatch
* vv
= this->GetVariableWatch())
1899 vv
->VariableAccessed
1900 (name
, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS
,
1905 return def
?true:false;
1908 const char* cmMakefile::GetDefinition(const char* name
) const
1911 if (this->GetCMakeInstance())
1913 this->GetCMakeInstance()->
1914 RecordPropertyAccess(name
,cmProperty::VARIABLE
);
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();
1926 def
= this->GetCacheManager()->GetCacheValue(name
);
1928 #ifdef CMAKE_BUILD_WITH_CMAKE
1929 cmVariableWatch
* vv
= this->GetVariableWatch();
1934 vv
->VariableAccessed(name
, cmVariableWatch::VARIABLE_READ_ACCESS
,
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);
1951 vv
->VariableAccessed(name
,
1952 cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS
, def
, this);
1960 const char* cmMakefile::GetSafeDefinition(const char* def
) const
1962 const char* ret
= this->GetDefinition(def
);
1970 std::vector
<std::string
> cmMakefile
1971 ::GetDefinitions(int cacheonly
/* = 0 */) const
1973 std::map
<cmStdString
, int> definitions
;
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
);
2001 const char *cmMakefile::ExpandVariablesInString(std::string
& source
)
2003 return this->ExpandVariablesInString(source
, false, false);
2006 const char *cmMakefile::ExpandVariablesInString(std::string
& source
,
2010 const char* filename
,
2015 if ( source
.empty() || source
.find_first_of("$@\\") == source
.npos
)
2017 return source
.c_str();
2020 // Special-case the @ONLY mode.
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.
2030 // Store an original copy of the input.
2031 std::string input
= source
;
2033 // Start with empty output.
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.
2054 source
.append(cmSystemTools::EscapeQuotes(val
));
2062 // Continue looking for @VAR@ further along the string.
2066 // Append the rest of the unchanged part of the string.
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);
2087 source
= parser
.GetResult();
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();
2105 cmSystemTools::Message(error
.str().c_str());
2108 return source
.c_str();
2111 void cmMakefile::RemoveVariablesInString(std::string
& source
,
2116 cmsys::RegularExpression
var("(\\${[A-Za-z_0-9]*})");
2117 while (var
.find(source
))
2119 source
.erase(var
.start(),var
.end() - var
.start());
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
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
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");
2160 this->AddDefinition("UNIX", "1");
2161 this->AddDefinition("CMAKE_HOST_UNIX", "1");
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");
2168 #if defined(__APPLE__)
2169 this->AddDefinition("APPLE", "1");
2170 this->AddDefinition("CMAKE_HOST_APPLE", "1");
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
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
);
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
);
2220 // Shouldn't get here, but just in case, return the default group.
2221 return groups
.front();
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())
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
))
2249 void cmMakefile::ExpandArguments(
2250 std::vector
<cmListFileArgument
> const& inArgs
,
2251 std::vector
<std::string
>& outArgs
)
2253 std::vector
<cmListFileArgument
>::const_iterator i
;
2255 outArgs
.reserve(inArgs
.size());
2256 for(i
= inArgs
.begin(); i
!= inArgs
.end(); ++i
)
2258 // Expand the variables in the argument.
2260 this->ExpandVariablesInString(value
, false, false, false,
2261 i
->FilePath
, i
->Line
,
2264 // If the argument is quoted, it should be one argument.
2265 // Otherwise, it may be a list of arguments.
2268 outArgs
.push_back(value
);
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
);
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
))
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
))
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())
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
))
2384 //----------------------------------------------------------------------------
2385 cmSourceFile
* cmMakefile::GetOrCreateSource(const char* sourceName
,
2388 if(cmSourceFile
* esf
= this->GetSource(sourceName
))
2394 cmSourceFile
* sf
= new cmSourceFile(this, sourceName
);
2397 sf
->SetProperty("GENERATED", "1");
2399 this->SourceFiles
.push_back(sf
);
2404 void cmMakefile::EnableLanguage(std::vector
<std::string
> const & lang
,
2407 this->AddDefinition("CMAKE_CFG_INTDIR",
2408 this->LocalGenerator
->GetGlobalGenerator()->GetCMakeCFGInitDirectory());
2409 this->LocalGenerator
->GetGlobalGenerator()->EnableLanguage(lang
, this,
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
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");
2447 cm
.SetIsInTryCompile(true);
2448 cmGlobalGenerator
*gg
= cm
.CreateGlobalGenerator
2449 (this->LocalGenerator
->GetGlobalGenerator()->GetName());
2452 cmSystemTools::Error(
2453 "Internal CMake error, TryCompile bad GlobalGenerator");
2454 // return to the original directory
2455 cmSystemTools::ChangeDirectory(cwd
.c_str());
2458 cm
.SetGlobalGenerator(gg
);
2461 cm
.SetHomeDirectory(srcdir
);
2462 cm
.SetHomeOutputDirectory(bindir
);
2463 cm
.SetStartDirectory(srcdir
);
2464 cm
.SetStartOutputDirectory(bindir
);
2465 cm
.SetCMakeCommand(cmakeCommand
.c_str());
2467 // if cmake args were provided then pass them in
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());
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());
2494 // finally call the generator to actually build the resulting project
2496 this->LocalGenerator
->GetGlobalGenerator()->TryCompile(srcdir
,bindir
,
2502 cmSystemTools::ChangeDirectory(cwd
.c_str());
2506 cmake
*cmMakefile::GetCMakeInstance() const
2508 if ( this->LocalGenerator
&& this->LocalGenerator
->GetGlobalGenerator() )
2510 return this->LocalGenerator
->GetGlobalGenerator()->GetCMakeInstance();
2515 #ifdef CMAKE_BUILD_WITH_CMAKE
2516 cmVariableWatch
*cmMakefile::GetVariableWatch() const
2518 if ( this->GetCMakeInstance() &&
2519 this->GetCMakeInstance()->GetVariableWatch() )
2521 return this->GetCMakeInstance()->GetVariableWatch();
2527 void cmMakefile::AddMacro(const char* name
, const char* signature
)
2529 if ( !name
|| !signature
)
2533 this->MacrosMap
[name
] = signature
;
2536 void cmMakefile::GetListOfMacros(std::string
& macros
)
2538 StringStringMap::iterator it
;
2541 for ( it
= this->MacrosMap
.begin(); it
!= this->MacrosMap
.end(); ++it
)
2547 macros
+= it
->first
;
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");
2569 cmSystemTools::ExpandListArgument(def
, modulePath
);
2572 // Also search in the standard modules location.
2573 def
= this->GetDefinition("CMAKE_ROOT");
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
);
2588 if(cmSystemTools::FileExists(itempl
.c_str()))
2596 void cmMakefile::ConfigureString(const std::string
& input
,
2597 std::string
& output
, bool atOnly
,
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')
2612 std::string
line(lineStart
, lineEnd
);
2614 // Skip the newline character.
2615 bool haveNewline
= (lineEnd
!= input
.end());
2621 // Replace #cmakedefine instances.
2622 if(this->cmDefineRegex
.find(line
))
2625 this->GetDefinition(this->cmDefineRegex
.match(1).c_str());
2626 if(!cmSystemTools::IsOff(def
))
2628 cmSystemTools::ReplaceString(line
, "#cmakedefine", "#define");
2633 output
+= "/* #undef ";
2634 output
+= this->cmDefineRegex
.match(1);
2638 else if(this->cmDefine01Regex
.find(line
))
2641 this->GetDefinition(this->cmDefine01Regex
.match(1).c_str());
2642 cmSystemTools::ReplaceString(line
, "#cmakedefine01", "#define");
2644 if(!cmSystemTools::IsOff(def
))
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
)
2676 if ( !this->CanIWriteThisFile(outfile
) )
2678 cmSystemTools::Error("Attempt to write file: ",
2679 outfile
, " into a source directory.");
2682 if ( !cmSystemTools::FileExists(infile
) )
2684 cmSystemTools::Error("File ", infile
, " does not exist.");
2687 std::string soutfile
= outfile
;
2688 std::string sinfile
= infile
;
2689 this->AddCMakeDependFile(infile
);
2690 cmSystemTools::ConvertToUnixSlashes(soutfile
);
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());
2702 if ( !cmSystemTools::CopyFileIfDifferent(sinfile
.c_str(),
2710 std::string tempOutputFile
= soutfile
;
2711 tempOutputFile
+= ".tmp";
2712 std::ofstream
fout(tempOutputFile
.c_str());
2715 cmSystemTools::Error(
2716 "Could not open file for write in copy operation ",
2717 tempOutputFile
.c_str());
2718 cmSystemTools::ReportLastSystemError("");
2721 std::ifstream
fin(sinfile
.c_str());
2724 cmSystemTools::Error("Could not open file for read in copy operation ",
2729 // now copy input to output and expand variables in the
2730 // input file at the same time
2732 std::string outLine
;
2733 while( cmSystemTools::GetLineFromStream(fin
, inLine
) )
2736 this->ConfigureString(inLine
, outLine
, atOnly
, escapeQuotes
);
2737 fout
<< outLine
.c_str() << "\n";
2739 // close the files before attempting to copy
2742 if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile
.c_str(),
2749 cmSystemTools::SetPermissions(soutfile
.c_str(), perm
);
2751 cmSystemTools::RemoveFile(tempOutputFile
.c_str());
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();
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());
2783 void cmMakefile::SetProperty(const char* prop
, const char* value
)
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
);
2800 if ( propname
== "LINK_DIRECTORIES" )
2802 std::vector
<std::string
> varArgsExpanded
;
2803 cmSystemTools::ExpandListArgument(value
, varArgsExpanded
);
2804 this->SetLinkDirectories(varArgsExpanded
);
2808 if ( propname
== "INCLUDE_REGULAR_EXPRESSION" )
2810 this->SetIncludeRegularExpression(value
);
2814 if ( propname
== "ADDITIONAL_MAKE_CLEAN_FILES" )
2816 // This property is not inherrited
2817 if ( strcmp(this->GetCurrentDirectory(),
2818 this->GetStartDirectory()) != 0 )
2824 this->Properties
.SetProperty(prop
,value
,cmProperty::DIRECTORY
);
2827 void cmMakefile::AppendProperty(const char* prop
, const char* value
)
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());
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());
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
);
2868 ret
= this->GetDefinition(prop
);
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
;
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())
2906 return output
.c_str();
2908 else if (!strcmp("VARIABLES",prop
) || !strcmp("CACHE_VARIABLES",prop
))
2911 if ( !strcmp("CACHE_VARIABLES",prop
) )
2915 std::vector
<std::string
> vars
= this->GetDefinitions(cacheonly
);
2916 for (unsigned int cc
= 0; cc
< vars
.size(); 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();
2944 if ( it
!= this->GetIncludeDirectories().begin())
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();
2961 if ( it
!= this->GetLinkDirectories().begin())
2968 return output
.c_str();
2972 const char *retVal
=
2973 this->Properties
.GetPropertyValue(prop
, scope
, chain
);
2976 if(this->LocalGenerator
->GetParent())
2978 return this->LocalGenerator
->GetParent()->GetMakefile()->
2979 GetProperty(prop
, scope
);
2981 return this->GetCMakeInstance()->GetProperty(prop
,scope
);
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() )
3006 cmTest
* cmMakefile::CreateTest(const char* testName
)
3012 cmTest
* test
= this->GetTest(testName
);
3018 test
->SetName(testName
);
3019 test
->SetMakefile(this);
3020 this->Tests
.push_back(test
);
3024 cmTest
* cmMakefile::GetTest(const char* testName
) const
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 )
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();
3057 std::deque
<cmStdString
>::iterator it
= this->ListFileStack
.end();
3060 if (depth
!= this->ListFileStack
.size())
3071 while (it
!= this->ListFileStack
.begin());
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
))
3101 // multiple scopes in this directory?
3102 if (this->DefinitionStack
.size() > 1)
3106 this->DefinitionStack
[this->DefinitionStack
.size()-2][var
] = varDef
;
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();
3121 parent
->AddDefinition(var
,varDef
);
3125 parent
->RemoveDefinition(var
);
3132 // define properties
3133 void cmMakefile::DefineProperties(cmake
*cm
)
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. ");
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. ");
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.");
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.");
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.");
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");
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.",
3205 //----------------------------------------------------------------------------
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
,
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.
3252 e
<< "cannot create target \"" << name
3253 << "\" because an imported target with the same name already exists.";
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
:
3267 case cmPolicies::REQUIRED_IF_USED
:
3268 case cmPolicies::REQUIRED_ALWAYS
:
3270 this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP_0002
)
3273 case cmPolicies::NEW
:
3277 // The conflict is with a non-imported target.
3278 // Allow this if the user has requested support.
3280 this->LocalGenerator
->GetGlobalGenerator()->GetCMakeInstance();
3281 if(isCustom
&& existing
->GetType() == cmTarget::UTILITY
&&
3282 this != existing
->GetMakefile() &&
3283 cm
->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
3288 // Produce an error that tells the user how to work around the
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 ";
3299 case cmTarget::STATIC_LIBRARY
:
3300 e
<< "a static library ";
3302 case cmTarget::SHARED_LIBRARY
:
3303 e
<< "a shared library ";
3305 case cmTarget::MODULE_LIBRARY
:
3306 e
<< "a module library ";
3308 case cmTarget::UTILITY
:
3309 e
<< "a custom target ";
3313 e
<< "created in source directory \""
3314 << existing
->GetMakefile()->GetCurrentDirectory() << "\". "
3315 << "See documentation for policy CMP_0002 for more details.";
3323 cmPolicies::PolicyStatus cmMakefile
3324 ::GetPolicyStatus(cmPolicies::PolicyID id
)
3326 cmPolicies::PolicyStatus status
= cmPolicies::REQUIRED_IF_USED
;
3327 PolicyMap::iterator mappos
;
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
;
3343 // if not found then
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
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
;
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 "
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 "
3405 "syntax should this version of CMake try to support.",
3406 cmCacheManager::STRING
);
3415 bool cmMakefile::PushPolicy()
3417 // Allocate a new stack entry.
3418 this->PolicyStack
.push_back(PolicyMap());
3422 bool cmMakefile::PopPolicy(bool reportError
)
3424 if(this->PolicyStack
.size() == 1)
3428 cmSystemTools::Error("Attempt to pop the policy stack past "
3433 this->PolicyStack
.pop_back();
3437 bool cmMakefile::SetPolicyVersion(const char *version
)
3439 return this->GetCMakeInstance()->GetPolicies()->
3440 ApplyPolicyVersion(this,version
);
3443 cmPolicies
*cmMakefile::GetPolicies()
3445 if (!this->GetCMakeInstance())
3449 return this->GetCMakeInstance()->GetPolicies();