cmMakefile.cxx 44 KB

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