cmMakefile.cxx 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmMakefile.h"
  14. #include "cmCommand.h"
  15. #include "cmStandardIncludes.h"
  16. #include "cmSourceFile.h"
  17. #include "cmDirectory.h"
  18. #include "cmSystemTools.h"
  19. #include "cmGlobalGenerator.h"
  20. #include "cmLocalGenerator.h"
  21. #include "cmCommands.h"
  22. #include "cmCacheManager.h"
  23. #include "cmFunctionBlocker.h"
  24. #include "cmListFileCache.h"
  25. #include "cmVariableWatch.h"
  26. #include "cmake.h"
  27. #include <stdio.h> // required for sprintf
  28. // default is not to be building executables
  29. cmMakefile::cmMakefile()
  30. {
  31. // Setup the default include file regular expression (match everything).
  32. m_IncludeFileRegularExpression = "^.*$";
  33. // Setup the default include complaint regular expression (match nothing).
  34. m_ComplainFileRegularExpression = "^$";
  35. // Source and header file extensions that we can handle
  36. m_SourceFileExtensions.push_back( "C" );
  37. m_SourceFileExtensions.push_back( "M" );
  38. m_SourceFileExtensions.push_back( "c" );
  39. m_SourceFileExtensions.push_back( "c++" );
  40. m_SourceFileExtensions.push_back( "cc" );
  41. m_SourceFileExtensions.push_back( "cpp" );
  42. m_SourceFileExtensions.push_back( "cxx" );
  43. m_SourceFileExtensions.push_back( "m" );
  44. m_SourceFileExtensions.push_back( "mm" );
  45. m_HeaderFileExtensions.push_back( "h" );
  46. m_HeaderFileExtensions.push_back( "h++" );
  47. m_HeaderFileExtensions.push_back( "hm" );
  48. m_HeaderFileExtensions.push_back( "hpp" );
  49. m_HeaderFileExtensions.push_back( "hxx" );
  50. m_HeaderFileExtensions.push_back( "in" );
  51. m_HeaderFileExtensions.push_back( "txx" );
  52. m_DefineFlags = " ";
  53. m_LocalGenerator = 0;
  54. this->AddSourceGroup("", "^.*$");
  55. this->AddSourceGroup("Source Files",
  56. "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat)$");
  57. this->AddSourceGroup("Header Files", "\\.(h|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
  58. this->AddDefaultDefinitions();
  59. }
  60. const char* cmMakefile::GetReleaseVersion()
  61. {
  62. #if CMake_VERSION_MINOR & 1
  63. return "development";
  64. #else
  65. return "patch " CMAKE_TO_STRING(CMake_VERSION_PATCH);
  66. #endif
  67. }
  68. unsigned int cmMakefile::GetCacheMajorVersion()
  69. {
  70. if(!this->GetCacheManager()->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"))
  71. {
  72. return 0;
  73. }
  74. return atoi(this->GetCacheManager()->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"));
  75. }
  76. unsigned int cmMakefile::GetCacheMinorVersion()
  77. {
  78. if(!this->GetCacheManager()->GetCacheValue("Cmake_Cache_MINOR_VERSION"))
  79. {
  80. return 0;
  81. }
  82. return atoi(this->GetCacheManager()->GetCacheValue("CMAKE_CACHE_MINOR_VERSION"));
  83. }
  84. cmMakefile::~cmMakefile()
  85. {
  86. for(std::vector<cmSourceFile*>::iterator i = m_SourceFiles.begin();
  87. i != m_SourceFiles.end(); ++i)
  88. {
  89. delete *i;
  90. }
  91. for(unsigned int i=0; i < m_UsedCommands.size(); i++)
  92. {
  93. delete m_UsedCommands[i];
  94. }
  95. for(DataMap::const_iterator d = m_DataMap.begin();
  96. d != m_DataMap.end(); ++d)
  97. {
  98. if(d->second)
  99. {
  100. delete d->second;
  101. }
  102. }
  103. std::list<cmFunctionBlocker *>::iterator pos;
  104. for (pos = m_FunctionBlockers.begin();
  105. pos != m_FunctionBlockers.end(); ++pos)
  106. {
  107. cmFunctionBlocker* b = *pos;
  108. delete b;
  109. }
  110. m_FunctionBlockers.clear();
  111. }
  112. void cmMakefile::PrintStringVector(const char* s, const std::vector<std::string>& v) const
  113. {
  114. std::cout << s << ": ( \n";
  115. for(std::vector<std::string>::const_iterator i = v.begin();
  116. i != v.end(); ++i)
  117. {
  118. std::cout << (*i).c_str() << " ";
  119. }
  120. std::cout << " )\n";
  121. }
  122. // call print on all the classes in the makefile
  123. void cmMakefile::Print() const
  124. {
  125. // print the class lists
  126. std::cout << "classes:\n";
  127. std::cout << " m_Targets: ";
  128. for (cmTargets::const_iterator l = m_Targets.begin();
  129. l != m_Targets.end(); l++)
  130. {
  131. std::cout << l->first << std::endl;
  132. }
  133. std::cout << " m_CurrentOutputDirectory; " <<
  134. m_CurrentOutputDirectory.c_str() << std::endl;
  135. std::cout << " m_StartOutputDirectory; " <<
  136. m_StartOutputDirectory.c_str() << std::endl;
  137. std::cout << " m_HomeOutputDirectory; " <<
  138. m_HomeOutputDirectory.c_str() << std::endl;
  139. std::cout << " m_cmCurrentDirectory; " <<
  140. m_cmCurrentDirectory.c_str() << std::endl;
  141. std::cout << " m_cmStartDirectory; " <<
  142. m_cmStartDirectory.c_str() << std::endl;
  143. std::cout << " m_cmHomeDirectory; " <<
  144. m_cmHomeDirectory.c_str() << std::endl;
  145. std::cout << " m_ProjectName; " << m_ProjectName.c_str() << std::endl;
  146. this->PrintStringVector("m_SubDirectories ", m_SubDirectories);
  147. this->PrintStringVector("m_IncludeDirectories;", m_IncludeDirectories);
  148. this->PrintStringVector("m_LinkDirectories", m_LinkDirectories);
  149. for( std::vector<cmSourceGroup>::const_iterator i = m_SourceGroups.begin();
  150. i != m_SourceGroups.end(); ++i)
  151. {
  152. i->Print();
  153. }
  154. }
  155. bool cmMakefile::CommandExists(const char* name) const
  156. {
  157. return this->GetCMakeInstance()->CommandExists(name);
  158. }
  159. bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff)
  160. {
  161. bool result = true;
  162. // quick return if blocked
  163. if(this->IsFunctionBlocked(lff))
  164. {
  165. // No error.
  166. return result;
  167. }
  168. std::string name = lff.m_Name;
  169. // execute the command
  170. cmCommand *rm =
  171. this->GetCMakeInstance()->GetCommand(name.c_str());
  172. if(rm)
  173. {
  174. cmCommand* usedCommand = rm->Clone();
  175. usedCommand->SetMakefile(this);
  176. bool keepCommand = false;
  177. if(usedCommand->GetEnabled() && !cmSystemTools::GetFatalErrorOccured())
  178. {
  179. // if not running in inherit mode or
  180. // if the command is inherited then InitialPass it.
  181. if(!m_Inheriting || usedCommand->IsInherited())
  182. {
  183. if(!usedCommand->InvokeInitialPass(lff.m_Arguments))
  184. {
  185. cmOStringStream error;
  186. error << "Error in cmake code at\n"
  187. << lff.m_FilePath << ":" << lff.m_Line << ":\n"
  188. << usedCommand->GetError();
  189. cmSystemTools::Error(error.str().c_str());
  190. result = false;
  191. }
  192. else
  193. {
  194. // use the command
  195. keepCommand = true;
  196. m_UsedCommands.push_back(usedCommand);
  197. }
  198. }
  199. }
  200. // if the Cloned command was not used
  201. // then delete it
  202. if(!keepCommand)
  203. {
  204. delete usedCommand;
  205. }
  206. }
  207. else
  208. {
  209. if(!cmSystemTools::GetFatalErrorOccured())
  210. {
  211. cmOStringStream error;
  212. error << "Error in cmake code at\n"
  213. << lff.m_FilePath << ":" << lff.m_Line << ":\n"
  214. << "Unknown CMake command \"" << lff.m_Name.c_str() << "\".";
  215. cmSystemTools::Error(error.str().c_str());
  216. result = false;
  217. }
  218. }
  219. return result;
  220. }
  221. // Parse the given CMakeLists.txt file into a list of classes.
  222. // Reads in current CMakeLists file and all parent CMakeLists files
  223. // executing all inherited commands in the parents
  224. //
  225. // if external is non-zero, this means that we have branched to grab some
  226. // commands from a remote list-file (that is, the equivalent of a
  227. // #include has been called). We DO NOT look at the parents of this
  228. // list-file, and for all other purposes, the name of this list-file
  229. // is "filename" and not "external".
  230. bool cmMakefile::ReadListFile(const char* filename_in, const char* external_in)
  231. {
  232. // used to watch for blockers going out of scope
  233. // e.g. mismatched IF statement
  234. std::set<cmFunctionBlocker *> originalBlockers;
  235. const char* external = 0;
  236. std::string external_abs;
  237. const char* filename = filename_in;
  238. std::string filename_abs;
  239. if (external_in)
  240. {
  241. external_abs =
  242. cmSystemTools::CollapseFullPath(external_in,
  243. m_cmCurrentDirectory.c_str());
  244. external = external_abs.c_str();
  245. if (filename_in)
  246. {
  247. filename_abs =
  248. cmSystemTools::CollapseFullPath(filename_in,
  249. m_cmCurrentDirectory.c_str());
  250. filename = filename_abs.c_str();
  251. }
  252. }
  253. // keep track of the current file being read
  254. if (filename)
  255. {
  256. if(m_cmCurrentListFile != filename)
  257. {
  258. m_cmCurrentListFile = filename;
  259. }
  260. // loop over current function blockers and record them
  261. std::list<cmFunctionBlocker *>::iterator pos;
  262. for (pos = m_FunctionBlockers.begin();
  263. pos != m_FunctionBlockers.end(); ++pos)
  264. {
  265. originalBlockers.insert(*pos);
  266. }
  267. }
  268. // if this is not a remote makefile
  269. // (if it were, this would be called from the "filename" call,
  270. // rather than the "external" call)
  271. if (!external)
  272. {
  273. // is there a parent CMakeLists file that does not go beyond the
  274. // Home directory? if so recurse and read in that List file
  275. std::string parentList = this->GetParentListFileName(filename);
  276. if (parentList != "")
  277. {
  278. std::string srcdir = m_cmCurrentDirectory;
  279. std::string bindir = m_CurrentOutputDirectory;
  280. std::string::size_type pos = parentList.rfind('/');
  281. m_cmCurrentDirectory = parentList.substr(0, pos);
  282. m_CurrentOutputDirectory = m_HomeOutputDirectory + parentList.substr(m_cmHomeDirectory.size(), pos - m_cmHomeDirectory.size());
  283. // if not found, oops
  284. if(pos == std::string::npos)
  285. {
  286. cmSystemTools::Error("Trailing slash not found");
  287. }
  288. this->ReadListFile(parentList.c_str());
  289. // restore the current directory
  290. m_cmCurrentDirectory = srcdir;
  291. m_CurrentOutputDirectory = bindir;
  292. }
  293. }
  294. // are we at the start CMakeLists file or are we processing a parent
  295. // lists file
  296. //
  297. // this might, or might not be true, irrespective if we are
  298. // off looking at an external makefile.
  299. m_Inheriting = (m_cmCurrentDirectory != m_cmStartDirectory);
  300. // Now read the input file
  301. const char *filenametoread= filename;
  302. if( external)
  303. {
  304. filenametoread= external;
  305. }
  306. // try to see if the list file is the top most
  307. // list file for a project, and if it is, then it
  308. // must have a project command. If there is not
  309. // one, then cmake will provide one via the
  310. // cmListFileCache class.
  311. bool requireProjectCommand = false;
  312. if(!external && m_cmCurrentDirectory == m_cmHomeDirectory)
  313. {
  314. if(cmSystemTools::LowerCase(
  315. cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt")
  316. {
  317. requireProjectCommand = true;
  318. }
  319. }
  320. cmListFile* lf =
  321. cmListFileCache::GetInstance()->GetFileCache(filenametoread,
  322. requireProjectCommand);
  323. if(!lf)
  324. {
  325. return false;
  326. }
  327. // add this list file to the list of dependencies
  328. m_ListFiles.push_back( filenametoread);
  329. const size_t numberFunctions = lf->m_Functions.size();
  330. for(size_t i =0; i < numberFunctions; ++i)
  331. {
  332. this->ExecuteCommand(lf->m_Functions[i]);
  333. }
  334. // send scope ended to and funciton blockers
  335. if (filename)
  336. {
  337. // loop over all function blockers to see if any block this command
  338. std::list<cmFunctionBlocker *>::iterator pos;
  339. for (pos = m_FunctionBlockers.begin();
  340. pos != m_FunctionBlockers.end(); ++pos)
  341. {
  342. // if this blocker was not in the original then send a
  343. // scope ended message
  344. if (originalBlockers.find(*pos) == originalBlockers.end())
  345. {
  346. (*pos)->ScopeEnded(*this);
  347. }
  348. }
  349. }
  350. return true;
  351. }
  352. void cmMakefile::AddCommand(cmCommand* wg)
  353. {
  354. this->GetCMakeInstance()->AddCommand(wg);
  355. }
  356. // Set the make file
  357. void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
  358. {
  359. m_LocalGenerator = lg;
  360. }
  361. void cmMakefile::FinalPass()
  362. {
  363. // do all the variable expansions here
  364. this->ExpandVariables();
  365. // give all the commands a chance to do something
  366. // after the file has been parsed before generation
  367. for(std::vector<cmCommand*>::iterator i = m_UsedCommands.begin();
  368. i != m_UsedCommands.end(); ++i)
  369. {
  370. (*i)->FinalPass();
  371. }
  372. }
  373. // Generate the output file
  374. void cmMakefile::ConfigureFinalPass()
  375. {
  376. this->FinalPass();
  377. const char* versionValue
  378. = this->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
  379. bool oldVersion = (!versionValue || atof(versionValue) < 1.4);
  380. // merge libraries
  381. for (cmTargets::iterator l = m_Targets.begin();
  382. l != m_Targets.end(); l++)
  383. {
  384. l->second.GenerateSourceFilesFromSourceLists(*this);
  385. // pick up any LINK_LIBRARIES that were added after the target
  386. if(oldVersion)
  387. {
  388. this->AddGlobalLinkInformation(l->first.c_str(), l->second);
  389. }
  390. l->second.AnalyzeLibDependencies(*this);
  391. }
  392. }
  393. void cmMakefile::AddCustomCommand(const char* source,
  394. const char* command,
  395. const std::vector<std::string>& commandArgs,
  396. const std::vector<std::string>& depends,
  397. const std::vector<std::string>& outputs,
  398. const char *target,
  399. const char *comment)
  400. {
  401. // find the target,
  402. if (m_Targets.find(target) != m_Targets.end())
  403. {
  404. std::string expandC = command;
  405. this->ExpandVariablesInString(expandC);
  406. std::string c = cmSystemTools::EscapeSpaces(expandC.c_str());
  407. std::string combinedArgs;
  408. unsigned int i;
  409. for (i = 0; i < commandArgs.size(); ++i)
  410. {
  411. expandC = commandArgs[i].c_str();
  412. this->ExpandVariablesInString(expandC);
  413. combinedArgs += cmSystemTools::EscapeSpaces(expandC.c_str());
  414. combinedArgs += " ";
  415. }
  416. cmCustomCommand cc(source,c.c_str(),combinedArgs.c_str(),depends,outputs);
  417. if ( comment && comment[0] )
  418. {
  419. cc.SetComment(comment);
  420. }
  421. m_Targets[target].GetCustomCommands().push_back(cc);
  422. std::string cacheCommand = command;
  423. this->ExpandVariablesInString(cacheCommand);
  424. if(this->GetCacheManager()->GetCacheValue(cacheCommand.c_str()))
  425. {
  426. m_Targets[target].AddUtility(
  427. this->GetCacheManager()->GetCacheValue(cacheCommand.c_str()));
  428. }
  429. }
  430. }
  431. void cmMakefile::AddCustomCommand(const char* source,
  432. const char* command,
  433. const std::vector<std::string>& commandArgs,
  434. const std::vector<std::string>& depends,
  435. const char* output,
  436. const char *target)
  437. {
  438. std::vector<std::string> outputs;
  439. outputs.push_back(output);
  440. this->AddCustomCommand(source, command, commandArgs, depends, outputs, target);
  441. }
  442. void cmMakefile::AddDefineFlag(const char* flag)
  443. {
  444. m_DefineFlags += " ";
  445. m_DefineFlags += flag;
  446. }
  447. void cmMakefile::AddLinkLibrary(const char* lib, cmTarget::LinkLibraryType llt)
  448. {
  449. m_LinkLibraries.push_back(
  450. std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt));
  451. }
  452. void cmMakefile::AddLinkLibraryForTarget(const char *target,
  453. const char* lib,
  454. cmTarget::LinkLibraryType llt)
  455. {
  456. cmTargets::iterator i = m_Targets.find(target);
  457. if ( i != m_Targets.end())
  458. {
  459. i->second.AddLinkLibrary( *this, target, lib, llt );
  460. }
  461. else
  462. {
  463. cmSystemTools::Error("Attempt to add link libraries to non-existant target: ", target, " for lib ", lib);
  464. }
  465. }
  466. void cmMakefile::AddLinkDirectoryForTarget(const char *target,
  467. const char* d)
  468. {
  469. cmTargets::iterator i = m_Targets.find(target);
  470. if ( i != m_Targets.end())
  471. {
  472. i->second.AddLinkDirectory( d );
  473. }
  474. else
  475. {
  476. cmSystemTools::Error("Attempt to add link directories to non-existant target: ",
  477. target, " for directory ", d);
  478. }
  479. }
  480. void cmMakefile::AddLinkLibrary(const char* lib)
  481. {
  482. this->AddLinkLibrary(lib,cmTarget::GENERAL);
  483. }
  484. void cmMakefile::AddLinkDirectory(const char* dir)
  485. {
  486. // Don't add a link directory that is already present. Yes, this
  487. // linear search results in n^2 behavior, but n won't be getting
  488. // much bigger than 20. We cannot use a set because of order
  489. // dependency of the link search path.
  490. // remove trailing slashes
  491. if(dir && dir[strlen(dir)-1] == '/')
  492. {
  493. std::string newdir = dir;
  494. newdir = newdir.substr(0, newdir.size()-1);
  495. if(std::find(m_LinkDirectories.begin(),
  496. m_LinkDirectories.end(), newdir.c_str()) == m_LinkDirectories.end())
  497. {
  498. m_LinkDirectories.push_back(newdir);
  499. }
  500. }
  501. else
  502. {
  503. if(std::find(m_LinkDirectories.begin(),
  504. m_LinkDirectories.end(), dir) == m_LinkDirectories.end())
  505. {
  506. m_LinkDirectories.push_back(dir);
  507. }
  508. }
  509. }
  510. void cmMakefile::AddSubDirectory(const char* sub)
  511. {
  512. // make sure it isn't already there
  513. if (std::find(m_SubDirectories.begin(),
  514. m_SubDirectories.end(), sub) == m_SubDirectories.end())
  515. {
  516. m_SubDirectories.push_back(sub);
  517. }
  518. }
  519. void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
  520. {
  521. // Don't add an include directory that is already present. Yes,
  522. // this linear search results in n^2 behavior, but n won't be
  523. // getting much bigger than 20. We cannot use a set because of
  524. // order dependency of the include path.
  525. if(std::find(m_IncludeDirectories.begin(),
  526. m_IncludeDirectories.end(), inc) == m_IncludeDirectories.end())
  527. {
  528. if (before)
  529. {
  530. // WARNING: this *is* expensive (linear time) since it's a vector
  531. m_IncludeDirectories.insert(m_IncludeDirectories.begin(), inc);
  532. }
  533. else
  534. {
  535. m_IncludeDirectories.push_back(inc);
  536. }
  537. }
  538. }
  539. void cmMakefile::AddDefinition(const char* name, const char* value)
  540. {
  541. if (!value )
  542. {
  543. return;
  544. }
  545. m_Definitions.erase( DefinitionMap::key_type(name));
  546. m_Definitions.insert(DefinitionMap::value_type(name, value));
  547. cmVariableWatch* vv = this->GetVariableWatch();
  548. if ( vv )
  549. {
  550. vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS);
  551. }
  552. }
  553. void cmMakefile::AddCacheDefinition(const char* name, const char* value,
  554. const char* doc,
  555. cmCacheManager::CacheEntryType type)
  556. {
  557. this->GetCacheManager()->AddCacheEntry(name, value, doc, type);
  558. this->AddDefinition(name, value);
  559. }
  560. void cmMakefile::AddDefinition(const char* name, bool value)
  561. {
  562. if(value)
  563. {
  564. m_Definitions.erase( DefinitionMap::key_type(name));
  565. m_Definitions.insert(DefinitionMap::value_type(name, "ON"));
  566. }
  567. else
  568. {
  569. m_Definitions.erase( DefinitionMap::key_type(name));
  570. m_Definitions.insert(DefinitionMap::value_type(name, "OFF"));
  571. }
  572. cmVariableWatch* vv = this->GetVariableWatch();
  573. if ( vv )
  574. {
  575. vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS);
  576. }
  577. }
  578. void cmMakefile::AddCacheDefinition(const char* name, bool value, const char* doc)
  579. {
  580. this->GetCacheManager()->AddCacheEntry(name, value, doc);
  581. this->AddDefinition(name, value);
  582. }
  583. void cmMakefile::RemoveDefinition(const char* name)
  584. {
  585. m_Definitions.erase(DefinitionMap::key_type(name));
  586. cmVariableWatch* vv = this->GetVariableWatch();
  587. if ( vv )
  588. {
  589. vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS);
  590. }
  591. }
  592. void cmMakefile::SetProjectName(const char* p)
  593. {
  594. m_ProjectName = p;
  595. }
  596. void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
  597. {
  598. // for these targets do not add anything
  599. switch(target.GetType())
  600. {
  601. case cmTarget::UTILITY:
  602. case cmTarget::INSTALL_FILES:
  603. case cmTarget::INSTALL_PROGRAMS:
  604. return;
  605. default:;
  606. }
  607. std::vector<std::string>::iterator j;
  608. for(j = m_LinkDirectories.begin();
  609. j != m_LinkDirectories.end(); ++j)
  610. {
  611. target.AddLinkDirectory(j->c_str());
  612. }
  613. target.MergeLinkLibraries( *this, name, m_LinkLibraries );
  614. }
  615. void cmMakefile::AddLibrary(const char* lname, int shared,
  616. const std::vector<std::string> &srcs)
  617. {
  618. cmTarget target;
  619. switch (shared)
  620. {
  621. case 0:
  622. target.SetType(cmTarget::STATIC_LIBRARY);
  623. break;
  624. case 1:
  625. target.SetType(cmTarget::SHARED_LIBRARY);
  626. break;
  627. case 2:
  628. target.SetType(cmTarget::MODULE_LIBRARY);
  629. break;
  630. default:
  631. target.SetType(cmTarget::STATIC_LIBRARY);
  632. }
  633. // Clear its dependencies. Otherwise, dependencies might persist
  634. // over changes in CMakeLists.txt, making the information stale and
  635. // hence useless.
  636. target.ClearDependencyInformation( *this, lname );
  637. target.SetInAll(true);
  638. target.GetSourceLists() = srcs;
  639. this->AddGlobalLinkInformation(lname, target);
  640. m_Targets.insert(cmTargets::value_type(lname,target));
  641. // Add an entry into the cache
  642. std::string libPath = lname;
  643. libPath += "_CMAKE_PATH";
  644. this->GetCacheManager()->
  645. AddCacheEntry(libPath.c_str(),
  646. this->GetCurrentOutputDirectory(),
  647. "Path to a library", cmCacheManager::INTERNAL);
  648. // Add an entry into the cache
  649. std::string ltname = lname;
  650. ltname += "_LIBRARY_TYPE";
  651. switch (shared)
  652. {
  653. case 0:
  654. this->GetCacheManager()->AddCacheEntry(ltname.c_str(),"STATIC",
  655. "Whether a library is static, shared or module.",
  656. cmCacheManager::INTERNAL);
  657. break;
  658. case 1:
  659. this->GetCacheManager()->
  660. AddCacheEntry(ltname.c_str(),
  661. "SHARED",
  662. "Whether a library is static, shared or module.",
  663. cmCacheManager::INTERNAL);
  664. break;
  665. case 2:
  666. this->GetCacheManager()->
  667. AddCacheEntry(ltname.c_str(),
  668. "MODULE",
  669. "Whether a library is static, shared or module.",
  670. cmCacheManager::INTERNAL);
  671. break;
  672. default:
  673. this->GetCacheManager()->
  674. AddCacheEntry(ltname.c_str(),
  675. "STATIC",
  676. "Whether a library is static, shared or module.",
  677. cmCacheManager::INTERNAL);
  678. }
  679. }
  680. void cmMakefile::AddExecutable(const char *exeName,
  681. const std::vector<std::string> &srcs)
  682. {
  683. this->AddExecutable(exeName,srcs,false);
  684. }
  685. void cmMakefile::AddExecutable(const char *exeName,
  686. const std::vector<std::string> &srcs,
  687. bool win32)
  688. {
  689. cmTarget target;
  690. if (win32)
  691. {
  692. target.SetType(cmTarget::WIN32_EXECUTABLE);
  693. }
  694. else
  695. {
  696. target.SetType(cmTarget::EXECUTABLE);
  697. }
  698. target.SetInAll(true);
  699. target.GetSourceLists() = srcs;
  700. this->AddGlobalLinkInformation(exeName, target);
  701. m_Targets.insert(cmTargets::value_type(exeName,target));
  702. // Add an entry into the cache
  703. std::string exePath = exeName;
  704. exePath += "_CMAKE_PATH";
  705. this->GetCacheManager()->
  706. AddCacheEntry(exePath.c_str(),
  707. this->GetCurrentOutputDirectory(),
  708. "Path to an executable", cmCacheManager::INTERNAL);
  709. }
  710. void cmMakefile::AddUtilityCommand(const char* utilityName,
  711. const char* command,
  712. const char* arguments,
  713. bool all)
  714. {
  715. std::vector<std::string> empty;
  716. this->AddUtilityCommand(utilityName,command,arguments,all,
  717. empty,empty);
  718. }
  719. void cmMakefile::AddUtilityCommand(const char* utilityName,
  720. const char* command,
  721. const char* arguments,
  722. bool all,
  723. const std::vector<std::string> &dep,
  724. const std::vector<std::string> &out)
  725. {
  726. cmTarget target;
  727. target.SetType(cmTarget::UTILITY);
  728. target.SetInAll(all);
  729. cmCustomCommand cc(utilityName, command, arguments, dep, out);
  730. target.GetCustomCommands().push_back(cc);
  731. m_Targets.insert(cmTargets::value_type(utilityName,target));
  732. }
  733. cmSourceGroup* cmMakefile::GetSourceGroup(const char* name)
  734. {
  735. // First see if the group exists. If so, replace its regular expression.
  736. for(std::vector<cmSourceGroup>::iterator sg = m_SourceGroups.begin();
  737. sg != m_SourceGroups.end(); ++sg)
  738. {
  739. std::string sgName = sg->GetName();
  740. if(sgName == name)
  741. {
  742. return &(*sg);
  743. }
  744. }
  745. return 0;
  746. }
  747. void cmMakefile::AddSourceGroup(const char* name, const char* regex)
  748. {
  749. // First see if the group exists. If so, replace its regular expression.
  750. for(std::vector<cmSourceGroup>::iterator sg = m_SourceGroups.begin();
  751. sg != m_SourceGroups.end(); ++sg)
  752. {
  753. std::string sgName = sg->GetName();
  754. if(sgName == name)
  755. {
  756. if ( regex )
  757. {
  758. // We only want to set the regular expression. If there are already
  759. // source files in the group, we don't want to remove them.
  760. sg->SetGroupRegex(regex);
  761. }
  762. return;
  763. }
  764. }
  765. // The group doesn't exist. Add it.
  766. m_SourceGroups.push_back(cmSourceGroup(name, regex));
  767. }
  768. void cmMakefile::AddExtraDirectory(const char* dir)
  769. {
  770. m_AuxSourceDirectories.push_back(dir);
  771. }
  772. // return the file name for the parent CMakeLists file to the
  773. // one passed in. Zero is returned if the CMakeLists file is the
  774. // one in the home directory or if for some reason a parent cmake lists
  775. // file cannot be found.
  776. std::string cmMakefile::GetParentListFileName(const char *currentFileName)
  777. {
  778. // extract the directory name
  779. std::string parentFile;
  780. std::string listsDir = currentFileName;
  781. std::string::size_type pos = listsDir.rfind('/');
  782. // if we could not find the directory return 0
  783. if(pos == std::string::npos)
  784. {
  785. return parentFile;
  786. }
  787. listsDir = listsDir.substr(0, pos);
  788. // if we are in the home directory then stop, return 0
  789. if(m_cmHomeDirectory == listsDir)
  790. {
  791. return parentFile;
  792. }
  793. // is there a parent directory we can check
  794. pos = listsDir.rfind('/');
  795. // if we could not find the directory return 0
  796. if(pos == std::string::npos)
  797. {
  798. return parentFile;
  799. }
  800. listsDir = listsDir.substr(0, pos);
  801. // is there a CMakeLists.txt file in the parent directory ?
  802. parentFile = listsDir;
  803. parentFile += "/CMakeLists.txt";
  804. while(!cmSystemTools::FileExists(parentFile.c_str()))
  805. {
  806. // There is no CMakeLists.txt file in the parent directory. This
  807. // can occur when coming out of a subdirectory resulting from a
  808. // SUBDIRS(Foo/Bar) command (coming out of Bar into Foo). Try
  809. // walking up until a CMakeLists.txt is found or the home
  810. // directory is hit.
  811. // if we are in the home directory then stop, return 0
  812. if(m_cmHomeDirectory == listsDir) { return ""; }
  813. // is there a parent directory we can check
  814. pos = listsDir.rfind('/');
  815. // if we could not find the directory return 0
  816. if(pos == std::string::npos) { return ""; }
  817. listsDir = listsDir.substr(0, pos);
  818. parentFile = listsDir;
  819. parentFile += "/CMakeLists.txt";
  820. }
  821. return parentFile;
  822. }
  823. // expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
  824. // include and library directories.
  825. void cmMakefile::ExpandVariables()
  826. {
  827. // Now expand variables in the include and link strings
  828. for(std::vector<std::string>::iterator d = m_IncludeDirectories.begin();
  829. d != m_IncludeDirectories.end(); ++d)
  830. {
  831. this->ExpandVariablesInString(*d);
  832. }
  833. for(std::vector<std::string>::iterator d = m_LinkDirectories.begin();
  834. d != m_LinkDirectories.end(); ++d)
  835. {
  836. this->ExpandVariablesInString(*d);
  837. }
  838. for(cmTarget::LinkLibraries::iterator l = m_LinkLibraries.begin();
  839. l != m_LinkLibraries.end(); ++l)
  840. {
  841. this->ExpandVariablesInString(l->first);
  842. }
  843. }
  844. bool cmMakefile::IsOn(const char* name) const
  845. {
  846. const char* value = this->GetDefinition(name);
  847. return cmSystemTools::IsOn(value);
  848. }
  849. const char* cmMakefile::GetDefinition(const char* name) const
  850. {
  851. const char* def = 0;
  852. DefinitionMap::const_iterator pos = m_Definitions.find(name);
  853. if(pos != m_Definitions.end())
  854. {
  855. def = (*pos).second.c_str();
  856. }
  857. else
  858. {
  859. def = this->GetCacheManager()->GetCacheValue(name);
  860. }
  861. cmVariableWatch* vv = this->GetVariableWatch();
  862. if ( vv )
  863. {
  864. if ( def )
  865. {
  866. vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS);
  867. }
  868. else
  869. {
  870. // are unknown access allowed
  871. DefinitionMap::const_iterator pos2 =
  872. m_Definitions.find("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
  873. if (pos2 != m_Definitions.end() &&
  874. cmSystemTools::IsOn((*pos2).second.c_str()))
  875. {
  876. vv->VariableAccessed(name,
  877. cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS);
  878. }
  879. else
  880. {
  881. vv->VariableAccessed(name, cmVariableWatch::
  882. UNKNOWN_VARIABLE_READ_ACCESS);
  883. }
  884. }
  885. }
  886. return def;
  887. }
  888. std::vector<std::string> cmMakefile::GetDefinitions(int cacheonly /* = 0 */) const
  889. {
  890. std::map<std::string, int> definitions;
  891. if ( !cacheonly )
  892. {
  893. DefinitionMap::const_iterator it;
  894. for ( it = m_Definitions.begin(); it != m_Definitions.end(); it ++ )
  895. {
  896. definitions[it->first] = 1;
  897. }
  898. }
  899. cmCacheManager::CacheIterator cit = this->GetCacheManager()->GetCacheIterator();
  900. for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
  901. {
  902. definitions[cit.GetName()] = 1;
  903. }
  904. std::vector<std::string> res;
  905. std::map<std::string, int>::iterator fit;
  906. for ( fit = definitions.begin(); fit != definitions.end(); fit ++ )
  907. {
  908. res.push_back(fit->first);
  909. }
  910. return res;
  911. }
  912. const char *cmMakefile::ExpandVariablesInString(std::string& source) const
  913. {
  914. return this->ExpandVariablesInString(source, false);
  915. }
  916. const char *cmMakefile::ExpandVariablesInString(std::string& source,
  917. bool escapeQuotes,
  918. bool atOnly) const
  919. {
  920. // This method replaces ${VAR} and @VAR@ where VAR is looked up
  921. // with GetDefinition(), if not found in the map, nothing is expanded.
  922. // It also supports the $ENV{VAR} syntax where VAR is looked up in
  923. // the current environment variables.
  924. // start by look for $ or @ in the string
  925. std::string::size_type markerPos;
  926. if(atOnly)
  927. {
  928. markerPos = source.find_first_of("@");
  929. }
  930. else
  931. {
  932. markerPos = source.find_first_of("$@");
  933. }
  934. // if not found, or found as the last character, then leave quickly as
  935. // nothing needs to be expanded
  936. if((markerPos == std::string::npos) || (markerPos >= source.size()-1))
  937. {
  938. return source.c_str();
  939. }
  940. // current position
  941. std::string::size_type currentPos =0; // start at 0
  942. std::string result; // string with replacements
  943. // go until the the end of the string
  944. while((markerPos != std::string::npos) && (markerPos < source.size()-1))
  945. {
  946. // grab string from currentPos to the start of the variable
  947. // and add it to the result
  948. result += source.substr(currentPos, markerPos - currentPos);
  949. char endVariableMarker; // what is the end of the variable @ or }
  950. int markerStartSize = 1; // size of the start marker 1 or 2 or 5
  951. if(!atOnly && source[markerPos] == '$')
  952. {
  953. // ${var} case
  954. if(source[markerPos+1] == '{')
  955. {
  956. endVariableMarker = '}';
  957. markerStartSize = 2;
  958. }
  959. // $ENV{var} case
  960. else if(markerPos+4 < source.size() &&
  961. source[markerPos+4] == '{' &&
  962. !source.substr(markerPos+1, 3).compare("ENV"))
  963. {
  964. endVariableMarker = '}';
  965. markerStartSize = 5;
  966. }
  967. else
  968. {
  969. // bogus $ with no { so add $ to result and move on
  970. result += '$'; // add bogus $ back into string
  971. currentPos = markerPos+1; // move on
  972. endVariableMarker = ' '; // set end var to space so we can tell bogus
  973. }
  974. }
  975. else
  976. {
  977. // @VAR case
  978. endVariableMarker = '@';
  979. }
  980. // if it was a valid variable (started with @ or ${ or $ENV{ )
  981. if(endVariableMarker != ' ')
  982. {
  983. markerPos += markerStartSize; // move past marker
  984. // find the end variable marker starting at the markerPos
  985. std::string::size_type endVariablePos =
  986. source.find(endVariableMarker, markerPos);
  987. if(endVariablePos == std::string::npos)
  988. {
  989. // no end marker found so add the bogus start
  990. if(endVariableMarker == '@')
  991. {
  992. result += '@';
  993. }
  994. else
  995. {
  996. result += (markerStartSize == 5 ? "$ENV{" : "${");
  997. }
  998. currentPos = markerPos;
  999. }
  1000. else
  1001. {
  1002. // good variable remove it
  1003. std::string var = source.substr(markerPos, endVariablePos - markerPos);
  1004. bool found = false;
  1005. if (markerStartSize == 5) // $ENV{
  1006. {
  1007. char *ptr = getenv(var.c_str());
  1008. if (ptr)
  1009. {
  1010. if (escapeQuotes)
  1011. {
  1012. result += cmSystemTools::EscapeQuotes(ptr);
  1013. }
  1014. else
  1015. {
  1016. result += ptr;
  1017. }
  1018. found = true;
  1019. }
  1020. }
  1021. else
  1022. {
  1023. const char* lookup = this->GetDefinition(var.c_str());
  1024. if(lookup)
  1025. {
  1026. if (escapeQuotes)
  1027. {
  1028. result += cmSystemTools::EscapeQuotes(lookup);
  1029. }
  1030. else
  1031. {
  1032. result += lookup;
  1033. }
  1034. found = true;
  1035. }
  1036. }
  1037. // if found add to result, if not, then it gets blanked
  1038. if (!found)
  1039. {
  1040. // if no definition is found then add the var back
  1041. if(endVariableMarker == '@')
  1042. {
  1043. result += "@";
  1044. result += var;
  1045. result += "@";
  1046. }
  1047. // do nothing, we remove the variable
  1048. /* else
  1049. {
  1050. result += (markerStartSize == 5 ? "$ENV{" : "${");
  1051. result += var;
  1052. result += "}";
  1053. }
  1054. */
  1055. }
  1056. // lookup var, and replace it
  1057. currentPos = endVariablePos+1;
  1058. }
  1059. }
  1060. if(atOnly)
  1061. {
  1062. markerPos = source.find_first_of("@", currentPos);
  1063. }
  1064. else
  1065. {
  1066. markerPos = source.find_first_of("$@", currentPos);
  1067. }
  1068. }
  1069. result += source.substr(currentPos); // pick up the rest of the string
  1070. source = result;
  1071. return source.c_str();
  1072. }
  1073. void cmMakefile::RemoveVariablesInString(std::string& source,
  1074. bool atOnly) const
  1075. {
  1076. if(!atOnly)
  1077. {
  1078. cmRegularExpression var("(\\${[A-Za-z_0-9]*})");
  1079. while (var.find(source))
  1080. {
  1081. source.erase(var.start(),var.end() - var.start());
  1082. }
  1083. }
  1084. if(!atOnly)
  1085. {
  1086. cmRegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
  1087. while (varb.find(source))
  1088. {
  1089. source.erase(varb.start(),varb.end() - varb.start());
  1090. }
  1091. }
  1092. cmRegularExpression var2("(@[A-Za-z_0-9]*@)");
  1093. while (var2.find(source))
  1094. {
  1095. source.erase(var2.start(),var2.end() - var2.start());
  1096. }
  1097. }
  1098. /**
  1099. * Add the default definitions to the makefile. These values must not
  1100. * be dependent on anything that isn't known when this cmMakefile instance
  1101. * is constructed.
  1102. */
  1103. void cmMakefile::AddDefaultDefinitions()
  1104. {
  1105. #if defined(_WIN32) || defined(__CYGWIN__)
  1106. this->AddDefinition("WIN32", "1");
  1107. #else
  1108. this->AddDefinition("UNIX", "1");
  1109. #endif
  1110. // Cygwin is more like unix so enable the unix commands
  1111. #if defined(__CYGWIN__)
  1112. this->AddDefinition("UNIX", "1");
  1113. this->AddDefinition("CYGWIN", "1");
  1114. #endif
  1115. #if defined(__APPLE__)
  1116. this->AddDefinition("APPLE", "1");
  1117. #endif
  1118. char temp[1024];
  1119. sprintf(temp, "%d", cmMakefile::GetMinorVersion());
  1120. this->AddDefinition("CMAKE_MINOR_VERSION", temp);
  1121. sprintf(temp, "%d", cmMakefile::GetMajorVersion());
  1122. this->AddDefinition("CMAKE_MAJOR_VERSION", temp);
  1123. }
  1124. /**
  1125. * Find a source group whose regular expression matches the filename
  1126. * part of the given source name. Search backward through the list of
  1127. * source groups, and take the first matching group found. This way
  1128. * non-inherited SOURCE_GROUP commands will have precedence over
  1129. * inherited ones.
  1130. */
  1131. cmSourceGroup&
  1132. cmMakefile::FindSourceGroup(const char* source,
  1133. std::vector<cmSourceGroup> &groups)
  1134. {
  1135. std::string file = source;
  1136. std::string::size_type pos = file.rfind('/');
  1137. if(pos != std::string::npos)
  1138. {
  1139. file = file.substr(pos, file.length()-pos);
  1140. }
  1141. for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
  1142. sg != groups.rend(); ++sg)
  1143. {
  1144. if(sg->Matches(file.c_str()))
  1145. {
  1146. return *sg;
  1147. }
  1148. }
  1149. // Shouldn't get here, but just in case, return the default group.
  1150. return groups.front();
  1151. }
  1152. bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff)
  1153. {
  1154. // if there are no blockers get out of here
  1155. if (m_FunctionBlockers.begin() == m_FunctionBlockers.end())
  1156. {
  1157. return false;
  1158. }
  1159. // loop over all function blockers to see if any block this command
  1160. // evaluate in reverse, this is critical for balanced IF statements etc
  1161. std::list<cmFunctionBlocker *>::reverse_iterator pos;
  1162. for (pos = m_FunctionBlockers.rbegin();
  1163. pos != m_FunctionBlockers.rend(); ++pos)
  1164. {
  1165. if((*pos)->IsFunctionBlocked(lff, *this))
  1166. {
  1167. return true;
  1168. }
  1169. }
  1170. return false;
  1171. }
  1172. void cmMakefile::ExpandArguments(
  1173. std::vector<cmListFileArgument> const& inArgs,
  1174. std::vector<std::string>& outArgs)
  1175. {
  1176. std::vector<cmListFileArgument>::const_iterator i;
  1177. for(i = inArgs.begin(); i != inArgs.end(); ++i)
  1178. {
  1179. // Expand the variables in the argument.
  1180. std::string value = i->Value;
  1181. this->ExpandVariablesInString(value);
  1182. // If the argument is quoted, it should be one argument.
  1183. // Otherwise, it may be a list of arguments.
  1184. if(i->Quoted)
  1185. {
  1186. outArgs.push_back(value);
  1187. }
  1188. else
  1189. {
  1190. cmSystemTools::ExpandListArgument(value, outArgs);
  1191. }
  1192. }
  1193. }
  1194. void cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
  1195. {
  1196. // loop over all function blockers to see if any block this command
  1197. std::list<cmFunctionBlocker *>::reverse_iterator pos;
  1198. for (pos = m_FunctionBlockers.rbegin();
  1199. pos != m_FunctionBlockers.rend(); ++pos)
  1200. {
  1201. if ((*pos)->ShouldRemove(lff, *this))
  1202. {
  1203. cmFunctionBlocker* b = *pos;
  1204. m_FunctionBlockers.remove(b);
  1205. delete b;
  1206. break;
  1207. }
  1208. }
  1209. return;
  1210. }
  1211. void cmMakefile::SetHomeDirectory(const char* dir)
  1212. {
  1213. m_cmHomeDirectory = dir;
  1214. cmSystemTools::ConvertToUnixSlashes(m_cmHomeDirectory);
  1215. this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
  1216. }
  1217. void cmMakefile::SetHomeOutputDirectory(const char* lib)
  1218. {
  1219. m_HomeOutputDirectory = lib;
  1220. cmSystemTools::ConvertToUnixSlashes(m_HomeOutputDirectory);
  1221. this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
  1222. }
  1223. /**
  1224. * Register the given cmData instance with its own name.
  1225. */
  1226. void cmMakefile::RegisterData(cmData* data)
  1227. {
  1228. std::string name = data->GetName();
  1229. DataMap::const_iterator d = m_DataMap.find(name);
  1230. if((d != m_DataMap.end()) && (d->second != 0) && (d->second != data))
  1231. {
  1232. delete d->second;
  1233. }
  1234. m_DataMap[name] = data;
  1235. }
  1236. /**
  1237. * Register the given cmData instance with the given name. This can be used
  1238. * to register a NULL pointer.
  1239. */
  1240. void cmMakefile::RegisterData(const char* name, cmData* data)
  1241. {
  1242. DataMap::const_iterator d = m_DataMap.find(name);
  1243. if((d != m_DataMap.end()) && (d->second != 0) && (d->second != data))
  1244. {
  1245. delete d->second;
  1246. }
  1247. m_DataMap[name] = data;
  1248. }
  1249. /**
  1250. * Lookup a cmData instance previously registered with the given name. If
  1251. * the instance cannot be found, return NULL.
  1252. */
  1253. cmData* cmMakefile::LookupData(const char* name) const
  1254. {
  1255. DataMap::const_iterator d = m_DataMap.find(name);
  1256. if(d != m_DataMap.end())
  1257. {
  1258. return d->second;
  1259. }
  1260. else
  1261. {
  1262. return 0;
  1263. }
  1264. }
  1265. cmSourceFile* cmMakefile::GetSource(const char* sourceName) const
  1266. {
  1267. std::string s = cmSystemTools::GetFilenameName(sourceName);
  1268. std::string ext;
  1269. std::string::size_type pos = s.rfind('.');
  1270. if(pos != std::string::npos)
  1271. {
  1272. ext = s.substr(pos+1, s.size() - pos-1);
  1273. s = s.substr(0, pos);
  1274. }
  1275. for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin();
  1276. i != m_SourceFiles.end(); ++i)
  1277. {
  1278. if ((*i)->GetSourceName() == s)
  1279. {
  1280. if ((ext.size() == 0 || (ext == (*i)->GetSourceExtension())))
  1281. {
  1282. return *i;
  1283. }
  1284. }
  1285. }
  1286. return 0;
  1287. }
  1288. cmSourceFile* cmMakefile::AddSource(cmSourceFile const&sf)
  1289. {
  1290. // check to see if it exists
  1291. cmSourceFile* ret = this->GetSource(sf.GetSourceName().c_str());
  1292. if(ret && ret->GetSourceExtension() == sf.GetSourceExtension())
  1293. {
  1294. return ret;
  1295. }
  1296. ret = new cmSourceFile(sf);
  1297. m_SourceFiles.push_back(ret);
  1298. return ret;
  1299. }
  1300. void cmMakefile::EnableLanguage(const char* lang)
  1301. {
  1302. m_LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this);
  1303. }
  1304. void cmMakefile::ExpandSourceListArguments(
  1305. std::vector<std::string> const& arguments,
  1306. std::vector<std::string>& newargs, unsigned int start)
  1307. {
  1308. // first figure out if we need to handle version 1.2 style source lists
  1309. int oldVersion = 1;
  1310. const char* versionValue
  1311. = this->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
  1312. if (versionValue && atof(versionValue) > 1.2)
  1313. {
  1314. oldVersion = 0;
  1315. }
  1316. // now expand the args
  1317. unsigned int i;
  1318. for(i = 0; i < arguments.size(); ++i)
  1319. {
  1320. // is the arg defined ?, if so use the def
  1321. const char *def = this->GetDefinition(arguments[i].c_str());
  1322. if (def && oldVersion && i >= start)
  1323. {
  1324. // Definition lookup could result in a list that needs to be
  1325. // expanded.
  1326. cmSystemTools::ExpandListArgument(def, newargs);
  1327. }
  1328. else
  1329. {
  1330. // List expansion will have been done already.
  1331. newargs.push_back(arguments[i]);
  1332. }
  1333. }
  1334. }
  1335. int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
  1336. const char *projectName, const char *targetName,
  1337. const std::vector<std::string> *cmakeArgs,
  1338. std::string *output)
  1339. {
  1340. // does the binary directory exist ? If not create it...
  1341. if (!cmSystemTools::FileIsDirectory(bindir))
  1342. {
  1343. cmSystemTools::MakeDirectory(bindir);
  1344. }
  1345. // change to the tests directory and run cmake
  1346. // use the cmake object instead of calling cmake
  1347. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  1348. cmSystemTools::ChangeDirectory(bindir);
  1349. // make sure the same generator is used
  1350. // use this program as the cmake to be run, it should not
  1351. // be run that way but the cmake object requires a vailid path
  1352. std::string cmakeCommand = this->GetDefinition("CMAKE_COMMAND");
  1353. cmake cm;
  1354. cm.SetIsInTryCompile(true);
  1355. cmGlobalGenerator *gg =
  1356. cm.CreateGlobalGenerator(m_LocalGenerator->GetGlobalGenerator()->GetName());
  1357. if (!gg)
  1358. {
  1359. cmSystemTools::Error(
  1360. "Internal CMake error, TryCompile bad GlobalGenerator");
  1361. // return to the original directory
  1362. cmSystemTools::ChangeDirectory(cwd.c_str());
  1363. return 1;
  1364. }
  1365. cm.SetGlobalGenerator(gg);
  1366. // do a configure
  1367. cm.SetHomeDirectory(srcdir);
  1368. cm.SetHomeOutputDirectory(bindir);
  1369. cm.SetStartDirectory(srcdir);
  1370. cm.SetStartOutputDirectory(bindir);
  1371. cm.SetCMakeCommand(cmakeCommand.c_str());
  1372. cm.LoadCache();
  1373. // if cmake args were provided then pass them in
  1374. if (cmakeArgs)
  1375. {
  1376. cm.SetCacheArgs(*cmakeArgs);
  1377. }
  1378. // to save time we pass the EnableLanguage info directly
  1379. gg->EnableLanguagesFromGenerator(m_LocalGenerator->GetGlobalGenerator());
  1380. if (cm.Configure() != 0)
  1381. {
  1382. cmSystemTools::Error(
  1383. "Internal CMake error, TryCompile configure of cmake failed");
  1384. // return to the original directory
  1385. cmSystemTools::ChangeDirectory(cwd.c_str());
  1386. return 1;
  1387. }
  1388. if (cm.Generate() != 0)
  1389. {
  1390. cmSystemTools::Error(
  1391. "Internal CMake error, TryCompile generation of cmake failed");
  1392. // return to the original directory
  1393. cmSystemTools::ChangeDirectory(cwd.c_str());
  1394. return 1;
  1395. }
  1396. // finally call the generator to actually build the resulting project
  1397. int ret =
  1398. m_LocalGenerator->GetGlobalGenerator()->TryCompile(srcdir,bindir,
  1399. projectName,
  1400. targetName,
  1401. output);
  1402. cmSystemTools::ChangeDirectory(cwd.c_str());
  1403. return ret;
  1404. }
  1405. cmake *cmMakefile::GetCMakeInstance() const
  1406. {
  1407. if ( m_LocalGenerator && m_LocalGenerator->GetGlobalGenerator() )
  1408. {
  1409. return m_LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
  1410. }
  1411. return 0;
  1412. }
  1413. cmVariableWatch *cmMakefile::GetVariableWatch() const
  1414. {
  1415. if ( this->GetCMakeInstance() &&
  1416. this->GetCMakeInstance()->GetVariableWatch() )
  1417. {
  1418. return this->GetCMakeInstance()->GetVariableWatch();
  1419. }
  1420. return 0;
  1421. }
  1422. cmCacheManager *cmMakefile::GetCacheManager() const
  1423. {
  1424. return this->GetCMakeInstance()->GetCacheManager();
  1425. }
  1426. bool cmMakefile::GetLocal() const
  1427. {
  1428. return this->GetCMakeInstance()->GetLocal();
  1429. }
  1430. void cmMakefile::DisplayStatus(const char* message, float s)
  1431. {
  1432. this->GetLocalGenerator()->GetGlobalGenerator()
  1433. ->GetCMakeInstance()->UpdateProgress(message, s);
  1434. }
  1435. /**
  1436. * Find the library with the given name. Searches the given path and then
  1437. * the system search path. Returns the full path to the library if it is
  1438. * found. Otherwise, the empty string is returned.
  1439. */
  1440. std::string cmMakefile::FindLibrary(const char* name,
  1441. const std::vector<std::string>& userPaths)
  1442. {
  1443. // See if the executable exists as written.
  1444. if(cmSystemTools::FileExists(name))
  1445. {
  1446. return cmSystemTools::CollapseFullPath(name);
  1447. }
  1448. // Add the system search path to our path.
  1449. std::vector<std::string> path = userPaths;
  1450. cmSystemTools::GetPath(path);
  1451. // Add some lib directories specific to compilers, depending on the
  1452. // current generator, so that library that might have been stored here
  1453. // can be found too.
  1454. // i.e. Microsoft Visual Studio or .Net: path to compiler/../Lib
  1455. // Borland: path to compiler/../Lib
  1456. const char* genName = this->GetDefinition("CMAKE_GENERATOR");
  1457. if (genName)
  1458. {
  1459. if (!strcmp(genName, "NMake Makefiles") ||
  1460. !strcmp(genName, "Visual Studio 6"))
  1461. {
  1462. const char* compiler = this->GetDefinition("CMAKE_CXX_COMPILER");
  1463. if (compiler)
  1464. {
  1465. std::string compiler_path = cmSystemTools::FindProgram(compiler);
  1466. if (compiler_path.size())
  1467. {
  1468. std::string lib_path =
  1469. cmSystemTools::GetFilenamePath(
  1470. cmSystemTools::GetFilenamePath(compiler_path)) + "/Lib";
  1471. path.push_back(lib_path);
  1472. }
  1473. }
  1474. }
  1475. else if (!strcmp(genName, "Visual Studio 7"))
  1476. {
  1477. // It is likely that the compiler won't be in the path for .Net, but
  1478. // we know where devenv is.
  1479. const char* devenv = this->GetDefinition("MICROSOFT_DEVENV");
  1480. if (devenv)
  1481. {
  1482. std::string devenv_path = cmSystemTools::FindProgram(devenv);
  1483. if (devenv_path.size())
  1484. {
  1485. std::string vc7_path =
  1486. cmSystemTools::GetFilenamePath(
  1487. cmSystemTools::GetFilenamePath(
  1488. cmSystemTools::GetFilenamePath(devenv_path))) + "/Vc7";
  1489. path.push_back(vc7_path + "/lib");
  1490. path.push_back(vc7_path + "/PlatformSDK/lib");
  1491. }
  1492. }
  1493. }
  1494. else if (!strcmp(genName, "Borland Makefiles"))
  1495. {
  1496. const char* bcb_bin_path = this->GetDefinition("BCB_BIN_PATH");
  1497. if (bcb_bin_path)
  1498. {
  1499. std::string lib_path =
  1500. cmSystemTools::GetFilenamePath(bcb_bin_path) + "/Lib";
  1501. path.push_back(lib_path);
  1502. }
  1503. }
  1504. }
  1505. return cmSystemTools::FindLibrary(name, path);
  1506. }