1 /*=========================================================================
3 Program: Insight Segmentation & Registration Toolkit
4 Module: $RCSfile: cmMakefile.cxx,v $
6 Date: $Date: 2002-07-25 13:16:17 $
7 Version: $Revision: 1.148 $
9 Copyright (c) 2002 Insight Consortium. All rights reserved.
10 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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 "cmCommand.h"
19 #include "cmStandardIncludes.h"
20 #include "cmSourceFile.h"
21 #include "cmDirectory.h"
22 #include "cmSystemTools.h"
23 #include "cmMakefileGenerator.h"
24 #include "cmCommands.h"
25 #include "cmCacheManager.h"
26 #include "cmFunctionBlocker.h"
27 #include "cmListFileCache.h"
28 #include <stdio.h> // required for sprintf
30 // default is not to be building executables
31 cmMakefile::cmMakefile()
33 // Setup the default include file regular expression (match everything).
34 m_IncludeFileRegularExpression
= "^.*$";
35 // Setup the default include complaint regular expression (match nothing).
36 m_ComplainFileRegularExpression
= "^$";
37 // Source and header file extensions that we can handle
38 m_SourceFileExtensions
.push_back( "cxx" );
39 m_SourceFileExtensions
.push_back( "cpp" );
40 m_SourceFileExtensions
.push_back( "c" );
41 m_SourceFileExtensions
.push_back( "M" );
42 m_SourceFileExtensions
.push_back( "m" );
43 m_SourceFileExtensions
.push_back( "mm" );
45 m_HeaderFileExtensions
.push_back( "h" );
46 m_HeaderFileExtensions
.push_back( "txx" );
47 m_HeaderFileExtensions
.push_back( "in" );
50 m_MakefileGenerator
= 0;
51 this->AddSourceGroup("", "^.*$");
52 this->AddSourceGroup("Source Files", "\\.(cpp|C|c|cxx|rc|def|r|odl|idl|hpj|bat)$");
53 this->AddSourceGroup("Header Files", "\\.(h|hh|hpp|hxx|hm|inl)$");
54 this->AddDefaultCommands();
55 this->AddDefaultDefinitions();
58 unsigned int cmMakefile::GetCacheMajorVersion()
60 if(!cmCacheManager::GetInstance()->
61 GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"))
65 return atoi(cmCacheManager::GetInstance()->
66 GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"));
69 unsigned int cmMakefile::GetCacheMinorVersion()
71 if(!cmCacheManager::GetInstance()->
72 GetCacheValue("Cmake_Cache_MINOR_VERSION"))
76 return atoi(cmCacheManager::GetInstance()->
77 GetCacheValue("CMAKE_CACHE_MINOR_VERSION"));
81 void cmMakefile::AddDefaultCommands()
83 std::list
<cmCommand
*> commands
;
84 GetPredefinedCommands(commands
);
85 for(std::list
<cmCommand
*>::iterator i
= commands
.begin();
86 i
!= commands
.end(); ++i
)
90 #if defined(_WIN32) || defined(__CYGWIN__)
91 this->AddDefinition("WIN32", "1");
93 this->AddDefinition("UNIX", "1");
95 // Cygwin is more like unix so enable the unix commands
96 #if defined(__CYGWIN__)
97 this->AddDefinition("UNIX", "1");
98 this->AddDefinition("CYGWIN", "1");
100 #if defined(__APPLE__)
101 this->AddDefinition("APPLE", "1");
105 cmMakefile::~cmMakefile()
107 for(std::vector
<cmSourceFile
*>::iterator i
= m_SourceFiles
.begin();
108 i
!= m_SourceFiles
.end(); ++i
)
112 for(unsigned int i
=0; i
< m_UsedCommands
.size(); i
++)
114 delete m_UsedCommands
[i
];
116 for(RegisteredCommandsMap::iterator j
= m_Commands
.begin();
117 j
!= m_Commands
.end(); ++j
)
121 for(DataMap::const_iterator d
= m_DataMap
.begin();
122 d
!= m_DataMap
.end(); ++d
)
129 std::list
<cmFunctionBlocker
*>::iterator pos
;
130 for (pos
= m_FunctionBlockers
.begin();
131 pos
!= m_FunctionBlockers
.end(); pos
= m_FunctionBlockers
.begin())
133 cmFunctionBlocker
* b
= *pos
;
134 m_FunctionBlockers
.remove(*pos
);
137 delete m_MakefileGenerator
;
140 void cmMakefile::PrintStringVector(const char* s
, const std::vector
<std::string
>& v
) const
142 std::cout
<< s
<< ": ( \n";
143 for(std::vector
<std::string
>::const_iterator i
= v
.begin();
146 std::cout
<< (*i
).c_str() << " ";
152 // call print on all the classes in the makefile
153 void cmMakefile::Print() const
155 // print the class lists
156 std::cout
<< "classes:\n";
158 std::cout
<< " m_Targets: ";
159 for (cmTargets::const_iterator l
= m_Targets
.begin();
160 l
!= m_Targets
.end(); l
++)
162 std::cout
<< l
->first
<< std::endl
;
165 std::cout
<< " m_CurrentOutputDirectory; " <<
166 m_CurrentOutputDirectory
.c_str() << std::endl
;
167 std::cout
<< " m_StartOutputDirectory; " <<
168 m_StartOutputDirectory
.c_str() << std::endl
;
169 std::cout
<< " m_HomeOutputDirectory; " <<
170 m_HomeOutputDirectory
.c_str() << std::endl
;
171 std::cout
<< " m_cmCurrentDirectory; " <<
172 m_cmCurrentDirectory
.c_str() << std::endl
;
173 std::cout
<< " m_cmStartDirectory; " <<
174 m_cmStartDirectory
.c_str() << std::endl
;
175 std::cout
<< " m_cmHomeDirectory; " <<
176 m_cmHomeDirectory
.c_str() << std::endl
;
177 std::cout
<< " m_ProjectName; " << m_ProjectName
.c_str() << std::endl
;
178 this->PrintStringVector("m_SubDirectories ", m_SubDirectories
);
179 this->PrintStringVector("m_IncludeDirectories;", m_IncludeDirectories
);
180 this->PrintStringVector("m_LinkDirectories", m_LinkDirectories
);
181 for( std::vector
<cmSourceGroup
>::const_iterator i
= m_SourceGroups
.begin();
182 i
!= m_SourceGroups
.end(); ++i
)
188 bool cmMakefile::CommandExists(const char* name
) const
190 return (m_Commands
.find(name
) != m_Commands
.end());
193 void cmMakefile::ExecuteCommand(std::string
&name
,
194 std::vector
<std::string
> const& arguments
)
196 // quick return if blocked
197 if(this->IsFunctionBlocked(name
.c_str(), arguments
))
201 // execute the command
202 RegisteredCommandsMap::iterator pos
= m_Commands
.find(name
);
203 if(pos
!= m_Commands
.end())
205 cmCommand
* rm
= (*pos
).second
;
206 cmCommand
* usedCommand
= rm
->Clone();
207 usedCommand
->SetMakefile(this);
208 bool keepCommand
= false;
209 if(usedCommand
->GetEnabled())
211 // if not running in inherit mode or
212 // if the command is inherited then InitialPass it.
213 if(!m_Inheriting
|| usedCommand
->IsInherited())
215 std::vector
<std::string
> expandedArguments
;
216 for(std::vector
<std::string
>::const_iterator i
= arguments
.begin();
217 i
!= arguments
.end(); ++i
)
219 std::string tmps
= *i
;
220 this->ExpandVariablesInString(tmps
);
221 if (tmps
.find_first_not_of(" ") != std::string::npos
)
223 // we found something in the args
224 expandedArguments
.push_back(tmps
);
227 if(!usedCommand
->InitialPass(expandedArguments
))
230 error
= usedCommand
->GetName();
231 error
+= ": Error : \n";
232 error
+= usedCommand
->GetError();
233 error
+= " from CMakeLists.txt file in directory: ";
234 error
+= m_cmCurrentDirectory
;
235 cmSystemTools::Error(error
.c_str());
241 m_UsedCommands
.push_back(usedCommand
);
245 // if the Cloned command was not used
252 else if((name
== "CABLE_WRAP_TCL") || (name
== "CABLE_CLASS_SET") ||
253 (name
== "CONFIGURE_GCCXML"))
255 cmSystemTools::Error("The command ", name
.c_str(),
256 " is not implemented in this version of CMake.\n"
257 "Contact cable@public.kitware.com for more information.");
261 cmSystemTools::Error("unknown CMake command:", name
.c_str(),
262 "\nReading cmake file in directory:" ,
263 m_cmCurrentDirectory
.c_str());
267 // Parse the given CMakeLists.txt file into a list of classes.
268 // Reads in current CMakeLists file and all parent CMakeLists files
269 // executing all inherited commands in the parents
271 // if external is non-zero, this means that we have branched to grab some
272 // commands from a remote list-file (that is, the equivalent of a
273 // #include has been called). We DO NOT look at the parents of this
274 // list-file, and for all other purposes, the name of this list-file
275 // is "filename" and not "external".
276 bool cmMakefile::ReadListFile(const char* filename
, const char* external
)
278 // used to watch for blockers going out of scope
279 // e.g. mismatched IF statement
280 std::set
<cmFunctionBlocker
*> originalBlockers
;
282 // keep track of the current file being read
285 if(m_cmCurrentListFile
!= filename
)
287 m_cmCurrentListFile
= filename
;
289 // loop over current function blockers and record them
290 std::list
<cmFunctionBlocker
*>::iterator pos
;
291 for (pos
= m_FunctionBlockers
.begin();
292 pos
!= m_FunctionBlockers
.end(); ++pos
)
294 originalBlockers
.insert(*pos
);
298 // if this is not a remote makefile
299 // (if it were, this would be called from the "filename" call,
300 // rather than the "external" call)
303 // is there a parent CMakeLists file that does not go beyond the
304 // Home directory? if so recurse and read in that List file
305 std::string parentList
= this->GetParentListFileName(filename
);
306 if (parentList
!= "")
308 std::string srcdir
= m_cmCurrentDirectory
;
309 std::string bindir
= m_CurrentOutputDirectory
;
311 std::string::size_type pos
= parentList
.rfind('/');
313 m_cmCurrentDirectory
= parentList
.substr(0, pos
);
314 m_CurrentOutputDirectory
= m_HomeOutputDirectory
+ parentList
.substr(m_cmHomeDirectory
.size(), pos
- m_cmHomeDirectory
.size());
316 // if not found, oops
317 if(pos
== std::string::npos
)
319 cmSystemTools::Error("Trailing slash not found");
322 this->ReadListFile(parentList
.c_str());
324 // restore the current directory
325 m_cmCurrentDirectory
= srcdir
;
326 m_CurrentOutputDirectory
= bindir
;
330 // are we at the start CMakeLists file or are we processing a parent
333 // this might, or might not be true, irrespective if we are
334 // off looking at an external makefile.
335 m_Inheriting
= (m_cmCurrentDirectory
!= m_cmStartDirectory
);
337 // Now read the input file
338 const char *filenametoread
= filename
;
342 filenametoread
= external
;
346 cmListFileCache::GetInstance()->GetFileCache(filenametoread
);
351 // add this list file to the list of dependencies
352 m_ListFiles
.push_back( filenametoread
);
353 const size_t numberFunctions
= lf
->m_Functions
.size();
354 for(size_t i
=0; i
< numberFunctions
; ++i
)
356 cmListFileFunction
& curFunction
= lf
->m_Functions
[i
];
357 this->ExecuteCommand(curFunction
.m_Name
,
358 curFunction
.m_Arguments
);
361 // send scope ended to and funciton blockers
364 // loop over all function blockers to see if any block this command
365 std::list
<cmFunctionBlocker
*>::iterator pos
;
366 for (pos
= m_FunctionBlockers
.begin();
367 pos
!= m_FunctionBlockers
.end(); ++pos
)
369 // if this blocker was not in the original then send a
370 // scope ended message
371 if (originalBlockers
.find(*pos
) == originalBlockers
.end())
373 (*pos
)->ScopeEnded(*this);
382 void cmMakefile::AddCommand(cmCommand
* wg
)
384 std::string name
= wg
->GetName();
385 m_Commands
.insert( RegisteredCommandsMap::value_type(name
, wg
));
389 void cmMakefile::SetMakefileGenerator(cmMakefileGenerator
* mf
)
391 if(mf
== m_MakefileGenerator
)
395 delete m_MakefileGenerator
;
396 m_MakefileGenerator
= mf
;
397 mf
->SetMakefile(this);
400 void cmMakefile::FinalPass()
402 // do all the variable expansions here
403 this->ExpandVariables();
405 // give all the commands a chance to do something
406 // after the file has been parsed before generation
407 for(std::vector
<cmCommand
*>::iterator i
= m_UsedCommands
.begin();
408 i
!= m_UsedCommands
.end(); ++i
)
415 // Generate the output file
416 void cmMakefile::GenerateMakefile()
419 const char* versionValue
420 = this->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
421 bool oldVersion
= (!versionValue
|| atof(versionValue
) < 1.4);
424 for (cmTargets::iterator l
= m_Targets
.begin();
425 l
!= m_Targets
.end(); l
++)
427 l
->second
.GenerateSourceFilesFromSourceLists(*this);
428 // pick up any LINK_LIBRARIES that were added after the target
431 this->AddGlobalLinkInformation(l
->first
.c_str(), l
->second
);
433 l
->second
.AnalyzeLibDependencies(*this);
435 // now do the generation
436 m_MakefileGenerator
->GenerateMakefile();
440 void cmMakefile::AddCustomCommand(const char* source
,
442 const std::vector
<std::string
>& commandArgs
,
443 const std::vector
<std::string
>& depends
,
444 const std::vector
<std::string
>& outputs
,
448 if (m_Targets
.find(target
) != m_Targets
.end())
450 std::string expandC
= command
;
451 this->ExpandVariablesInString(expandC
);
452 std::string c
= cmSystemTools::EscapeSpaces(expandC
.c_str());
454 std::string combinedArgs
;
457 for (i
= 0; i
< commandArgs
.size(); ++i
)
459 combinedArgs
+= cmSystemTools::EscapeSpaces(commandArgs
[i
].c_str());
463 cmCustomCommand
cc(source
,c
.c_str(),combinedArgs
.c_str(),depends
,outputs
);
464 m_Targets
[target
].GetCustomCommands().push_back(cc
);
465 std::string cacheCommand
= command
;
466 this->ExpandVariablesInString(cacheCommand
);
467 if(cmCacheManager::GetInstance()->GetCacheValue(cacheCommand
.c_str()))
469 m_Targets
[target
].AddUtility(
470 cmCacheManager::GetInstance()->GetCacheValue(cacheCommand
.c_str()));
475 void cmMakefile::AddCustomCommand(const char* source
,
477 const std::vector
<std::string
>& commandArgs
,
478 const std::vector
<std::string
>& depends
,
482 std::vector
<std::string
> outputs
;
483 outputs
.push_back(output
);
484 this->AddCustomCommand(source
, command
, commandArgs
, depends
, outputs
, target
);
487 void cmMakefile::AddDefineFlag(const char* flag
)
489 m_DefineFlags
+= " ";
490 m_DefineFlags
+= flag
;
494 void cmMakefile::AddLinkLibrary(const char* lib
, cmTarget::LinkLibraryType llt
)
496 m_LinkLibraries
.push_back(
497 std::pair
<std::string
, cmTarget::LinkLibraryType
>(lib
,llt
));
500 void cmMakefile::AddLinkLibraryForTarget(const char *target
,
502 cmTarget::LinkLibraryType llt
)
504 cmTargets::iterator i
= m_Targets
.find(target
);
505 if ( i
!= m_Targets
.end())
507 i
->second
.AddLinkLibrary( *this, target
, lib
, llt
);
511 cmSystemTools::Error("Attempt to add link libraries to non-existant target: ", target
, " for lib ", lib
);
515 void cmMakefile::AddLinkDirectoryForTarget(const char *target
,
518 cmTargets::iterator i
= m_Targets
.find(target
);
519 if ( i
!= m_Targets
.end())
521 i
->second
.AddLinkDirectory( d
);
525 cmSystemTools::Error("Attempt to add link directories to non-existant target: ",
526 target
, " for directory ", d
);
530 void cmMakefile::AddLinkLibrary(const char* lib
)
532 this->AddLinkLibrary(lib
,cmTarget::GENERAL
);
535 void cmMakefile::AddLinkDirectory(const char* dir
)
537 // Don't add a link directory that is already present. Yes, this
538 // linear search results in n^2 behavior, but n won't be getting
539 // much bigger than 20. We cannot use a set because of order
540 // dependency of the link search path.
542 // remove trailing slashes
543 if(dir
&& dir
[strlen(dir
)-1] == '/')
545 std::string newdir
= dir
;
546 newdir
= newdir
.substr(0, newdir
.size()-1);
547 if(std::find(m_LinkDirectories
.begin(),
548 m_LinkDirectories
.end(), newdir
.c_str()) == m_LinkDirectories
.end())
550 m_LinkDirectories
.push_back(newdir
);
555 if(std::find(m_LinkDirectories
.begin(),
556 m_LinkDirectories
.end(), dir
) == m_LinkDirectories
.end())
558 m_LinkDirectories
.push_back(dir
);
563 void cmMakefile::AddSubDirectory(const char* sub
)
565 m_SubDirectories
.push_back(sub
);
568 void cmMakefile::AddIncludeDirectory(const char* inc
, bool before
)
570 // Don't add an include directory that is already present. Yes,
571 // this linear search results in n^2 behavior, but n won't be
572 // getting much bigger than 20. We cannot use a set because of
573 // order dependency of the include path.
574 if(std::find(m_IncludeDirectories
.begin(),
575 m_IncludeDirectories
.end(), inc
) == m_IncludeDirectories
.end())
579 // WARNING: this *is* expensive (linear time) since it's a vector
580 m_IncludeDirectories
.insert(m_IncludeDirectories
.begin(), inc
);
584 m_IncludeDirectories
.push_back(inc
);
590 void cmMakefile::AddDefinition(const char* name
, const char* value
)
592 m_Definitions
.erase( DefinitionMap::key_type(name
));
593 m_Definitions
.insert(DefinitionMap::value_type(name
, value
));
597 void cmMakefile::AddCacheDefinition(const char* name
, const char* value
,
599 cmCacheManager::CacheEntryType type
)
601 cmCacheManager::GetInstance()->AddCacheEntry(name
, value
, doc
, type
);
602 this->AddDefinition(name
, value
);
606 void cmMakefile::AddDefinition(const char* name
, bool value
)
610 m_Definitions
.erase( DefinitionMap::key_type(name
));
611 m_Definitions
.insert(DefinitionMap::value_type(name
, "ON"));
615 m_Definitions
.erase( DefinitionMap::key_type(name
));
616 m_Definitions
.insert(DefinitionMap::value_type(name
, "OFF"));
621 void cmMakefile::AddCacheDefinition(const char* name
, bool value
, const char* doc
)
623 cmCacheManager::GetInstance()->AddCacheEntry(name
, value
, doc
);
624 this->AddDefinition(name
, value
);
627 void cmMakefile::SetProjectName(const char* p
)
633 void cmMakefile::AddGlobalLinkInformation(const char* name
, cmTarget
& target
)
635 // for these targets do not add anything
636 switch(target
.GetType())
638 case cmTarget::UTILITY
: return;
639 case cmTarget::INSTALL_FILES
: return;
640 case cmTarget::INSTALL_PROGRAMS
: return;
643 std::vector
<std::string
>::iterator j
;
644 for(j
= m_LinkDirectories
.begin();
645 j
!= m_LinkDirectories
.end(); ++j
)
647 target
.AddLinkDirectory(j
->c_str());
649 target
.MergeLinkLibraries( *this, name
, m_LinkLibraries
);
653 void cmMakefile::AddLibrary(const char* lname
, int shared
,
654 const std::vector
<std::string
> &srcs
)
660 target
.SetType(cmTarget::STATIC_LIBRARY
);
663 target
.SetType(cmTarget::SHARED_LIBRARY
);
666 target
.SetType(cmTarget::MODULE_LIBRARY
);
669 target
.SetType(cmTarget::STATIC_LIBRARY
);
671 // Clear its dependencies. Otherwise, dependencies might persist
672 // over changes in CMakeLists.txt, making the information stale and
674 std::string depname
= lname
;
675 depname
+= "_LIB_DEPENDS";
676 cmCacheManager::GetInstance()->
677 AddCacheEntry(depname
.c_str(), "",
678 "Dependencies for target", cmCacheManager::STATIC
);
681 target
.SetInAll(true);
682 target
.GetSourceLists() = srcs
;
683 this->AddGlobalLinkInformation(lname
, target
);
684 m_Targets
.insert(cmTargets::value_type(lname
,target
));
686 // Add an entry into the cache
687 std::string libPath
= lname
;
688 libPath
+= "_CMAKE_PATH";
689 cmCacheManager::GetInstance()->
690 AddCacheEntry(libPath
.c_str(),
691 this->GetCurrentOutputDirectory(),
692 "Path to a library", cmCacheManager::INTERNAL
);
694 // Add an entry into the cache
695 std::string ltname
= lname
;
696 ltname
+= "_LIBRARY_TYPE";
700 cmCacheManager::GetInstance()->
701 AddCacheEntry(ltname
.c_str(),
703 "Whether a library is static, shared or module.",
704 cmCacheManager::INTERNAL
);
707 cmCacheManager::GetInstance()->
708 AddCacheEntry(ltname
.c_str(),
710 "Whether a library is static, shared or module.",
711 cmCacheManager::INTERNAL
);
714 cmCacheManager::GetInstance()->
715 AddCacheEntry(ltname
.c_str(),
717 "Whether a library is static, shared or module.",
718 cmCacheManager::INTERNAL
);
721 cmCacheManager::GetInstance()->
722 AddCacheEntry(ltname
.c_str(),
724 "Whether a library is static, shared or module.",
725 cmCacheManager::INTERNAL
);
730 void cmMakefile::AddExecutable(const char *exeName
,
731 const std::vector
<std::string
> &srcs
)
733 this->AddExecutable(exeName
,srcs
,false);
736 void cmMakefile::AddExecutable(const char *exeName
,
737 const std::vector
<std::string
> &srcs
,
743 target
.SetType(cmTarget::WIN32_EXECUTABLE
);
747 target
.SetType(cmTarget::EXECUTABLE
);
749 target
.SetInAll(true);
750 target
.GetSourceLists() = srcs
;
751 this->AddGlobalLinkInformation(exeName
, target
);
752 m_Targets
.insert(cmTargets::value_type(exeName
,target
));
755 // Add an entry into the cache
756 std::string exePath
= exeName
;
757 exePath
+= "_CMAKE_PATH";
758 cmCacheManager::GetInstance()->
759 AddCacheEntry(exePath
.c_str(),
760 this->GetCurrentOutputDirectory(),
761 "Path to an executable", cmCacheManager::INTERNAL
);
765 void cmMakefile::AddUtilityCommand(const char* utilityName
,
767 const char* arguments
,
770 std::vector
<std::string
> empty
;
771 this->AddUtilityCommand(utilityName
,command
,arguments
,all
,
775 void cmMakefile::AddUtilityCommand(const char* utilityName
,
777 const char* arguments
,
779 const std::vector
<std::string
> &dep
,
780 const std::vector
<std::string
> &out
)
783 target
.SetType(cmTarget::UTILITY
);
784 target
.SetInAll(all
);
785 cmCustomCommand
cc(utilityName
, command
, arguments
, dep
, out
);
786 target
.GetCustomCommands().push_back(cc
);
787 m_Targets
.insert(cmTargets::value_type(utilityName
,target
));
791 void cmMakefile::AddSourceGroup(const char* name
, const char* regex
)
793 // First see if the group exists. If so, replace its regular expression.
794 for(std::vector
<cmSourceGroup
>::iterator sg
= m_SourceGroups
.begin();
795 sg
!= m_SourceGroups
.end(); ++sg
)
797 std::string sgName
= sg
->GetName();
800 // We only want to set the regular expression. If there are already
801 // source files in the group, we don't want to remove them.
802 sg
->SetGroupRegex(regex
);
807 // The group doesn't exist. Add it.
808 m_SourceGroups
.push_back(cmSourceGroup(name
, regex
));
811 void cmMakefile::AddExtraDirectory(const char* dir
)
813 m_AuxSourceDirectories
.push_back(dir
);
817 // return the file name for the parent CMakeLists file to the
818 // one passed in. Zero is returned if the CMakeLists file is the
819 // one in the home directory or if for some reason a parent cmake lists
820 // file cannot be found.
821 std::string
cmMakefile::GetParentListFileName(const char *currentFileName
)
823 // extract the directory name
824 std::string parentFile
;
825 std::string listsDir
= currentFileName
;
826 std::string::size_type pos
= listsDir
.rfind('/');
827 // if we could not find the directory return 0
828 if(pos
== std::string::npos
)
832 listsDir
= listsDir
.substr(0, pos
);
834 // if we are in the home directory then stop, return 0
835 if(m_cmHomeDirectory
== listsDir
)
840 // is there a parent directory we can check
841 pos
= listsDir
.rfind('/');
842 // if we could not find the directory return 0
843 if(pos
== std::string::npos
)
847 listsDir
= listsDir
.substr(0, pos
);
849 // is there a CMakeLists.txt file in the parent directory ?
850 parentFile
= listsDir
;
851 parentFile
+= "/CMakeLists.txt";
852 while(!cmSystemTools::FileExists(parentFile
.c_str()))
854 // There is no CMakeLists.txt file in the parent directory. This
855 // can occur when coming out of a subdirectory resulting from a
856 // SUBDIRS(Foo/Bar) command (coming out of Bar into Foo). Try
857 // walking up until a CMakeLists.txt is found or the home
860 // if we are in the home directory then stop, return 0
861 if(m_cmHomeDirectory
== listsDir
) { return ""; }
863 // is there a parent directory we can check
864 pos
= listsDir
.rfind('/');
865 // if we could not find the directory return 0
866 if(pos
== std::string::npos
) { return ""; }
867 listsDir
= listsDir
.substr(0, pos
);
868 parentFile
= listsDir
;
869 parentFile
+= "/CMakeLists.txt";
875 // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
876 // include and library directories.
878 void cmMakefile::ExpandVariables()
880 // Now expand varibles in the include and link strings
881 for(std::vector
<std::string
>::iterator d
= m_IncludeDirectories
.begin();
882 d
!= m_IncludeDirectories
.end(); ++d
)
884 this->ExpandVariablesInString(*d
);
886 for(std::vector
<std::string
>::iterator d
= m_LinkDirectories
.begin();
887 d
!= m_LinkDirectories
.end(); ++d
)
889 this->ExpandVariablesInString(*d
);
891 for(cmTarget::LinkLibraries::iterator l
= m_LinkLibraries
.begin();
892 l
!= m_LinkLibraries
.end(); ++l
)
894 this->ExpandVariablesInString(l
->first
);
898 bool cmMakefile::IsOn(const char* name
) const
900 const char* value
= this->GetDefinition(name
);
901 return cmSystemTools::IsOn(value
);
904 const char* cmMakefile::GetDefinition(const char* name
) const
906 DefinitionMap::const_iterator pos
= m_Definitions
.find(name
);
907 if(pos
!= m_Definitions
.end())
909 return (*pos
).second
.c_str();
911 return cmCacheManager::GetInstance()->GetCacheValue(name
);
914 int cmMakefile::DumpDocumentationToFile(std::ostream
& f
)
916 // Open the supplied filename
918 // Loop over all registered commands and print out documentation
923 sprintf(tmp
,"Version %d.%d", cmMakefile::GetMajorVersion(),
924 cmMakefile::GetMinorVersion());
926 f
<< "<h1>Documentation for commands of CMake " << tmp
<< "</h1>\n";
928 for(RegisteredCommandsMap::iterator j
= m_Commands
.begin();
929 j
!= m_Commands
.end(); ++j
)
931 name
= (*j
).second
->GetName();
932 terse
= (*j
).second
->GetTerseDocumentation();
933 full
= (*j
).second
->GetFullDocumentation();
934 f
<< "<li><b>" << name
<< "</b> - " << terse
<< std::endl
935 << "<br><i>Usage:</i> " << full
<< "</li>" << std::endl
<< std::endl
;
937 f
<< "</ul></html>\n";
942 const char *cmMakefile::ExpandVariablesInString(std::string
& source
) const
944 return this->ExpandVariablesInString(source
, false);
947 const char *cmMakefile::ExpandVariablesInString(std::string
& source
,
951 // This method replaces ${VAR} and @VAR@ where VAR is looked up
952 // with GetDefinition(), if not found in the map, nothing is expanded.
953 // It also supports the $ENV{VAR} syntax where VAR is looked up in
954 // the current environment variables.
956 // start by look for $ or @ in the string
957 std::string::size_type markerPos
;
960 markerPos
= source
.find_first_of("@");
964 markerPos
= source
.find_first_of("$@");
966 // if not found, or found as the last character, then leave quickly as
967 // nothing needs to be expanded
968 if((markerPos
== std::string::npos
) || (markerPos
>= source
.size()-1))
970 return source
.c_str();
973 std::string::size_type currentPos
=0; // start at 0
974 std::string result
; // string with replacements
975 // go until the the end of the string
976 while((markerPos
!= std::string::npos
) && (markerPos
< source
.size()-1))
978 // grab string from currentPos to the start of the variable
979 // and add it to the result
980 result
+= source
.substr(currentPos
, markerPos
- currentPos
);
981 char endVariableMarker
; // what is the end of the variable @ or }
982 int markerStartSize
= 1; // size of the start marker 1 or 2 or 5
983 if(!atOnly
&& source
[markerPos
] == '$')
986 if(source
[markerPos
+1] == '{')
988 endVariableMarker
= '}';
992 else if(markerPos
+4 < source
.size() &&
993 source
[markerPos
+4] == '{' &&
994 !source
.substr(markerPos
+1, 3).compare("ENV"))
996 endVariableMarker
= '}';
1001 // bogus $ with no { so add $ to result and move on
1002 result
+= '$'; // add bogus $ back into string
1003 currentPos
= markerPos
+1; // move on
1004 endVariableMarker
= ' '; // set end var to space so we can tell bogus
1010 endVariableMarker
= '@';
1012 // if it was a valid variable (started with @ or ${ or $ENV{ )
1013 if(endVariableMarker
!= ' ')
1015 markerPos
+= markerStartSize
; // move past marker
1016 // find the end variable marker starting at the markerPos
1017 std::string::size_type endVariablePos
=
1018 source
.find(endVariableMarker
, markerPos
);
1019 if(endVariablePos
== std::string::npos
)
1021 // no end marker found so add the bogus start
1022 if(endVariableMarker
== '@')
1028 result
+= (markerStartSize
== 5 ? "$ENV{" : "${");
1030 currentPos
= markerPos
;
1034 // good variable remove it
1035 std::string var
= source
.substr(markerPos
, endVariablePos
- markerPos
);
1037 if (markerStartSize
== 5) // $ENV{
1039 char *ptr
= getenv(var
.c_str());
1044 result
+= cmSystemTools::EscapeQuotes(ptr
);
1055 const char* lookup
= this->GetDefinition(var
.c_str());
1060 result
+= cmSystemTools::EscapeQuotes(lookup
);
1069 // if found add to result, if not, then it gets blanked
1072 // if no definition is found then add the var back
1073 if(endVariableMarker
== '@')
1079 // do nothing, we remove the variable
1082 result += (markerStartSize == 5 ? "$ENV{" : "${");
1088 // lookup var, and replace it
1089 currentPos
= endVariablePos
+1;
1094 markerPos
= source
.find_first_of("@", currentPos
);
1098 markerPos
= source
.find_first_of("$@", currentPos
);
1101 result
+= source
.substr(currentPos
); // pick up the rest of the string
1103 return source
.c_str();
1106 void cmMakefile::RemoveVariablesInString(std::string
& source
,
1111 cmRegularExpression
var("(\\${[A-Za-z_0-9]*})");
1112 while (var
.find(source
))
1114 source
.erase(var
.start(),var
.end() - var
.start());
1120 cmRegularExpression
varb("(\\$ENV{[A-Za-z_0-9]*})");
1121 while (varb
.find(source
))
1123 source
.erase(varb
.start(),varb
.end() - varb
.start());
1126 cmRegularExpression
var2("(@[A-Za-z_0-9]*@)");
1127 while (var2
.find(source
))
1129 source
.erase(var2
.start(),var2
.end() - var2
.start());
1133 // recursive function to create a vector of cmMakefile objects
1134 // This is done by reading the sub directory CMakeLists.txt files,
1135 // then calling this function with the new cmMakefile object
1137 cmMakefile::FindSubDirectoryCMakeListsFiles(std::vector
<cmMakefile
*>& makefiles
)
1139 // loop over all the sub directories of this makefile
1140 const std::vector
<std::string
>& subdirs
= this->GetSubDirectories();
1141 for(std::vector
<std::string
>::const_iterator i
= subdirs
.begin();
1142 i
!= subdirs
.end(); ++i
)
1144 std::string subdir
= *i
;
1145 // Create a path to the list file in the sub directory
1146 std::string listFile
= this->GetCurrentDirectory();
1149 listFile
+= "/CMakeLists.txt";
1150 // if there is a CMakeLists.txt file read it
1151 if(!cmSystemTools::FileExists(listFile
.c_str()))
1153 cmSystemTools::Error("CMakeLists.txt file missing from sub directory:",
1158 cmMakefile
* mf
= new cmMakefile
;
1159 mf
->SetMakefileGenerator(m_MakefileGenerator
->CreateObject());
1160 makefiles
.push_back(mf
);
1161 // initialize new makefile
1162 mf
->SetHomeOutputDirectory(this->GetHomeOutputDirectory());
1163 mf
->SetHomeDirectory(this->GetHomeDirectory());
1164 // add the subdir to the start output directory
1165 std::string outdir
= this->GetStartOutputDirectory();
1168 mf
->SetStartOutputDirectory(outdir
.c_str());
1169 // add the subdir to the start source directory
1170 std::string currentDir
= this->GetStartDirectory();
1172 currentDir
+= subdir
;
1173 mf
->SetStartDirectory(currentDir
.c_str());
1174 // Parse the CMakeLists.txt file
1175 currentDir
+= "/CMakeLists.txt";
1176 mf
->MakeStartDirectoriesCurrent();
1177 mf
->ReadListFile(currentDir
.c_str());
1178 // recurse into nextDir
1179 mf
->FindSubDirectoryCMakeListsFiles(makefiles
);
1186 * Add the default definitions to the makefile. These values must not
1187 * be dependent on anything that isn't known when this cmMakefile instance
1190 void cmMakefile::AddDefaultDefinitions()
1192 #if defined(_WIN32) && !defined(__CYGWIN__)
1193 this->AddDefinition("CMAKE_CFG_INTDIR","$(IntDir)");
1195 this->AddDefinition("CMAKE_CFG_INTDIR",".");
1198 sprintf(temp
, "%d", cmMakefile::GetMinorVersion());
1199 this->AddDefinition("CMAKE_MINOR_VERSION", temp
);
1200 sprintf(temp
, "%d", cmMakefile::GetMajorVersion());
1201 this->AddDefinition("CMAKE_MAJOR_VERSION", temp
);
1205 * Find a source group whose regular expression matches the filename
1206 * part of the given source name. Search backward through the list of
1207 * source groups, and take the first matching group found. This way
1208 * non-inherited SOURCE_GROUP commands will have precedence over
1212 cmMakefile::FindSourceGroup(const char* source
,
1213 std::vector
<cmSourceGroup
> &groups
)
1215 std::string file
= source
;
1216 std::string::size_type pos
= file
.rfind('/');
1217 if(pos
!= std::string::npos
)
1219 file
= file
.substr(pos
, file
.length()-pos
);
1222 for(std::vector
<cmSourceGroup
>::reverse_iterator sg
= groups
.rbegin();
1223 sg
!= groups
.rend(); ++sg
)
1225 if(sg
->Matches(file
.c_str()))
1231 // Shouldn't get here, but just in case, return the default group.
1232 return groups
.front();
1235 bool cmMakefile::IsFunctionBlocked(const char *name
,
1236 std::vector
<std::string
> const&args
)
1238 // if there are no blockers get out of here
1239 if (m_FunctionBlockers
.begin() == m_FunctionBlockers
.end())
1244 // loop over all function blockers to see if any block this command
1245 std::list
<cmFunctionBlocker
*>::iterator pos
;
1246 std::vector
<std::string
> expandedArguments
;
1247 for(std::vector
<std::string
>::const_iterator i
= args
.begin();
1248 i
!= args
.end(); ++i
)
1250 std::string tmps
= *i
;
1251 this->ExpandVariablesInString(tmps
);
1252 if (tmps
.find_first_not_of(" ") != std::string::npos
)
1254 // we found something in the args
1255 expandedArguments
.push_back(tmps
);
1258 for (pos
= m_FunctionBlockers
.begin();
1259 pos
!= m_FunctionBlockers
.end(); ++pos
)
1261 if ((*pos
)->NeedExpandedVariables())
1263 if ((*pos
)->IsFunctionBlocked(name
, expandedArguments
, *this))
1270 if ((*pos
)->IsFunctionBlocked(name
, args
, *this))
1280 void cmMakefile::RemoveFunctionBlocker(const char *name
,
1281 const std::vector
<std::string
> &args
)
1283 // loop over all function blockers to see if any block this command
1284 std::list
<cmFunctionBlocker
*>::reverse_iterator pos
;
1285 for (pos
= m_FunctionBlockers
.rbegin();
1286 pos
!= m_FunctionBlockers
.rend(); ++pos
)
1288 if ((*pos
)->ShouldRemove(name
, args
, *this))
1290 cmFunctionBlocker
* b
= *pos
;
1291 m_FunctionBlockers
.remove(*pos
);
1300 void cmMakefile::SetHomeDirectory(const char* dir
)
1302 m_cmHomeDirectory
= dir
;
1303 cmSystemTools::ConvertToUnixSlashes(m_cmHomeDirectory
);
1304 this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
1307 void cmMakefile::SetHomeOutputDirectory(const char* lib
)
1309 m_HomeOutputDirectory
= lib
;
1310 cmSystemTools::ConvertToUnixSlashes(m_HomeOutputDirectory
);
1311 this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
1316 * Register the given cmData instance with its own name.
1318 void cmMakefile::RegisterData(cmData
* data
)
1320 std::string name
= data
->GetName();
1321 DataMap::const_iterator d
= m_DataMap
.find(name
);
1322 if((d
!= m_DataMap
.end()) && (d
->second
!= NULL
) && (d
->second
!= data
))
1326 m_DataMap
[name
] = data
;
1331 * Register the given cmData instance with the given name. This can be used
1332 * to register a NULL pointer.
1334 void cmMakefile::RegisterData(const char* name
, cmData
* data
)
1336 DataMap::const_iterator d
= m_DataMap
.find(name
);
1337 if((d
!= m_DataMap
.end()) && (d
->second
!= NULL
) && (d
->second
!= data
))
1341 m_DataMap
[name
] = data
;
1346 * Lookup a cmData instance previously registered with the given name. If
1347 * the instance cannot be found, return NULL.
1349 cmData
* cmMakefile::LookupData(const char* name
) const
1351 DataMap::const_iterator d
= m_DataMap
.find(name
);
1352 if(d
!= m_DataMap
.end())
1362 cmSourceFile
* cmMakefile::GetSource(const char* sourceName
) const
1364 std::string s
= cmSystemTools::GetFilenameName(sourceName
);
1366 std::string::size_type pos
= s
.rfind('.');
1367 if(pos
!= std::string::npos
)
1369 ext
= s
.substr(pos
+1, s
.size() - pos
-1);
1370 s
= s
.substr(0, pos
);
1372 for(std::vector
<cmSourceFile
*>::const_iterator i
= m_SourceFiles
.begin();
1373 i
!= m_SourceFiles
.end(); ++i
)
1375 if ((*i
)->GetSourceName() == s
)
1377 if ((ext
.size() == 0 || (ext
== (*i
)->GetSourceExtension())))
1388 cmSourceFile
* cmMakefile::AddSource(cmSourceFile
const&sf
)
1390 // check to see if it exists
1391 cmSourceFile
* ret
= this->GetSource(sf
.GetSourceName().c_str());
1392 if(ret
&& ret
->GetSourceExtension() == sf
.GetSourceExtension())
1396 ret
= new cmSourceFile(sf
);
1397 m_SourceFiles
.push_back(ret
);
1402 void cmMakefile::EnableLanguage(const char* lang
)
1404 m_MakefileGenerator
->EnableLanguage(lang
);
1407 void cmMakefile::ExpandSourceListArguments(
1408 std::vector
<std::string
> const& arguments
,
1409 std::vector
<std::string
>& newargs
, unsigned int start
)
1411 // first figure out if we need to handle version 1.2 style source lists
1413 const char* versionValue
1414 = this->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
1415 if (versionValue
&& atof(versionValue
) > 1.2)
1420 // now expand the args
1421 std::vector
<std::string
> tmpArgs
;
1423 for(i
= 0; i
< arguments
.size(); ++i
)
1425 // is the arg defined ?, if so use the def
1426 const char *def
= this->GetDefinition(arguments
[i
].c_str());
1427 if (def
&& oldVersion
&& i
>= start
)
1429 tmpArgs
.push_back(def
);
1433 tmpArgs
.push_back(arguments
[i
]);
1436 cmSystemTools::ExpandListArguments(tmpArgs
, newargs
);