cmMakefile.cxx 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. /*=========================================================================
  2. Program: Insight Segmentation & Registration Toolkit
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2001 Insight Consortium
  8. All rights reserved.
  9. Redistribution and use in source and binary forms, with or without
  10. modification, are permitted provided that the following conditions are met:
  11. * Redistributions of source code must retain the above copyright notice,
  12. this list of conditions and the following disclaimer.
  13. * Redistributions in binary form must reproduce the above copyright notice,
  14. this list of conditions and the following disclaimer in the documentation
  15. and/or other materials provided with the distribution.
  16. * The name of the Insight Consortium, nor the names of any consortium members,
  17. nor of any contributors, may be used to endorse or promote products derived
  18. from this software without specific prior written permission.
  19. * Modified source versions must be plainly marked as such, and must not be
  20. misrepresented as being the original software.
  21. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
  22. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
  25. ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  27. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  28. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  29. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. =========================================================================*/
  32. #include "cmMakefile.h"
  33. #include "cmCommand.h"
  34. #include "cmStandardIncludes.h"
  35. #include "cmSourceFile.h"
  36. #include "cmDirectory.h"
  37. #include "cmSystemTools.h"
  38. #include "cmMakefileGenerator.h"
  39. #include "cmCommands.h"
  40. #include "cmCacheManager.h"
  41. #include "cmFunctionBlocker.h"
  42. // default is not to be building executables
  43. cmMakefile::cmMakefile()
  44. {
  45. // Setup the default include file regular expression.
  46. // Should be changed to something like "\\.(h|hh|hpp|hxx)$" or "^.*$"
  47. m_IncludeFileRegularExpression = "^itk|^vtk|^vnl|^vcl|^f2c";
  48. m_DefineFlags = " ";
  49. m_MakefileGenerator = 0;
  50. this->AddSourceGroup("", "^.*$");
  51. this->AddSourceGroup("Source Files", "\\.(cpp|C|c|cxx|rc|def|r|odl|idl|hpj|bat)$");
  52. this->AddSourceGroup("Header Files", "\\.(h|hh|hpp|hxx|hm|inl)$");
  53. this->AddDefaultCommands();
  54. this->AddDefaultDefinitions();
  55. cmCacheManager::GetInstance()->DefineCache(this);
  56. #if defined(_WIN32) && !defined(__CYGWIN__)
  57. const char* cacheValue
  58. = cmCacheManager::GetInstance()->GetCacheValue("CMAKE_ROOT");
  59. std::string fpath = cacheValue;
  60. fpath += "/Templates/CMakeWindowsSystemConfig.cmake";
  61. this->ReadListFile(NULL,fpath.c_str());
  62. #endif
  63. }
  64. void cmMakefile::AddDefaultCommands()
  65. {
  66. std::list<cmCommand*> commands;
  67. GetPredefinedCommands(commands);
  68. for(std::list<cmCommand*>::iterator i = commands.begin();
  69. i != commands.end(); ++i)
  70. {
  71. this->AddCommand(*i);
  72. }
  73. #if defined(_WIN32) || defined(__CYGWIN__)
  74. this->AddDefinition("WIN32", "1");
  75. #else
  76. this->AddDefinition("UNIX", "1");
  77. #endif
  78. // Cygwin is more like unix so enable the unix commands
  79. #if defined(__CYGWIN__)
  80. this->AddDefinition("UNIX", "1");
  81. #endif
  82. }
  83. cmMakefile::~cmMakefile()
  84. {
  85. for(unsigned int i=0; i < m_UsedCommands.size(); i++)
  86. {
  87. delete m_UsedCommands[i];
  88. }
  89. for(RegisteredCommandsMap::iterator j = m_Commands.begin();
  90. j != m_Commands.end(); ++j)
  91. {
  92. delete (*j).second;
  93. }
  94. for(DataMap::const_iterator d = m_DataMap.begin();
  95. d != m_DataMap.end(); ++d)
  96. {
  97. if(d->second)
  98. {
  99. delete d->second;
  100. }
  101. }
  102. delete m_MakefileGenerator;
  103. }
  104. void cmMakefile::PrintStringVector(const char* s, const std::vector<std::string>& v) const
  105. {
  106. std::cout << s << ": ( \n";
  107. for(std::vector<std::string>::const_iterator i = v.begin();
  108. i != v.end(); ++i)
  109. {
  110. std::cout << (*i).c_str() << " ";
  111. }
  112. std::cout << " )\n";
  113. }
  114. // call print on all the classes in the makefile
  115. void cmMakefile::Print() const
  116. {
  117. // print the class lists
  118. std::cout << "classes:\n";
  119. for(SourceMap::const_iterator l = m_Sources.begin();
  120. l != m_Sources.end(); l++)
  121. {
  122. std::cout << " Class list named: " << l->first << std::endl;
  123. for(std::vector<cmSourceFile>::const_iterator i = l->second.begin();
  124. i != l->second.end(); i++)
  125. {
  126. i->Print();
  127. }
  128. }
  129. std::cout << " m_Targets: ";
  130. for (cmTargets::const_iterator l = m_Targets.begin();
  131. l != m_Targets.end(); l++)
  132. {
  133. std::cout << l->first << std::endl;
  134. }
  135. std::cout << " m_CurrentOutputDirectory; " <<
  136. m_CurrentOutputDirectory.c_str() << std::endl;
  137. std::cout << " m_StartOutputDirectory; " <<
  138. m_StartOutputDirectory.c_str() << std::endl;
  139. std::cout << " m_HomeOutputDirectory; " <<
  140. m_HomeOutputDirectory.c_str() << std::endl;
  141. std::cout << " m_cmCurrentDirectory; " <<
  142. m_cmCurrentDirectory.c_str() << std::endl;
  143. std::cout << " m_cmStartDirectory; " <<
  144. m_cmStartDirectory.c_str() << std::endl;
  145. std::cout << " m_cmHomeDirectory; " <<
  146. m_cmHomeDirectory.c_str() << std::endl;
  147. std::cout << " m_ProjectName; " << m_ProjectName.c_str() << std::endl;
  148. this->PrintStringVector("m_SubDirectories ", m_SubDirectories);
  149. this->PrintStringVector("m_MakeVerbatim ", m_MakeVerbatim);
  150. this->PrintStringVector("m_IncludeDirectories;", m_IncludeDirectories);
  151. this->PrintStringVector("m_LinkDirectories", m_LinkDirectories);
  152. this->PrintStringVector("m_Utilities", m_Utilities);
  153. this->PrintStringVector("m_UtilityDirectories", m_UtilityDirectories);
  154. for( std::vector<cmSourceGroup>::const_iterator i = m_SourceGroups.begin();
  155. i != m_SourceGroups.end(); ++i)
  156. {
  157. i->Print();
  158. }
  159. }
  160. // Parse the given CMakeLists.txt file into a list of classes.
  161. // Reads in current CMakeLists file and all parent CMakeLists files
  162. // executing all inherited commands in the parents
  163. //
  164. // if external is non-zero, this means that we have branched to grab some
  165. // commands from a remote list-file (that is, the equivalent of a
  166. // #include has been called). We DO NOT look at the parents of this
  167. // list-file, and for all other purposes, the name of this list-file
  168. // is "filename" and not "external".
  169. bool cmMakefile::ReadListFile(const char* filename, const char* external)
  170. {
  171. // keep track of the current file being read
  172. if (filename)
  173. {
  174. m_cmCurrentListFile= filename;
  175. }
  176. // if this is not a remote makefile
  177. // (if it were, this would be called from the "filename" call,
  178. // rather than the "external" call)
  179. if (!external)
  180. {
  181. // is there a parent CMakeLists file that does not go beyond the
  182. // Home directory? if so recurse and read in that List file
  183. std::string parentList = this->GetParentListFileName(filename);
  184. if (parentList != "")
  185. {
  186. // save the current directory
  187. std::string srcdir = m_cmCurrentDirectory;
  188. std::string bindir = m_CurrentOutputDirectory;
  189. // compute the new current directories
  190. std::string::size_type pos = m_cmCurrentDirectory.rfind('/');
  191. if(pos != std::string::npos)
  192. {
  193. m_cmCurrentDirectory = m_cmCurrentDirectory.substr(0, pos);
  194. }
  195. pos = m_CurrentOutputDirectory.rfind('/');
  196. if(pos != std::string::npos)
  197. {
  198. m_CurrentOutputDirectory = m_CurrentOutputDirectory.substr(0, pos);
  199. }
  200. this->ReadListFile(parentList.c_str());
  201. // restore the current directory
  202. m_cmCurrentDirectory = srcdir;
  203. m_CurrentOutputDirectory = bindir;
  204. }
  205. }
  206. // are we at the start CMakeLists file or are we processing a parent
  207. // lists file
  208. //
  209. // this might, or might not be true, irrespective if we are
  210. // off looking at an external makefile.
  211. bool inheriting = (m_cmCurrentDirectory != m_cmStartDirectory);
  212. // Now read the input file
  213. const char *filenametoread= filename;
  214. if( external)
  215. {
  216. filenametoread= external;
  217. }
  218. std::ifstream fin(filenametoread);
  219. if(!fin)
  220. {
  221. cmSystemTools::Error("error can not open file ", filenametoread);
  222. return false;
  223. }
  224. std::string name;
  225. std::vector<std::string> arguments;
  226. while ( fin )
  227. {
  228. // add this list file to the list of dependencies
  229. m_ListFiles.push_back( filenametoread);
  230. if(cmSystemTools::ParseFunction(fin, name, arguments) &&
  231. !this->IsFunctionBlocked(name.c_str(),arguments))
  232. {
  233. RegisteredCommandsMap::iterator pos = m_Commands.find(name);
  234. if(pos != m_Commands.end())
  235. {
  236. cmCommand* rm = (*pos).second;
  237. cmCommand* usedCommand = rm->Clone();
  238. usedCommand->SetMakefile(this);
  239. bool keepCommand = false;
  240. if(usedCommand->GetEnabled())
  241. {
  242. // if not running in inherit mode or
  243. // if the command is inherited then Invoke it.
  244. if(!inheriting || usedCommand->IsInherited())
  245. {
  246. if(!usedCommand->Invoke(arguments))
  247. {
  248. cmSystemTools::Error(usedCommand->GetName(),
  249. ": Error : \n",
  250. usedCommand->GetError(),
  251. m_cmCurrentDirectory.c_str());
  252. }
  253. else
  254. {
  255. // use the command
  256. keepCommand = true;
  257. m_UsedCommands.push_back(usedCommand);
  258. }
  259. }
  260. }
  261. // if the Cloned command was not used
  262. // then delete it
  263. if(!keepCommand)
  264. {
  265. delete usedCommand;
  266. }
  267. }
  268. else
  269. {
  270. cmSystemTools::Error("unknown CMake command ", name.c_str(), filename);
  271. }
  272. }
  273. }
  274. // send scope ended to and funciton blockers
  275. if (filename)
  276. {
  277. // loop over all function blockers to see if any block this command
  278. std::set<cmFunctionBlocker *>::const_iterator pos;
  279. for (pos = m_FunctionBlockers.begin();
  280. pos != m_FunctionBlockers.end(); ++pos)
  281. {
  282. (*pos)->ScopeEnded(*this);
  283. }
  284. }
  285. return true;
  286. }
  287. cmSourceFile *cmMakefile::GetSource(const char *srclist, const char *cname)
  288. {
  289. SourceMap::iterator sl = m_Sources.find(srclist);
  290. // find the src list
  291. if (sl == m_Sources.end())
  292. {
  293. return 0;
  294. }
  295. // find the class
  296. for (std::vector<cmSourceFile>::iterator i = sl->second.begin();
  297. i != sl->second.end(); ++i)
  298. {
  299. if (i->GetSourceName() == cname)
  300. {
  301. return &(*i);
  302. }
  303. }
  304. return 0;
  305. }
  306. void cmMakefile::AddCommand(cmCommand* wg)
  307. {
  308. std::string name = wg->GetName();
  309. m_Commands.insert( RegisteredCommandsMap::value_type(name, wg));
  310. }
  311. // Set the make file
  312. void cmMakefile::SetMakefileGenerator(cmMakefileGenerator* mf)
  313. {
  314. delete m_MakefileGenerator;
  315. m_MakefileGenerator = mf;
  316. }
  317. // Generate the output file
  318. void cmMakefile::GenerateMakefile()
  319. {
  320. // do all the variable expansions here
  321. this->ExpandVariables();
  322. // set the makefile on the generator
  323. m_MakefileGenerator->SetMakefile(this);
  324. // give all the commands a chance to do something
  325. // after the file has been parsed before generation
  326. for(std::vector<cmCommand*>::iterator i = m_UsedCommands.begin();
  327. i != m_UsedCommands.end(); ++i)
  328. {
  329. (*i)->FinalPass();
  330. }
  331. // merge libraries
  332. for (cmTargets::iterator l = m_Targets.begin();
  333. l != m_Targets.end(); l++)
  334. {
  335. l->second.GenerateSourceFilesFromSourceLists(*this);
  336. l->second.MergeLibraries(m_LinkLibraries);
  337. }
  338. // now do the generation
  339. m_MakefileGenerator->GenerateMakefile();
  340. }
  341. void cmMakefile::AddSource(cmSourceFile& cmfile, const char *srclist)
  342. {
  343. m_Sources[srclist].push_back(cmfile);
  344. }
  345. void cmMakefile::AddCustomCommand(const char* source,
  346. const char* command,
  347. const std::vector<std::string>& depends,
  348. const std::vector<std::string>& outputs,
  349. const char *target)
  350. {
  351. // find the target,
  352. if (m_Targets.find(target) != m_Targets.end())
  353. {
  354. cmCustomCommand cc(source,command,depends,outputs);
  355. m_Targets[target].GetCustomCommands().push_back(cc);
  356. }
  357. }
  358. void cmMakefile::AddCustomCommand(const char* source,
  359. const char* command,
  360. const std::vector<std::string>& depends,
  361. const char* output,
  362. const char *target)
  363. {
  364. std::vector<std::string> outputs;
  365. outputs.push_back(output);
  366. this->AddCustomCommand(source, command, depends, outputs, target);
  367. }
  368. void cmMakefile::AddDefineFlag(const char* flag)
  369. {
  370. m_DefineFlags += " ";
  371. m_DefineFlags += flag;
  372. }
  373. void cmMakefile::AddUtility(const char* util)
  374. {
  375. m_Utilities.push_back(util);
  376. }
  377. void cmMakefile::AddUtilityDirectory(const char* dir)
  378. {
  379. m_UtilityDirectories.push_back(dir);
  380. }
  381. void cmMakefile::AddLinkLibrary(const char* lib, cmTarget::LinkLibraryType llt)
  382. {
  383. m_LinkLibraries.push_back(
  384. std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt));
  385. }
  386. void cmMakefile::AddLinkLibraryForTarget(const char *target,
  387. const char* lib,
  388. cmTarget::LinkLibraryType llt)
  389. {
  390. if (m_Targets.find(target) != m_Targets.end())
  391. {
  392. m_Targets[target].GetLinkLibraries().
  393. push_back(
  394. std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt));
  395. }
  396. }
  397. void cmMakefile::AddLinkLibrary(const char* lib)
  398. {
  399. this->AddLinkLibrary(lib,cmTarget::GENERAL);
  400. }
  401. void cmMakefile::AddLinkDirectory(const char* dir)
  402. {
  403. m_LinkDirectories.push_back(dir);
  404. }
  405. void cmMakefile::AddSubDirectory(const char* sub)
  406. {
  407. m_SubDirectories.push_back(sub);
  408. }
  409. void cmMakefile::AddIncludeDirectory(const char* inc)
  410. {
  411. m_IncludeDirectories.push_back(inc);
  412. }
  413. void cmMakefile::AddDefinition(const char* name, const char* value)
  414. {
  415. m_Definitions.erase( DefinitionMap::key_type(name));
  416. m_Definitions.insert(DefinitionMap::value_type(name, value));
  417. }
  418. void cmMakefile::AddDefinition(const char* name, bool value)
  419. {
  420. if(value)
  421. {
  422. m_Definitions.erase( DefinitionMap::key_type(name));
  423. m_Definitions.insert(DefinitionMap::value_type(name, "ON"));
  424. }
  425. else
  426. {
  427. m_Definitions.erase( DefinitionMap::key_type(name));
  428. m_Definitions.insert(DefinitionMap::value_type(name, "OFF"));
  429. }
  430. }
  431. void cmMakefile::SetProjectName(const char* p)
  432. {
  433. m_ProjectName = p;
  434. }
  435. void cmMakefile::AddLibrary(const char* lname, const std::vector<std::string> &srcs)
  436. {
  437. cmTarget target;
  438. target.SetType(cmTarget::LIBRARY);
  439. target.SetInAll(true);
  440. target.GetSourceLists() = srcs;
  441. m_Targets.insert(cmTargets::value_type(lname,target));
  442. // Add an entry into the cache
  443. cmCacheManager::GetInstance()->
  444. AddCacheEntry(lname,
  445. this->GetCurrentOutputDirectory(),
  446. "Path to a library", cmCacheManager::INTERNAL);
  447. }
  448. void cmMakefile::AddExecutable(const char *exeName,
  449. const std::vector<std::string> &srcs)
  450. {
  451. this->AddExecutable(exeName,srcs,false);
  452. }
  453. void cmMakefile::AddExecutable(const char *exeName,
  454. const std::vector<std::string> &srcs,
  455. bool win32)
  456. {
  457. cmTarget target;
  458. if (win32)
  459. {
  460. target.SetType(cmTarget::WIN32_EXECUTABLE);
  461. }
  462. else
  463. {
  464. target.SetType(cmTarget::EXECUTABLE);
  465. }
  466. target.SetInAll(true);
  467. target.GetSourceLists() = srcs;
  468. m_Targets.insert(cmTargets::value_type(exeName,target));
  469. // Add an entry into the cache
  470. cmCacheManager::GetInstance()->
  471. AddCacheEntry(exeName,
  472. this->GetCurrentOutputDirectory(),
  473. "Path to an executable", cmCacheManager::INTERNAL);
  474. }
  475. void cmMakefile::AddUtilityCommand(const char* utilityName,
  476. const char* command,
  477. bool all)
  478. {
  479. std::vector<std::string> empty;
  480. this->AddUtilityCommand(utilityName,command,all,
  481. empty,empty);
  482. }
  483. void cmMakefile::AddUtilityCommand(const char* utilityName,
  484. const char* command,
  485. bool all,
  486. const std::vector<std::string> &dep,
  487. const std::vector<std::string> &out)
  488. {
  489. cmTarget target;
  490. target.SetType(cmTarget::UTILITY);
  491. target.SetInAll(all);
  492. cmCustomCommand cc(utilityName, command, dep, out);
  493. target.GetCustomCommands().push_back(cc);
  494. m_Targets.insert(cmTargets::value_type(utilityName,target));
  495. }
  496. void cmMakefile::AddSourceGroup(const char* name, const char* regex)
  497. {
  498. // First see if the group exists. If so, replace its regular expression.
  499. for(std::vector<cmSourceGroup>::iterator sg = m_SourceGroups.begin();
  500. sg != m_SourceGroups.end(); ++sg)
  501. {
  502. std::string sgName = sg->GetName();
  503. if(sgName == name)
  504. {
  505. // We only want to set the regular expression. If there are already
  506. // source files in the group, we don't want to remove them.
  507. sg->SetGroupRegex(regex);
  508. return;
  509. }
  510. }
  511. // The group doesn't exist. Add it.
  512. m_SourceGroups.push_back(cmSourceGroup(name, regex));
  513. }
  514. void cmMakefile::AddExtraDirectory(const char* dir)
  515. {
  516. m_AuxSourceDirectories.push_back(dir);
  517. }
  518. // return the file name for the parent CMakeLists file to the
  519. // one passed in. Zero is returned if the CMakeLists file is the
  520. // one in the home directory or if for some reason a parent cmake lists
  521. // file cannot be found.
  522. std::string cmMakefile::GetParentListFileName(const char *currentFileName)
  523. {
  524. // extract the directory name
  525. std::string parentFile;
  526. std::string listsDir = currentFileName;
  527. std::string::size_type pos = listsDir.rfind('/');
  528. // if we could not find the directory return 0
  529. if(pos == std::string::npos)
  530. {
  531. return parentFile;
  532. }
  533. listsDir = listsDir.substr(0, pos);
  534. // if we are in the home directory then stop, return 0
  535. if(m_cmHomeDirectory == listsDir)
  536. {
  537. return parentFile;
  538. }
  539. // is there a parent directory we can check
  540. pos = listsDir.rfind('/');
  541. // if we could not find the directory return 0
  542. if(pos == std::string::npos)
  543. {
  544. return parentFile;
  545. }
  546. listsDir = listsDir.substr(0, pos);
  547. // is there a CMakeLists.txt file in the parent directory ?
  548. parentFile = listsDir;
  549. parentFile += "/CMakeLists.txt";
  550. if(!cmSystemTools::FileExists(parentFile.c_str()))
  551. {
  552. parentFile = "";
  553. return parentFile;
  554. }
  555. return parentFile;
  556. }
  557. // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
  558. // include and library directories.
  559. void cmMakefile::ExpandVariables()
  560. {
  561. // Now expand varibles in the include and link strings
  562. std::vector<std::string>::iterator j, begin, end;
  563. begin = m_IncludeDirectories.begin();
  564. end = m_IncludeDirectories.end();
  565. for(j = begin; j != end; ++j)
  566. {
  567. this->ExpandVariablesInString(*j);
  568. }
  569. begin = m_LinkDirectories.begin();
  570. end = m_LinkDirectories.end();
  571. for(j = begin; j != end; ++j)
  572. {
  573. this->ExpandVariablesInString(*j);
  574. }
  575. cmTarget::LinkLibraries::iterator j2, end2;
  576. j2 = m_LinkLibraries.begin();
  577. end2 = m_LinkLibraries.end();
  578. for(; j2 != end2; ++j2)
  579. {
  580. this->ExpandVariablesInString(j2->first);
  581. }
  582. }
  583. const char* cmMakefile::GetDefinition(const char* name)
  584. {
  585. DefinitionMap::iterator pos = m_Definitions.find(name);
  586. if(pos != m_Definitions.end())
  587. {
  588. return (*pos).second.c_str();
  589. }
  590. return 0;
  591. }
  592. int cmMakefile::DumpDocumentationToFile(const char *fileName)
  593. {
  594. // Open the supplied filename
  595. std::ofstream f;
  596. f.open(fileName, std::ios::out);
  597. if ( f.fail() )
  598. {
  599. return 0;
  600. }
  601. // Loop over all registered commands and print out documentation
  602. const char *name;
  603. const char *terse;
  604. const char *full;
  605. for(RegisteredCommandsMap::iterator j = m_Commands.begin();
  606. j != m_Commands.end(); ++j)
  607. {
  608. name = (*j).second->GetName();
  609. terse = (*j).second->GetTerseDocumentation();
  610. full = (*j).second->GetFullDocumentation();
  611. f << name << " - " << terse << std::endl
  612. << "Usage: " << full << std::endl << std::endl;
  613. }
  614. return 1;
  615. }
  616. void cmMakefile::ExpandVariablesInString(std::string& source) const
  617. {
  618. for(DefinitionMap::const_iterator i = m_Definitions.begin();
  619. i != m_Definitions.end(); ++i)
  620. {
  621. std::string variable = "${";
  622. variable += (*i).first;
  623. variable += "}";
  624. cmSystemTools::ReplaceString(source, variable.c_str(),
  625. (*i).second.c_str());
  626. variable = "@";
  627. variable += (*i).first;
  628. variable += "@";
  629. cmSystemTools::ReplaceString(source, variable.c_str(),
  630. (*i).second.c_str());
  631. }
  632. }
  633. void cmMakefile::RemoveVariablesInString(std::string& source) const
  634. {
  635. cmRegularExpression var("(\\${[A-Za-z_0-9]*})");
  636. cmRegularExpression var2("(@[A-Za-z_0-9]*@)");
  637. while (var.find(source))
  638. {
  639. source.erase(var.start(),var.end() - var.start());
  640. }
  641. while (var2.find(source))
  642. {
  643. source.erase(var2.start(),var2.end() - var2.start());
  644. }
  645. }
  646. // recursive function to create a vector of cmMakefile objects
  647. // This is done by reading the sub directory CMakeLists.txt files,
  648. // then calling this function with the new cmMakefile object
  649. void
  650. cmMakefile::FindSubDirectoryCMakeListsFiles(std::vector<cmMakefile*>&
  651. makefiles)
  652. {
  653. // loop over all the sub directories of this makefile
  654. const std::vector<std::string>& subdirs = this->GetSubDirectories();
  655. for(std::vector<std::string>::const_iterator i = subdirs.begin();
  656. i != subdirs.end(); ++i)
  657. {
  658. std::string subdir = *i;
  659. // Create a path to the list file in the sub directory
  660. std::string listFile = this->GetCurrentDirectory();
  661. listFile += "/";
  662. listFile += subdir;
  663. listFile += "/CMakeLists.txt";
  664. // if there is a CMakeLists.txt file read it
  665. if(!cmSystemTools::FileExists(listFile.c_str()))
  666. {
  667. cmSystemTools::Error("CMakeLists.txt file missing from sub directory:",
  668. listFile.c_str());
  669. }
  670. else
  671. {
  672. cmMakefile* mf = new cmMakefile;
  673. makefiles.push_back(mf);
  674. // initialize new makefile
  675. mf->SetHomeOutputDirectory(this->GetHomeOutputDirectory());
  676. mf->SetHomeDirectory(this->GetHomeDirectory());
  677. // add the subdir to the start output directory
  678. std::string outdir = this->GetStartOutputDirectory();
  679. outdir += "/";
  680. outdir += subdir;
  681. mf->SetStartOutputDirectory(outdir.c_str());
  682. // add the subdir to the start source directory
  683. std::string currentDir = this->GetStartDirectory();
  684. currentDir += "/";
  685. currentDir += subdir;
  686. mf->SetStartDirectory(currentDir.c_str());
  687. // Parse the CMakeLists.txt file
  688. currentDir += "/CMakeLists.txt";
  689. mf->MakeStartDirectoriesCurrent();
  690. mf->ReadListFile(currentDir.c_str());
  691. // recurse into nextDir
  692. mf->FindSubDirectoryCMakeListsFiles(makefiles);
  693. }
  694. }
  695. }
  696. /**
  697. * Add the default definitions to the makefile. These values must not
  698. * be dependent on anything that isn't known when this cmMakefile instance
  699. * is constructed.
  700. */
  701. void cmMakefile::AddDefaultDefinitions()
  702. {
  703. #if defined(_WIN32) && !defined(__CYGWIN__)
  704. this->AddDefinition("CMAKE_CFG_OUTDIR","$(OUTDIR)");
  705. #else
  706. this->AddDefinition("CMAKE_CFG_OUTDIR",".");
  707. #endif
  708. }
  709. /**
  710. * Find a source group whose regular expression matches the filename
  711. * part of the given source name. Search backward through the list of
  712. * source groups, and take the first matching group found. This way
  713. * non-inherited SOURCE_GROUP commands will have precedence over
  714. * inherited ones.
  715. */
  716. cmSourceGroup&
  717. cmMakefile::FindSourceGroup(const char* source,
  718. std::vector<cmSourceGroup> &groups)
  719. {
  720. std::string file = source;
  721. std::string::size_type pos = file.rfind('/');
  722. if(pos != std::string::npos)
  723. {
  724. file = file.substr(pos, file.length()-pos);
  725. }
  726. for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
  727. sg != groups.rend(); ++sg)
  728. {
  729. if(sg->Matches(file.c_str()))
  730. {
  731. return *sg;
  732. }
  733. }
  734. // Shouldn't get here, but just in case, return the default group.
  735. return groups.front();
  736. }
  737. bool cmMakefile::IsFunctionBlocked(const char *name,
  738. std::vector<std::string> &args) const
  739. {
  740. // loop over all function blockers to see if any block this command
  741. std::set<cmFunctionBlocker *>::const_iterator pos;
  742. for (pos = m_FunctionBlockers.begin();
  743. pos != m_FunctionBlockers.end(); ++pos)
  744. {
  745. if ((*pos)->IsFunctionBlocked(name, args, *this))
  746. {
  747. return true;
  748. }
  749. }
  750. return false;
  751. }
  752. void cmMakefile::RemoveFunctionBlocker(const char *name,
  753. const std::vector<std::string> &args)
  754. {
  755. // loop over all function blockers to see if any block this command
  756. std::set<cmFunctionBlocker *>::const_iterator pos;
  757. for (pos = m_FunctionBlockers.begin();
  758. pos != m_FunctionBlockers.end(); ++pos)
  759. {
  760. if ((*pos)->ShouldRemove(name, args, *this))
  761. {
  762. m_FunctionBlockers.erase(*pos);
  763. return;
  764. }
  765. }
  766. return;
  767. }
  768. void cmMakefile::SetHomeDirectory(const char* dir)
  769. {
  770. m_cmHomeDirectory = dir;
  771. cmSystemTools::ConvertToUnixSlashes(m_cmHomeDirectory);
  772. this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
  773. }
  774. void cmMakefile::SetHomeOutputDirectory(const char* lib)
  775. {
  776. m_HomeOutputDirectory = lib;
  777. cmSystemTools::ConvertToUnixSlashes(m_HomeOutputDirectory);
  778. this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
  779. #if !defined(_WIN32) || defined(__CYGWIN__)
  780. std::string fpath = lib;
  781. fpath += "/CMakeSystemConfig.cmake";
  782. this->ReadListFile(NULL,fpath.c_str());
  783. #endif
  784. }
  785. /**
  786. * Register the given cmData instance with its own name.
  787. */
  788. void cmMakefile::RegisterData(cmData* data)
  789. {
  790. std::string name = data->GetName();
  791. DataMap::const_iterator d = m_DataMap.find(name);
  792. if((d != m_DataMap.end()) && (d->second != NULL) && (d->second != data))
  793. {
  794. delete d->second;
  795. }
  796. m_DataMap[name] = data;
  797. }
  798. /**
  799. * Register the given cmData instance with the given name. This can be used
  800. * to register a NULL pointer.
  801. */
  802. void cmMakefile::RegisterData(const char* name, cmData* data)
  803. {
  804. DataMap::const_iterator d = m_DataMap.find(name);
  805. if((d != m_DataMap.end()) && (d->second != NULL) && (d->second != data))
  806. {
  807. delete d->second;
  808. }
  809. m_DataMap[name] = data;
  810. }
  811. /**
  812. * Lookup a cmData instance previously registered with the given name. If
  813. * the instance cannot be found, return NULL.
  814. */
  815. cmData* cmMakefile::LookupData(const char* name) const
  816. {
  817. DataMap::const_iterator d = m_DataMap.find(name);
  818. if(d != m_DataMap.end())
  819. {
  820. return d->second;
  821. }
  822. else
  823. {
  824. return NULL;
  825. }
  826. }