cmMakefile.cxx 48 KB

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