FIX: stupid pb fixed (close to being medieval'ed by The Ken)
[cmake.git] / Source / cmMakefile.cxx
blob9f1e0e40d32e0d3b1150cd31ce1950ed60d948c0
1 /*=========================================================================
3 Program: Insight Segmentation & Registration Toolkit
4 Module: $RCSfile: cmMakefile.cxx,v $
5 Language: C++
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" );
49 m_DefineFlags = " ";
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"))
63 return 0;
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"))
74 return 0;
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)
88 this->AddCommand(*i);
90 #if defined(_WIN32) || defined(__CYGWIN__)
91 this->AddDefinition("WIN32", "1");
92 #else
93 this->AddDefinition("UNIX", "1");
94 #endif
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");
99 #endif
100 #if defined(__APPLE__)
101 this->AddDefinition("APPLE", "1");
102 #endif
105 cmMakefile::~cmMakefile()
107 for(std::vector<cmSourceFile*>::iterator i = m_SourceFiles.begin();
108 i != m_SourceFiles.end(); ++i)
110 delete *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)
119 delete (*j).second;
121 for(DataMap::const_iterator d = m_DataMap.begin();
122 d != m_DataMap.end(); ++d)
124 if(d->second)
126 delete d->second;
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);
135 delete b;
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();
144 i != v.end(); ++i)
146 std::cout << (*i).c_str() << " ";
148 std::cout << " )\n";
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)
184 i->Print();
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))
199 return;
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))
229 std::string error;
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());
237 else
239 // use the command
240 keepCommand = true;
241 m_UsedCommands.push_back(usedCommand);
245 // if the Cloned command was not used
246 // then delete it
247 if(!keepCommand)
249 delete usedCommand;
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.");
259 else
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
283 if (filename)
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)
301 if (!external)
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
331 // lists file
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;
340 if( external)
342 filenametoread= external;
345 cmListFile* lf =
346 cmListFileCache::GetInstance()->GetFileCache(filenametoread);
347 if(!lf)
349 return false;
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
362 if (filename)
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);
378 return true;
382 void cmMakefile::AddCommand(cmCommand* wg)
384 std::string name = wg->GetName();
385 m_Commands.insert( RegisteredCommandsMap::value_type(name, wg));
388 // Set the make file
389 void cmMakefile::SetMakefileGenerator(cmMakefileGenerator* mf)
391 if(mf == m_MakefileGenerator)
393 return;
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)
410 (*i)->FinalPass();
415 // Generate the output file
416 void cmMakefile::GenerateMakefile()
418 this->FinalPass();
419 const char* versionValue
420 = this->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
421 bool oldVersion = (!versionValue || atof(versionValue) < 1.4);
422 // merge libraries
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
429 if(oldVersion)
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,
441 const char* command,
442 const std::vector<std::string>& commandArgs,
443 const std::vector<std::string>& depends,
444 const std::vector<std::string>& outputs,
445 const char *target)
447 // find the target,
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;
455 unsigned int i;
457 for (i = 0; i < commandArgs.size(); ++i)
459 combinedArgs += cmSystemTools::EscapeSpaces(commandArgs[i].c_str());
460 combinedArgs += " ";
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,
476 const char* command,
477 const std::vector<std::string>& commandArgs,
478 const std::vector<std::string>& depends,
479 const char* output,
480 const char *target)
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,
501 const char* lib,
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 );
509 else
511 cmSystemTools::Error("Attempt to add link libraries to non-existant target: ", target, " for lib ", lib);
515 void cmMakefile::AddLinkDirectoryForTarget(const char *target,
516 const char* d)
518 cmTargets::iterator i = m_Targets.find(target);
519 if ( i != m_Targets.end())
521 i->second.AddLinkDirectory( d );
523 else
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);
553 else
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())
577 if (before)
579 // WARNING: this *is* expensive (linear time) since it's a vector
580 m_IncludeDirectories.insert(m_IncludeDirectories.begin(), inc);
582 else
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,
598 const char* doc,
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)
608 if(value)
610 m_Definitions.erase( DefinitionMap::key_type(name));
611 m_Definitions.insert(DefinitionMap::value_type(name, "ON"));
613 else
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)
629 m_ProjectName = 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;
641 default:;
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)
656 cmTarget target;
657 switch (shared)
659 case 0:
660 target.SetType(cmTarget::STATIC_LIBRARY);
661 break;
662 case 1:
663 target.SetType(cmTarget::SHARED_LIBRARY);
664 break;
665 case 2:
666 target.SetType(cmTarget::MODULE_LIBRARY);
667 break;
668 default:
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
673 // hence useless.
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";
697 switch (shared)
699 case 0:
700 cmCacheManager::GetInstance()->
701 AddCacheEntry(ltname.c_str(),
702 "STATIC",
703 "Whether a library is static, shared or module.",
704 cmCacheManager::INTERNAL);
705 break;
706 case 1:
707 cmCacheManager::GetInstance()->
708 AddCacheEntry(ltname.c_str(),
709 "SHARED",
710 "Whether a library is static, shared or module.",
711 cmCacheManager::INTERNAL);
712 break;
713 case 2:
714 cmCacheManager::GetInstance()->
715 AddCacheEntry(ltname.c_str(),
716 "MODULE",
717 "Whether a library is static, shared or module.",
718 cmCacheManager::INTERNAL);
719 break;
720 default:
721 cmCacheManager::GetInstance()->
722 AddCacheEntry(ltname.c_str(),
723 "STATIC",
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,
738 bool win32)
740 cmTarget target;
741 if (win32)
743 target.SetType(cmTarget::WIN32_EXECUTABLE);
745 else
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,
766 const char* command,
767 const char* arguments,
768 bool all)
770 std::vector<std::string> empty;
771 this->AddUtilityCommand(utilityName,command,arguments,all,
772 empty,empty);
775 void cmMakefile::AddUtilityCommand(const char* utilityName,
776 const char* command,
777 const char* arguments,
778 bool all,
779 const std::vector<std::string> &dep,
780 const std::vector<std::string> &out)
782 cmTarget target;
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();
798 if(sgName == name)
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);
803 return;
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)
830 return parentFile;
832 listsDir = listsDir.substr(0, pos);
834 // if we are in the home directory then stop, return 0
835 if(m_cmHomeDirectory == listsDir)
837 return parentFile;
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)
845 return parentFile;
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
858 // directory is hit.
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";
872 return parentFile;
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
919 const char *name;
920 const char *terse;
921 const char *full;
922 char tmp[1024];
923 sprintf(tmp,"Version %d.%d", cmMakefile::GetMajorVersion(),
924 cmMakefile::GetMinorVersion());
925 f << "<html>\n";
926 f << "<h1>Documentation for commands of CMake " << tmp << "</h1>\n";
927 f << "<ul>\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";
938 return 1;
942 const char *cmMakefile::ExpandVariablesInString(std::string& source) const
944 return this->ExpandVariablesInString(source, false);
947 const char *cmMakefile::ExpandVariablesInString(std::string& source,
948 bool escapeQuotes,
949 bool atOnly) const
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;
958 if(atOnly)
960 markerPos = source.find_first_of("@");
962 else
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();
972 // current position
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] == '$')
985 // ${var} case
986 if(source[markerPos+1] == '{')
988 endVariableMarker = '}';
989 markerStartSize = 2;
991 // $ENV{var} case
992 else if(markerPos+4 < source.size() &&
993 source[markerPos+4] == '{' &&
994 !source.substr(markerPos+1, 3).compare("ENV"))
996 endVariableMarker = '}';
997 markerStartSize = 5;
999 else
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
1007 else
1009 // @VAR case
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 == '@')
1024 result += '@';
1026 else
1028 result += (markerStartSize == 5 ? "$ENV{" : "${");
1030 currentPos = markerPos;
1032 else
1034 // good variable remove it
1035 std::string var = source.substr(markerPos, endVariablePos - markerPos);
1036 bool found = false;
1037 if (markerStartSize == 5) // $ENV{
1039 char *ptr = getenv(var.c_str());
1040 if (ptr)
1042 if (escapeQuotes)
1044 result += cmSystemTools::EscapeQuotes(ptr);
1046 else
1048 result += ptr;
1050 found = true;
1053 else
1055 const char* lookup = this->GetDefinition(var.c_str());
1056 if(lookup)
1058 if (escapeQuotes)
1060 result += cmSystemTools::EscapeQuotes(lookup);
1062 else
1064 result += lookup;
1066 found = true;
1069 // if found add to result, if not, then it gets blanked
1070 if (!found)
1072 // if no definition is found then add the var back
1073 if(endVariableMarker == '@')
1075 result += "@";
1076 result += var;
1077 result += "@";
1079 // do nothing, we remove the variable
1080 /* else
1082 result += (markerStartSize == 5 ? "$ENV{" : "${");
1083 result += var;
1084 result += "}";
1088 // lookup var, and replace it
1089 currentPos = endVariablePos+1;
1092 if(atOnly)
1094 markerPos = source.find_first_of("@", currentPos);
1096 else
1098 markerPos = source.find_first_of("$@", currentPos);
1101 result += source.substr(currentPos); // pick up the rest of the string
1102 source = result;
1103 return source.c_str();
1106 void cmMakefile::RemoveVariablesInString(std::string& source,
1107 bool atOnly) const
1109 if(!atOnly)
1111 cmRegularExpression var("(\\${[A-Za-z_0-9]*})");
1112 while (var.find(source))
1114 source.erase(var.start(),var.end() - var.start());
1118 if(!atOnly)
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
1136 void
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();
1147 listFile += "/";
1148 listFile += subdir;
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:",
1154 listFile.c_str());
1156 else
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();
1166 outdir += "/";
1167 outdir += subdir;
1168 mf->SetStartOutputDirectory(outdir.c_str());
1169 // add the subdir to the start source directory
1170 std::string currentDir = this->GetStartDirectory();
1171 currentDir += "/";
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
1188 * is constructed.
1190 void cmMakefile::AddDefaultDefinitions()
1192 #if defined(_WIN32) && !defined(__CYGWIN__)
1193 this->AddDefinition("CMAKE_CFG_INTDIR","$(IntDir)");
1194 #else
1195 this->AddDefinition("CMAKE_CFG_INTDIR",".");
1196 #endif
1197 char temp[1024];
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
1209 * inherited ones.
1211 cmSourceGroup&
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()))
1227 return *sg;
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())
1241 return false;
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))
1265 return true;
1268 else
1270 if ((*pos)->IsFunctionBlocked(name, args, *this))
1272 return true;
1277 return false;
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);
1292 delete b;
1293 return;
1297 return;
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))
1324 delete d->second;
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))
1339 delete d->second;
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())
1354 return d->second;
1356 else
1358 return NULL;
1362 cmSourceFile* cmMakefile::GetSource(const char* sourceName) const
1364 std::string s = cmSystemTools::GetFilenameName(sourceName);
1365 std::string ext;
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())))
1379 return *i;
1383 return 0;
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())
1394 return ret;
1396 ret = new cmSourceFile(sf);
1397 m_SourceFiles.push_back(ret);
1398 return 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
1412 int oldVersion = 1;
1413 const char* versionValue
1414 = this->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
1415 if (versionValue && atof(versionValue) > 1.2)
1417 oldVersion = 0;
1420 // now expand the args
1421 std::vector<std::string> tmpArgs;
1422 unsigned int i;
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);
1431 else
1433 tmpArgs.push_back(arguments[i]);
1436 cmSystemTools::ExpandListArguments(tmpArgs, newargs);