cmMakefile.cxx 46 KB

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