1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmMakefile.cxx,v $
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"
31 #ifdef CMAKE_BUILD_WITH_CMAKE
32 # include "cmVariableWatch.h"
34 #include "cmInstallGenerator.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
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("", "^.*$");
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$");
92 this->AddDefaultDefinitions();
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
;
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
;
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
)
171 for(std::vector
<cmSourceFile
*>::iterator i
= this->SourceFiles
.begin();
172 i
!= this->SourceFiles
.end(); ++i
)
176 for(std::vector
<cmTest
*>::iterator i
= this->Tests
.begin();
177 i
!= this->Tests
.end(); ++i
)
181 for(std::vector
<cmTarget
*>::iterator
182 i
= this->ImportedTargetsOwned
.begin();
183 i
!= this->ImportedTargetsOwned
.end(); ++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
)
199 std::list
<cmFunctionBlocker
*>::iterator pos
;
200 for (pos
= this->FunctionBlockers
.begin();
201 pos
!= this->FunctionBlockers
.end(); ++pos
)
203 cmFunctionBlocker
* b
= *pos
;
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();
216 std::cout
<< (*i
).c_str() << " ";
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
;
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
;
270 bool cmMakefile::CommandExists(const char* name
) const
272 return this->GetCMakeInstance()->CommandExists(name
);
275 bool cmMakefile::ExecuteCommand(const cmListFileFunction
& lff
,
276 cmExecutionStatus
&status
)
280 // quick return if blocked
281 if(this->IsFunctionBlocked(lff
,status
))
287 std::string name
= lff
.Name
;
289 // execute the command
291 this->GetCMakeInstance()->GetCommand(name
.c_str());
294 const char* versionValue
295 = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
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());
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());
328 if ( this->GetCMakeInstance()->GetScriptMode() )
330 cmSystemTools::SetFatalErrorOccured();
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());
350 cmSystemTools::SetFatalErrorOccured();
352 // if the Cloned command was not used
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());
369 cmSystemTools::SetFatalErrorOccured();
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
;
401 cmSystemTools::CollapseFullPath(external_in
,
402 this->cmStartDirectory
.c_str());
403 external
= external_abs
.c_str();
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
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
;
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
);
458 *fullPath
=filenametoread
;
460 cmListFile cacheFile
;
461 if( !cacheFile
.ParseFile(filenametoread
, requireProjectCommand
) )
463 // pop the listfile off the stack
464 this->ListFileStack
.pop_back();
469 this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile
.c_str());
470 this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile
.c_str());
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());
492 // send scope ended to and function blockers
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();
519 void cmMakefile::AddCommand(cmCommand
* wg
)
521 this->GetCMakeInstance()->AddCommand(wg
);
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
)
545 // Generate the output file
546 void cmMakefile::ConfigureFinalPass()
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 //----------------------------------------------------------------------------
568 cmMakefile::AddCustomCommandToTarget(const char* target
,
569 const std::vector
<std::string
>& depends
,
570 const cmCustomCommandLines
& commandLines
,
571 cmTarget::CustomCommandType type
,
573 const char* workingDir
,
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
);
586 case cmTarget::PRE_BUILD
:
587 ti
->second
.GetPreBuildCommands().push_back(cc
);
589 case cmTarget::PRE_LINK
:
590 ti
->second
.GetPreLinkCommands().push_back(cc
);
592 case cmTarget::POST_BUILD
:
593 ti
->second
.GetPostBuildCommands().push_back(cc
);
599 //----------------------------------------------------------------------------
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
,
606 const char* workingDir
,
610 // Make sure there is at least one output.
613 cmSystemTools::Error("Attempt to add a custom rule with no output!");
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
635 // The existing custom command is different. We need to
636 // generate a rule file for this new command.
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.
651 // Construct a rule file associated with the first output produced.
652 std::string outName
= outputs
[0];
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 \"",
664 "\" which already has a custom rule.");
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.
693 cmCustomCommand
* cc
=
694 new cmCustomCommand(outputs
, depends2
, commandLines
,
695 comment
, workingDir
);
696 cc
->SetEscapeOldStyle(escapeOldStyle
);
697 file
->SetCustomCommand(cc
);
701 //----------------------------------------------------------------------------
703 cmMakefile::AddCustomCommandToOutput(const char* output
,
704 const std::vector
<std::string
>& depends
,
705 const char* main_dependency
,
706 const cmCustomCommandLines
& commandLines
,
708 const char* workingDir
,
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 //----------------------------------------------------------------------------
721 cmMakefile::AddCustomCommandOldStyle(const char* target
,
722 const std::vector
<std::string
>& outputs
,
723 const std::vector
<std::string
>& depends
,
725 const cmCustomCommandLines
& commandLines
,
728 // Translate the old-style signature to one of the new-style
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
735 this->AddCustomCommandToTarget(target
, depends
, commandLines
,
736 cmTarget::POST_BUILD
, comment
, 0);
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);
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
770 std::string sname
= output
;
772 if(!this->GetSource(sname
.c_str()))
774 if (this->Targets
.find(target
) != this->Targets
.end())
776 this->Targets
[target
].AddSource(source
);
780 cmSystemTools::Error("Attempt to add a custom rule to a target "
781 "that does not exist yet for target ", target
);
788 //----------------------------------------------------------------------------
789 void cmMakefile::AddUtilityCommand(const char* utilityName
,
791 const std::vector
<std::string
>& depends
,
792 const char* workingDirectory
,
799 // Construct the command line for the custom command.
800 cmCustomCommandLine commandLine
;
801 commandLine
.push_back(command
);
804 commandLine
.push_back(arg1
);
808 commandLine
.push_back(arg2
);
812 commandLine
.push_back(arg3
);
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
,
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
);
838 target
->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
842 // Use an empty comment to avoid generation of default comment.
846 // Store the custom command in the target.
847 std::string force
= this->GetStartOutputDirectory();
848 force
+= cmake::GetCMakeFilesDirectory();
850 force
+= utilityName
;
851 const char* no_main_dependency
= 0;
852 bool no_replace
= false;
853 this->AddCustomCommandToOutput(force
.c_str(), depends
,
855 commandLines
, comment
,
856 workingDirectory
, no_replace
,
858 cmSourceFile
* sf
= target
->AddSource(force
.c_str());
860 // The output is not actually created so mark it symbolic.
863 sf
->SetProperty("SYMBOLIC", "1");
867 cmSystemTools::Error("Could not get source file entry for ",
872 void cmMakefile::AddDefineFlag(const char* flag
)
879 // If this is really a definition, update COMPILE_DEFINITIONS.
880 if(this->ParseDefineFlag(flag
, false))
886 std::string ret
= flag
;
887 std::string::size_type pos
= 0;
888 while((pos
= ret
.find('\n', pos
)) != std::string::npos
)
894 while((pos
= ret
.find('\r', pos
)) != std::string::npos
)
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
);
914 // If this is really a definition, update COMPILE_DEFINITIONS.
915 if(this->ParseDefineFlag(flag
, true))
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
);
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
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()))
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
))
961 // Get the definition part after the flag.
962 const char* define
= def
.c_str() + 2;
966 if(const char* cdefs
= this->GetProperty("COMPILE_DEFINITIONS"))
969 std::vector
<std::string
> defs
;
970 cmSystemTools::ExpandListArgument(cdefs
, defs
);
972 // Recompose the list without the definition.
974 const char* sep
= "";
975 for(std::vector
<std::string
>::const_iterator di
= defs
.begin();
976 di
!= defs
.end(); ++di
)
986 // Store the new list.
987 this->SetProperty("COMPILE_DEFINITIONS", ndefs
.c_str());
992 // Append the definition to the directory property.
993 this->AppendProperty("COMPILE_DEFINITIONS", define
);
999 void cmMakefile::AddLinkLibrary(const char* lib
,
1000 cmTarget::LinkLibraryType llt
)
1002 cmTarget::LibraryID tmp
;
1005 this->LinkLibraries
.push_back(tmp
);
1008 void cmMakefile::AddLinkLibraryForTarget(const char *target
,
1010 cmTarget::LinkLibraryType llt
)
1012 cmTargets::iterator i
= this->Targets
.find(target
);
1013 if ( i
!= this->Targets
.end())
1016 this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib
);
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()))
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
)
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
1046 // if we allow modules but the type is not a module then it is
1048 (allowModules
&& tgt
->GetType() != cmTarget::MODULE_LIBRARY
))
1050 cmSystemTools::Error(e
.str().c_str());
1054 i
->second
.AddLinkLibrary( *this, target
, lib
, llt
);
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
,
1069 cmTargets::iterator i
= this->Targets
.find(target
);
1070 if ( i
!= this->Targets
.end())
1072 i
->second
.AddLinkDirectory( d
);
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.
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
);
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
;
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()));
1161 this->LinkLibraries
= parent
->LinkLibraries
;
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
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();
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();
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
,
1229 std::vector
<cmLocalGenerator
*>& children
=
1230 this->LocalGenerator
->GetChildren();
1231 // has this directory already been added? If so error
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",
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
);
1255 lg2
->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1257 lg2
->GetMakefile()->SetPreOrder(preorder
);
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
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())
1284 // WARNING: this *is* expensive (linear time) since it's a vector
1285 this->IncludeDirectories
.insert(this->IncludeDirectories
.begin(), inc
);
1289 this->IncludeDirectories
.push_back(inc
);
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
)
1325 if (this->GetCMakeInstance())
1327 this->GetCMakeInstance()->
1328 RecordPropertyAccess(name
,cmProperty::VARIABLE
);
1332 this->TemporaryDefinitionKey
= name
;
1333 this->DefinitionStack
.back()[this->TemporaryDefinitionKey
] = value
;
1335 #ifdef CMAKE_BUILD_WITH_CMAKE
1336 cmVariableWatch
* vv
= this->GetVariableWatch();
1339 vv
->VariableAccessed(this->TemporaryDefinitionKey
,
1340 cmVariableWatch::VARIABLE_MODIFIED_ACCESS
,
1348 void cmMakefile::AddCacheDefinition(const char* name
, const char* value
,
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
) &&
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());
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
)
1390 this->DefinitionStack
.back()
1391 .erase( DefinitionMap::key_type(name
));
1392 this->DefinitionStack
.back()
1393 .insert(DefinitionMap::value_type(name
, "ON"));
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();
1406 vv
->VariableAccessed(name
, cmVariableWatch::VARIABLE_MODIFIED_ACCESS
,
1407 value
?"ON":"OFF", this);
1413 void cmMakefile::AddCacheDefinition(const char* name
,
1418 cmCacheManager::CacheIterator it
=
1419 this->GetCacheManager()->GetCacheIterator(name
);
1420 if(!it
.IsAtEnd() && (it
.GetType() == cmCacheManager::UNINITIALIZED
) &&
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();
1436 vv
->VariableAccessed(name
, cmVariableWatch::VARIABLE_REMOVED_ACCESS
,
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
:
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
1484 target
->ClearDependencyInformation( *this, lname
);
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
);
1500 target
->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
1502 target
->AddSources(srcs
);
1503 this->AddGlobalLinkInformation(exeName
, *target
);
1507 //----------------------------------------------------------------------------
1509 cmMakefile::AddNewTarget(cmTarget::TargetType type
, const char* name
)
1511 cmTargets::iterator it
;
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
);
1521 cmSourceFile
*cmMakefile::GetSourceFileWithOutput(const char *cname
)
1523 std::string name
= cname
;
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
)
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] == '/'))
1554 // otherwise return NULL
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])
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());
1591 void cmMakefile::AddSourceGroup(const char* 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
,
1605 cmSourceGroup
* sg
= 0;
1606 std::vector
<std::string
> currentName
;
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
);
1619 // i now contains the index of the last found component
1622 // group already exists, replace its regular expression
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
);
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
);
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
);
1701 if ( cmSystemTools::IsNOTFOUND(value
) )
1709 bool cmMakefile::CanIWriteThisFile(const char* fileName
)
1711 if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
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") )
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()) )
1738 const char* cmMakefile::GetRequiredDefinition(const char* name
) const
1740 const char* ret
= this->GetDefinition(name
);
1743 cmSystemTools::Error("Error required internal CMake variable not "
1744 "set, cmake may be not be built correctly.\n",
1745 "Missing variable is:\n",
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();
1763 def
= this->GetCacheManager()->GetCacheValue(name
);
1765 #ifdef CMAKE_BUILD_WITH_CMAKE
1766 if(cmVariableWatch
* vv
= this->GetVariableWatch())
1770 vv
->VariableAccessed
1771 (name
, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS
,
1776 return def
?true:false;
1779 const char* cmMakefile::GetDefinition(const char* name
) const
1782 if (this->GetCMakeInstance())
1784 this->GetCMakeInstance()->
1785 RecordPropertyAccess(name
,cmProperty::VARIABLE
);
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();
1797 def
= this->GetCacheManager()->GetCacheValue(name
);
1799 #ifdef CMAKE_BUILD_WITH_CMAKE
1800 cmVariableWatch
* vv
= this->GetVariableWatch();
1805 vv
->VariableAccessed(name
, cmVariableWatch::VARIABLE_READ_ACCESS
,
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);
1822 vv
->VariableAccessed(name
,
1823 cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS
, def
, this);
1831 const char* cmMakefile::GetSafeDefinition(const char* def
) const
1833 const char* ret
= this->GetDefinition(def
);
1841 std::vector
<std::string
> cmMakefile
1842 ::GetDefinitions(int cacheonly
/* = 0 */) const
1844 std::map
<cmStdString
, int> definitions
;
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
);
1872 const char *cmMakefile::ExpandVariablesInString(std::string
& source
)
1874 return this->ExpandVariablesInString(source
, false, false);
1877 const char *cmMakefile::ExpandVariablesInString(std::string
& source
,
1881 const char* filename
,
1886 if ( source
.empty() || source
.find_first_of("$@\\") == source
.npos
)
1888 return source
.c_str();
1891 // Special-case the @ONLY mode.
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.
1901 // Store an original copy of the input.
1902 std::string input
= source
;
1904 // Start with empty output.
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.
1925 source
.append(cmSystemTools::EscapeQuotes(val
));
1933 // Continue looking for @VAR@ further along the string.
1937 // Append the rest of the unchanged part of the string.
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);
1958 source
= parser
.GetResult();
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");
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();
1984 cmSystemTools::Message(error
.str().c_str());
1987 return source
.c_str();
1990 void cmMakefile::RemoveVariablesInString(std::string
& source
,
1995 cmsys::RegularExpression
var("(\\${[A-Za-z_0-9]*})");
1996 while (var
.find(source
))
1998 source
.erase(var
.start(),var
.end() - var
.start());
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
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
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");
2039 this->AddDefinition("UNIX", "1");
2040 this->AddDefinition("CMAKE_HOST_UNIX", "1");
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");
2047 #if defined(__APPLE__)
2048 this->AddDefinition("APPLE", "1");
2049 this->AddDefinition("CMAKE_HOST_APPLE", "1");
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
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
);
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
);
2099 // Shouldn't get here, but just in case, return the default group.
2100 return groups
.front();
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())
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
))
2128 void cmMakefile::ExpandArguments(
2129 std::vector
<cmListFileArgument
> const& inArgs
,
2130 std::vector
<std::string
>& outArgs
)
2132 std::vector
<cmListFileArgument
>::const_iterator i
;
2134 outArgs
.reserve(inArgs
.size());
2135 for(i
= inArgs
.begin(); i
!= inArgs
.end(); ++i
)
2137 // Expand the variables in the argument.
2139 this->ExpandVariablesInString(value
, false, false, false,
2140 i
->FilePath
, i
->Line
,
2143 // If the argument is quoted, it should be one argument.
2144 // Otherwise, it may be a list of arguments.
2147 outArgs
.push_back(value
);
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
);
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
))
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
))
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())
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
))
2263 //----------------------------------------------------------------------------
2264 cmSourceFile
* cmMakefile::GetOrCreateSource(const char* sourceName
,
2267 if(cmSourceFile
* esf
= this->GetSource(sourceName
))
2273 cmSourceFile
* sf
= new cmSourceFile(this, sourceName
);
2276 sf
->SetProperty("GENERATED", "1");
2278 this->SourceFiles
.push_back(sf
);
2283 void cmMakefile::EnableLanguage(std::vector
<std::string
> const & lang
,
2286 this->AddDefinition("CMAKE_CFG_INTDIR",
2287 this->LocalGenerator
->GetGlobalGenerator()->GetCMakeCFGInitDirectory());
2288 this->LocalGenerator
->GetGlobalGenerator()->EnableLanguage(lang
, this,
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
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");
2326 cm
.SetIsInTryCompile(true);
2327 cmGlobalGenerator
*gg
= cm
.CreateGlobalGenerator
2328 (this->LocalGenerator
->GetGlobalGenerator()->GetName());
2331 cmSystemTools::Error(
2332 "Internal CMake error, TryCompile bad GlobalGenerator");
2333 // return to the original directory
2334 cmSystemTools::ChangeDirectory(cwd
.c_str());
2337 cm
.SetGlobalGenerator(gg
);
2340 cm
.SetHomeDirectory(srcdir
);
2341 cm
.SetHomeOutputDirectory(bindir
);
2342 cm
.SetStartDirectory(srcdir
);
2343 cm
.SetStartOutputDirectory(bindir
);
2344 cm
.SetCMakeCommand(cmakeCommand
.c_str());
2346 // if cmake args were provided then pass them in
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());
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());
2373 // finally call the generator to actually build the resulting project
2375 this->LocalGenerator
->GetGlobalGenerator()->TryCompile(srcdir
,bindir
,
2381 cmSystemTools::ChangeDirectory(cwd
.c_str());
2385 cmake
*cmMakefile::GetCMakeInstance() const
2387 if ( this->LocalGenerator
&& this->LocalGenerator
->GetGlobalGenerator() )
2389 return this->LocalGenerator
->GetGlobalGenerator()->GetCMakeInstance();
2394 #ifdef CMAKE_BUILD_WITH_CMAKE
2395 cmVariableWatch
*cmMakefile::GetVariableWatch() const
2397 if ( this->GetCMakeInstance() &&
2398 this->GetCMakeInstance()->GetVariableWatch() )
2400 return this->GetCMakeInstance()->GetVariableWatch();
2406 void cmMakefile::AddMacro(const char* name
, const char* signature
)
2408 if ( !name
|| !signature
)
2412 this->MacrosMap
[name
] = signature
;
2415 void cmMakefile::GetListOfMacros(std::string
& macros
)
2417 StringStringMap::iterator it
;
2420 for ( it
= this->MacrosMap
.begin(); it
!= this->MacrosMap
.end(); ++it
)
2426 macros
+= it
->first
;
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");
2448 cmSystemTools::ExpandListArgument(def
, modulePath
);
2451 // Also search in the standard modules location.
2452 def
= this->GetDefinition("CMAKE_ROOT");
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
);
2467 if(cmSystemTools::FileExists(itempl
.c_str()))
2475 void cmMakefile::ConfigureString(const std::string
& input
,
2476 std::string
& output
, bool atOnly
,
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')
2491 std::string
line(lineStart
, lineEnd
);
2493 // Skip the newline character.
2494 bool haveNewline
= (lineEnd
!= input
.end());
2500 // Replace #cmakedefine instances.
2501 if(this->cmDefineRegex
.find(line
))
2504 this->GetDefinition(this->cmDefineRegex
.match(1).c_str());
2505 if(!cmSystemTools::IsOff(def
))
2507 cmSystemTools::ReplaceString(line
, "#cmakedefine", "#define");
2512 output
+= "/* #undef ";
2513 output
+= this->cmDefineRegex
.match(1);
2517 else if(this->cmDefine01Regex
.find(line
))
2520 this->GetDefinition(this->cmDefine01Regex
.match(1).c_str());
2521 cmSystemTools::ReplaceString(line
, "#cmakedefine01", "#define");
2523 if(!cmSystemTools::IsOff(def
))
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
)
2555 if ( !this->CanIWriteThisFile(outfile
) )
2557 cmSystemTools::Error("Attempt to write file: ",
2558 outfile
, " into a source directory.");
2561 if ( !cmSystemTools::FileExists(infile
) )
2563 cmSystemTools::Error("File ", infile
, " does not exist.");
2566 std::string soutfile
= outfile
;
2567 std::string sinfile
= infile
;
2568 this->AddCMakeDependFile(infile
);
2569 cmSystemTools::ConvertToUnixSlashes(soutfile
);
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());
2581 if ( !cmSystemTools::CopyFileIfDifferent(sinfile
.c_str(),
2589 std::string tempOutputFile
= soutfile
;
2590 tempOutputFile
+= ".tmp";
2591 std::ofstream
fout(tempOutputFile
.c_str());
2594 cmSystemTools::Error(
2595 "Could not open file for write in copy operation ",
2596 tempOutputFile
.c_str());
2597 cmSystemTools::ReportLastSystemError("");
2600 std::ifstream
fin(sinfile
.c_str());
2603 cmSystemTools::Error("Could not open file for read in copy operation ",
2608 // now copy input to output and expand variables in the
2609 // input file at the same time
2611 std::string outLine
;
2612 while( cmSystemTools::GetLineFromStream(fin
, inLine
) )
2615 this->ConfigureString(inLine
, outLine
, atOnly
, escapeQuotes
);
2616 fout
<< outLine
.c_str() << "\n";
2618 // close the files before attempting to copy
2621 if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile
.c_str(),
2628 cmSystemTools::SetPermissions(soutfile
.c_str(), perm
);
2630 cmSystemTools::RemoveFile(tempOutputFile
.c_str());
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();
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());
2662 void cmMakefile::SetProperty(const char* prop
, const char* value
)
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
);
2679 if ( propname
== "LINK_DIRECTORIES" )
2681 std::vector
<std::string
> varArgsExpanded
;
2682 cmSystemTools::ExpandListArgument(value
, varArgsExpanded
);
2683 this->SetLinkDirectories(varArgsExpanded
);
2687 if ( propname
== "INCLUDE_REGULAR_EXPRESSION" )
2689 this->SetIncludeRegularExpression(value
);
2693 if ( propname
== "ADDITIONAL_MAKE_CLEAN_FILES" )
2695 // This property is not inherrited
2696 if ( strcmp(this->GetCurrentDirectory(),
2697 this->GetStartDirectory()) != 0 )
2703 this->Properties
.SetProperty(prop
,value
,cmProperty::DIRECTORY
);
2706 void cmMakefile::AppendProperty(const char* prop
, const char* value
)
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());
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());
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
);
2747 ret
= this->GetDefinition(prop
);
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
;
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())
2785 return output
.c_str();
2787 else if (!strcmp("VARIABLES",prop
) || !strcmp("CACHE_VARIABLES",prop
))
2790 if ( !strcmp("CACHE_VARIABLES",prop
) )
2794 std::vector
<std::string
> vars
= this->GetDefinitions(cacheonly
);
2795 for (unsigned int cc
= 0; cc
< vars
.size(); 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();
2823 if ( it
!= this->GetIncludeDirectories().begin())
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();
2840 if ( it
!= this->GetLinkDirectories().begin())
2847 return output
.c_str();
2851 const char *retVal
=
2852 this->Properties
.GetPropertyValue(prop
, scope
, chain
);
2855 if(this->LocalGenerator
->GetParent())
2857 return this->LocalGenerator
->GetParent()->GetMakefile()->
2858 GetProperty(prop
, scope
);
2860 return this->GetCMakeInstance()->GetProperty(prop
,scope
);
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() )
2885 cmTest
* cmMakefile::CreateTest(const char* testName
)
2891 cmTest
* test
= this->GetTest(testName
);
2897 test
->SetName(testName
);
2898 test
->SetMakefile(this);
2899 this->Tests
.push_back(test
);
2903 cmTest
* cmMakefile::GetTest(const char* testName
) const
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 )
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();
2936 std::deque
<cmStdString
>::iterator it
= this->ListFileStack
.end();
2939 if (depth
!= this->ListFileStack
.size())
2950 while (it
!= this->ListFileStack
.begin());
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
))
2980 // multiple scopes in this directory?
2981 if (this->DefinitionStack
.size() > 1)
2985 this->DefinitionStack
[this->DefinitionStack
.size()-2][var
] = varDef
;
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();
3000 parent
->AddDefinition(var
,varDef
);
3004 parent
->RemoveDefinition(var
);
3011 // define properties
3012 void cmMakefile::DefineProperties(cmake
*cm
)
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. ");
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. ");
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.",
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.");
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.");
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.");
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");
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.",
3093 //----------------------------------------------------------------------------
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
);