cmState.cxx 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2015 Stephen Kelly <[email protected]>
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmState.h"
  11. #include "cmake.h"
  12. #include "cmCacheManager.h"
  13. #include "cmCommand.h"
  14. #include "cmAlgorithms.h"
  15. #include "cmDefinitions.h"
  16. #include <assert.h>
  17. struct cmState::SnapshotDataType
  18. {
  19. cmState::PositionType ScopeParent;
  20. cmState::PositionType DirectoryParent;
  21. cmLinkedTree<cmState::PolicyStackEntry>::iterator Policies;
  22. cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyRoot;
  23. cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyScope;
  24. cmState::SnapshotType SnapshotType;
  25. cmLinkedTree<std::string>::iterator ExecutionListFile;
  26. cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator
  27. BuildSystemDirectory;
  28. cmLinkedTree<cmDefinitions>::iterator Vars;
  29. cmLinkedTree<cmDefinitions>::iterator Root;
  30. cmLinkedTree<cmDefinitions>::iterator Parent;
  31. std::string EntryPointCommand;
  32. long EntryPointLine;
  33. std::vector<std::string>::size_type IncludeDirectoryPosition;
  34. std::vector<std::string>::size_type CompileDefinitionsPosition;
  35. std::vector<std::string>::size_type CompileOptionsPosition;
  36. };
  37. struct cmState::PolicyStackEntry: public cmPolicies::PolicyMap
  38. {
  39. typedef cmPolicies::PolicyMap derived;
  40. PolicyStackEntry(bool w = false): derived(), Weak(w) {}
  41. PolicyStackEntry(derived const& d, bool w): derived(d), Weak(w) {}
  42. PolicyStackEntry(PolicyStackEntry const& r): derived(r), Weak(r.Weak) {}
  43. bool Weak;
  44. };
  45. struct cmState::BuildsystemDirectoryStateType
  46. {
  47. cmState::PositionType DirectoryEnd;
  48. std::string Location;
  49. std::string OutputLocation;
  50. std::vector<std::string> CurrentSourceDirectoryComponents;
  51. std::vector<std::string> CurrentBinaryDirectoryComponents;
  52. // The top-most directories for relative path conversion. Both the
  53. // source and destination location of a relative path conversion
  54. // must be underneath one of these directories (both under source or
  55. // both under binary) in order for the relative path to be evaluated
  56. // safely by the build tools.
  57. std::string RelativePathTopSource;
  58. std::string RelativePathTopBinary;
  59. std::vector<std::string> IncludeDirectories;
  60. std::vector<cmListFileBacktrace> IncludeDirectoryBacktraces;
  61. std::vector<std::string> CompileDefinitions;
  62. std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
  63. std::vector<std::string> CompileOptions;
  64. std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
  65. std::string ProjectName;
  66. cmPropertyMap Properties;
  67. std::vector<cmState::Snapshot> Children;
  68. };
  69. cmState::cmState(cmake* cm)
  70. : CMakeInstance(cm),
  71. IsInTryCompile(false),
  72. WindowsShell(false),
  73. WindowsVSIDE(false),
  74. WatcomWMake(false),
  75. MinGWMake(false),
  76. NMake(false),
  77. MSYSShell(false)
  78. {
  79. }
  80. cmState::~cmState()
  81. {
  82. cmDeleteAll(this->Commands);
  83. }
  84. const char* cmCacheEntryTypes[] =
  85. { "BOOL",
  86. "PATH",
  87. "FILEPATH",
  88. "STRING",
  89. "INTERNAL",
  90. "STATIC",
  91. "UNINITIALIZED",
  92. 0
  93. };
  94. const char*
  95. cmState::CacheEntryTypeToString(cmState::CacheEntryType type)
  96. {
  97. if ( type > 6 )
  98. {
  99. return cmCacheEntryTypes[6];
  100. }
  101. return cmCacheEntryTypes[type];
  102. }
  103. cmState::CacheEntryType
  104. cmState::StringToCacheEntryType(const char* s)
  105. {
  106. int i = 0;
  107. while(cmCacheEntryTypes[i])
  108. {
  109. if(strcmp(s, cmCacheEntryTypes[i]) == 0)
  110. {
  111. return static_cast<cmState::CacheEntryType>(i);
  112. }
  113. ++i;
  114. }
  115. return STRING;
  116. }
  117. bool cmState::IsCacheEntryType(std::string const& key)
  118. {
  119. for(int i=0; cmCacheEntryTypes[i]; ++i)
  120. {
  121. if(strcmp(key.c_str(), cmCacheEntryTypes[i]) == 0)
  122. {
  123. return true;
  124. }
  125. }
  126. return false;
  127. }
  128. bool cmState::LoadCache(const std::string& path, bool internal,
  129. std::set<std::string>& excludes,
  130. std::set<std::string>& includes)
  131. {
  132. return this->CMakeInstance->GetCacheManager()->LoadCache(path, internal,
  133. excludes, includes);
  134. }
  135. bool cmState::SaveCache(const std::string& path)
  136. {
  137. return this->CMakeInstance->GetCacheManager()->SaveCache(path);
  138. }
  139. bool cmState::DeleteCache(const std::string& path)
  140. {
  141. return this->CMakeInstance->GetCacheManager()->DeleteCache(path);
  142. }
  143. std::vector<std::string> cmState::GetCacheEntryKeys() const
  144. {
  145. std::vector<std::string> definitions;
  146. definitions.reserve(this->CMakeInstance->GetCacheManager()->GetSize());
  147. cmCacheManager::CacheIterator cit =
  148. this->CMakeInstance->GetCacheManager()->GetCacheIterator();
  149. for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
  150. {
  151. definitions.push_back(cit.GetName());
  152. }
  153. return definitions;
  154. }
  155. const char* cmState::GetCacheEntryValue(std::string const& key) const
  156. {
  157. cmCacheManager::CacheEntry* e = this->CMakeInstance->GetCacheManager()
  158. ->GetCacheEntry(key);
  159. if (!e)
  160. {
  161. return 0;
  162. }
  163. return e->Value.c_str();
  164. }
  165. const char*
  166. cmState::GetInitializedCacheValue(std::string const& key) const
  167. {
  168. return this->CMakeInstance->GetCacheManager()->GetInitializedCacheValue(key);
  169. }
  170. cmState::CacheEntryType
  171. cmState::GetCacheEntryType(std::string const& key) const
  172. {
  173. cmCacheManager::CacheIterator it =
  174. this->CMakeInstance->GetCacheManager()->GetCacheIterator(key.c_str());
  175. return it.GetType();
  176. }
  177. void cmState::SetCacheEntryValue(std::string const& key,
  178. std::string const& value)
  179. {
  180. this->CMakeInstance->GetCacheManager()->SetCacheEntryValue(key, value);
  181. }
  182. void cmState::SetCacheEntryProperty(std::string const& key,
  183. std::string const& propertyName,
  184. std::string const& value)
  185. {
  186. cmCacheManager::CacheIterator it =
  187. this->CMakeInstance->GetCacheManager()->GetCacheIterator(key.c_str());
  188. it.SetProperty(propertyName, value.c_str());
  189. }
  190. void cmState::SetCacheEntryBoolProperty(std::string const& key,
  191. std::string const& propertyName,
  192. bool value)
  193. {
  194. cmCacheManager::CacheIterator it =
  195. this->CMakeInstance->GetCacheManager()->GetCacheIterator(key.c_str());
  196. it.SetProperty(propertyName, value);
  197. }
  198. const char* cmState::GetCacheEntryProperty(std::string const& key,
  199. std::string const& propertyName)
  200. {
  201. cmCacheManager::CacheIterator it = this->CMakeInstance->GetCacheManager()
  202. ->GetCacheIterator(key.c_str());
  203. if (!it.PropertyExists(propertyName))
  204. {
  205. return 0;
  206. }
  207. return it.GetProperty(propertyName);
  208. }
  209. bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
  210. std::string const& propertyName)
  211. {
  212. return this->CMakeInstance->GetCacheManager()
  213. ->GetCacheIterator(key.c_str()).GetPropertyAsBool(propertyName);
  214. }
  215. void cmState::AddCacheEntry(const std::string& key, const char* value,
  216. const char* helpString,
  217. cmState::CacheEntryType type)
  218. {
  219. this->CMakeInstance->GetCacheManager()->AddCacheEntry(key, value,
  220. helpString, type);
  221. }
  222. void cmState::RemoveCacheEntry(std::string const& key)
  223. {
  224. this->CMakeInstance->GetCacheManager()->RemoveCacheEntry(key);
  225. }
  226. void cmState::AppendCacheEntryProperty(const std::string& key,
  227. const std::string& property,
  228. const std::string& value,
  229. bool asString)
  230. {
  231. this->CMakeInstance->GetCacheManager()
  232. ->GetCacheIterator(key.c_str()).AppendProperty(property,
  233. value.c_str(),
  234. asString);
  235. }
  236. void cmState::RemoveCacheEntryProperty(std::string const& key,
  237. std::string const& propertyName)
  238. {
  239. this->CMakeInstance->GetCacheManager()
  240. ->GetCacheIterator(key.c_str()).SetProperty(propertyName, (void*)0);
  241. }
  242. cmState::Snapshot cmState::Reset()
  243. {
  244. this->GlobalProperties.clear();
  245. this->PropertyDefinitions.clear();
  246. PositionType pos = this->SnapshotData.Truncate();
  247. this->ExecutionListFiles.Truncate();
  248. {
  249. cmLinkedTree<BuildsystemDirectoryStateType>::iterator it =
  250. this->BuildsystemDirectory.Truncate();
  251. it->IncludeDirectories.clear();
  252. it->IncludeDirectoryBacktraces.clear();
  253. it->CompileDefinitions.clear();
  254. it->CompileDefinitionsBacktraces.clear();
  255. it->CompileOptions.clear();
  256. it->CompileOptionsBacktraces.clear();
  257. it->DirectoryEnd = pos;
  258. it->Properties.clear();
  259. it->Children.clear();
  260. }
  261. this->PolicyStack.Clear();
  262. pos->Policies = this->PolicyStack.Root();
  263. pos->PolicyRoot = this->PolicyStack.Root();
  264. pos->PolicyScope = this->PolicyStack.Root();
  265. assert(pos->Policies.IsValid());
  266. assert(pos->PolicyRoot.IsValid());
  267. this->VarTree.Clear();
  268. pos->Vars = this->VarTree.Extend(this->VarTree.Root());
  269. pos->Parent = this->VarTree.Root();
  270. pos->Root = this->VarTree.Root();
  271. this->DefineProperty
  272. ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
  273. "", "", true);
  274. this->DefineProperty
  275. ("RULE_LAUNCH_LINK", cmProperty::DIRECTORY,
  276. "", "", true);
  277. this->DefineProperty
  278. ("RULE_LAUNCH_CUSTOM", cmProperty::DIRECTORY,
  279. "", "", true);
  280. this->DefineProperty
  281. ("RULE_LAUNCH_COMPILE", cmProperty::TARGET,
  282. "", "", true);
  283. this->DefineProperty
  284. ("RULE_LAUNCH_LINK", cmProperty::TARGET,
  285. "", "", true);
  286. this->DefineProperty
  287. ("RULE_LAUNCH_CUSTOM", cmProperty::TARGET,
  288. "", "", true);
  289. return Snapshot(this, pos);
  290. }
  291. void cmState::DefineProperty(const std::string& name,
  292. cmProperty::ScopeType scope,
  293. const char *ShortDescription,
  294. const char *FullDescription,
  295. bool chained)
  296. {
  297. this->PropertyDefinitions[scope].DefineProperty(name,scope,ShortDescription,
  298. FullDescription,
  299. chained);
  300. }
  301. cmPropertyDefinition const* cmState
  302. ::GetPropertyDefinition(const std::string& name,
  303. cmProperty::ScopeType scope) const
  304. {
  305. if (this->IsPropertyDefined(name,scope))
  306. {
  307. cmPropertyDefinitionMap const& defs =
  308. this->PropertyDefinitions.find(scope)->second;
  309. return &defs.find(name)->second;
  310. }
  311. return 0;
  312. }
  313. bool cmState::IsPropertyDefined(const std::string& name,
  314. cmProperty::ScopeType scope) const
  315. {
  316. std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it
  317. = this->PropertyDefinitions.find(scope);
  318. if (it == this->PropertyDefinitions.end())
  319. {
  320. return false;
  321. }
  322. return it->second.IsPropertyDefined(name);
  323. }
  324. bool cmState::IsPropertyChained(const std::string& name,
  325. cmProperty::ScopeType scope) const
  326. {
  327. std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it
  328. = this->PropertyDefinitions.find(scope);
  329. if (it == this->PropertyDefinitions.end())
  330. {
  331. return false;
  332. }
  333. return it->second.IsPropertyChained(name);
  334. }
  335. void cmState::SetLanguageEnabled(std::string const& l)
  336. {
  337. std::vector<std::string>::iterator it =
  338. std::lower_bound(this->EnabledLanguages.begin(),
  339. this->EnabledLanguages.end(), l);
  340. if (it == this->EnabledLanguages.end() || *it != l)
  341. {
  342. this->EnabledLanguages.insert(it, l);
  343. }
  344. }
  345. bool cmState::GetLanguageEnabled(std::string const& l) const
  346. {
  347. return std::binary_search(this->EnabledLanguages.begin(),
  348. this->EnabledLanguages.end(), l);
  349. }
  350. std::vector<std::string> cmState::GetEnabledLanguages() const
  351. {
  352. return this->EnabledLanguages;
  353. }
  354. void cmState::SetEnabledLanguages(std::vector<std::string> const& langs)
  355. {
  356. this->EnabledLanguages = langs;
  357. }
  358. void cmState::ClearEnabledLanguages()
  359. {
  360. this->EnabledLanguages.clear();
  361. }
  362. bool cmState::GetIsInTryCompile() const
  363. {
  364. return this->IsInTryCompile;
  365. }
  366. void cmState::SetIsInTryCompile(bool b)
  367. {
  368. this->IsInTryCompile = b;
  369. }
  370. void cmState::RenameCommand(std::string const& oldName,
  371. std::string const& newName)
  372. {
  373. // if the command already exists, free the old one
  374. std::string sOldName = cmSystemTools::LowerCase(oldName);
  375. std::string sNewName = cmSystemTools::LowerCase(newName);
  376. std::map<std::string, cmCommand*>::iterator pos =
  377. this->Commands.find(sOldName);
  378. if ( pos == this->Commands.end() )
  379. {
  380. return;
  381. }
  382. cmCommand* cmd = pos->second;
  383. pos = this->Commands.find(sNewName);
  384. if (pos != this->Commands.end())
  385. {
  386. delete pos->second;
  387. this->Commands.erase(pos);
  388. }
  389. this->Commands.insert(std::make_pair(sNewName, cmd));
  390. pos = this->Commands.find(sOldName);
  391. this->Commands.erase(pos);
  392. }
  393. void cmState::AddCommand(cmCommand* command)
  394. {
  395. std::string name = cmSystemTools::LowerCase(command->GetName());
  396. // if the command already exists, free the old one
  397. std::map<std::string, cmCommand*>::iterator pos = this->Commands.find(name);
  398. if (pos != this->Commands.end())
  399. {
  400. delete pos->second;
  401. this->Commands.erase(pos);
  402. }
  403. this->Commands.insert(std::make_pair(name, command));
  404. }
  405. void cmState::RemoveUnscriptableCommands()
  406. {
  407. std::vector<std::string> unscriptableCommands;
  408. for (std::map<std::string, cmCommand*>::iterator
  409. pos = this->Commands.begin();
  410. pos != this->Commands.end(); )
  411. {
  412. if (!pos->second->IsScriptable())
  413. {
  414. delete pos->second;
  415. this->Commands.erase(pos++);
  416. }
  417. else
  418. {
  419. ++pos;
  420. }
  421. }
  422. }
  423. cmCommand* cmState::GetCommand(std::string const& name) const
  424. {
  425. cmCommand* command = 0;
  426. std::string sName = cmSystemTools::LowerCase(name);
  427. std::map<std::string, cmCommand*>::const_iterator pos =
  428. this->Commands.find(sName);
  429. if (pos != this->Commands.end())
  430. {
  431. command = (*pos).second;
  432. }
  433. return command;
  434. }
  435. std::vector<std::string> cmState::GetCommandNames() const
  436. {
  437. std::vector<std::string> commandNames;
  438. commandNames.reserve(this->Commands.size());
  439. std::map<std::string, cmCommand*>::const_iterator cmds
  440. = this->Commands.begin();
  441. for ( ; cmds != this->Commands.end(); ++ cmds )
  442. {
  443. commandNames.push_back(cmds->first);
  444. }
  445. return commandNames;
  446. }
  447. void cmState::RemoveUserDefinedCommands()
  448. {
  449. std::vector<cmCommand*> renamedCommands;
  450. for(std::map<std::string, cmCommand*>::iterator j = this->Commands.begin();
  451. j != this->Commands.end(); )
  452. {
  453. if (j->second->IsA("cmMacroHelperCommand") ||
  454. j->second->IsA("cmFunctionHelperCommand"))
  455. {
  456. delete j->second;
  457. this->Commands.erase(j++);
  458. }
  459. else if (j->first != j->second->GetName())
  460. {
  461. renamedCommands.push_back(j->second);
  462. this->Commands.erase(j++);
  463. }
  464. else
  465. {
  466. ++j;
  467. }
  468. }
  469. for (std::vector<cmCommand*>::const_iterator it = renamedCommands.begin();
  470. it != renamedCommands.end(); ++it)
  471. {
  472. this->Commands[cmSystemTools::LowerCase((*it)->GetName())] = *it;
  473. }
  474. }
  475. void cmState::SetGlobalProperty(const std::string& prop, const char* value)
  476. {
  477. this->GlobalProperties.SetProperty(prop, value);
  478. }
  479. void cmState::AppendGlobalProperty(const std::string& prop,
  480. const char* value, bool asString)
  481. {
  482. this->GlobalProperties.AppendProperty(prop, value, asString);
  483. }
  484. const char *cmState::GetGlobalProperty(const std::string& prop)
  485. {
  486. if ( prop == "CACHE_VARIABLES" )
  487. {
  488. std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
  489. this->SetGlobalProperty("CACHE_VARIABLES", cmJoin(cacheKeys, ";").c_str());
  490. }
  491. else if ( prop == "COMMANDS" )
  492. {
  493. std::vector<std::string> commands = this->GetCommandNames();
  494. this->SetGlobalProperty("COMMANDS", cmJoin(commands, ";").c_str());
  495. }
  496. else if ( prop == "IN_TRY_COMPILE" )
  497. {
  498. this->SetGlobalProperty("IN_TRY_COMPILE",
  499. this->IsInTryCompile ? "1" : "0");
  500. }
  501. else if ( prop == "ENABLED_LANGUAGES" )
  502. {
  503. std::string langs;
  504. langs = cmJoin(this->EnabledLanguages, ";");
  505. this->SetGlobalProperty("ENABLED_LANGUAGES", langs.c_str());
  506. }
  507. #define STRING_LIST_ELEMENT(F) ";" #F
  508. if (prop == "CMAKE_C_KNOWN_FEATURES")
  509. {
  510. return FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT) + 1;
  511. }
  512. if (prop == "CMAKE_CXX_KNOWN_FEATURES")
  513. {
  514. return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
  515. }
  516. #undef STRING_LIST_ELEMENT
  517. return this->GlobalProperties.GetPropertyValue(prop);
  518. }
  519. bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
  520. {
  521. return cmSystemTools::IsOn(this->GetGlobalProperty(prop));
  522. }
  523. void cmState::SetSourceDirectory(std::string const& sourceDirectory)
  524. {
  525. this->SourceDirectory = sourceDirectory;
  526. cmSystemTools::ConvertToUnixSlashes(this->SourceDirectory);
  527. cmSystemTools::SplitPath(
  528. cmSystemTools::CollapseFullPath(this->SourceDirectory),
  529. this->SourceDirectoryComponents);
  530. }
  531. const char* cmState::GetSourceDirectory() const
  532. {
  533. return this->SourceDirectory.c_str();
  534. }
  535. std::vector<std::string> const& cmState::GetSourceDirectoryComponents() const
  536. {
  537. return this->SourceDirectoryComponents;
  538. }
  539. void cmState::SetBinaryDirectory(std::string const& binaryDirectory)
  540. {
  541. this->BinaryDirectory = binaryDirectory;
  542. cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory);
  543. cmSystemTools::SplitPath(
  544. cmSystemTools::CollapseFullPath(this->BinaryDirectory),
  545. this->BinaryDirectoryComponents);
  546. }
  547. void cmState::SetWindowsShell(bool windowsShell)
  548. {
  549. this->WindowsShell = windowsShell;
  550. }
  551. bool cmState::UseWindowsShell() const
  552. {
  553. return this->WindowsShell;
  554. }
  555. void cmState::SetWindowsVSIDE(bool windowsVSIDE)
  556. {
  557. this->WindowsVSIDE = windowsVSIDE;
  558. }
  559. bool cmState::UseWindowsVSIDE() const
  560. {
  561. return this->WindowsVSIDE;
  562. }
  563. void cmState::SetWatcomWMake(bool watcomWMake)
  564. {
  565. this->WatcomWMake = watcomWMake;
  566. }
  567. bool cmState::UseWatcomWMake() const
  568. {
  569. return this->WatcomWMake;
  570. }
  571. void cmState::SetMinGWMake(bool minGWMake)
  572. {
  573. this->MinGWMake = minGWMake;
  574. }
  575. bool cmState::UseMinGWMake() const
  576. {
  577. return this->MinGWMake;
  578. }
  579. void cmState::SetNMake(bool nMake)
  580. {
  581. this->NMake = nMake;
  582. }
  583. bool cmState::UseNMake() const
  584. {
  585. return this->NMake;
  586. }
  587. void cmState::SetMSYSShell(bool mSYSShell)
  588. {
  589. this->MSYSShell = mSYSShell;
  590. }
  591. bool cmState::UseMSYSShell() const
  592. {
  593. return this->MSYSShell;
  594. }
  595. unsigned int cmState::GetCacheMajorVersion() const
  596. {
  597. return this->CMakeInstance->GetCacheManager()->GetCacheMajorVersion();
  598. }
  599. unsigned int cmState::GetCacheMinorVersion() const
  600. {
  601. return this->CMakeInstance->GetCacheManager()->GetCacheMinorVersion();
  602. }
  603. const char* cmState::GetBinaryDirectory() const
  604. {
  605. return this->BinaryDirectory.c_str();
  606. }
  607. std::vector<std::string> const& cmState::GetBinaryDirectoryComponents() const
  608. {
  609. return this->BinaryDirectoryComponents;
  610. }
  611. void cmState::Directory::ComputeRelativePathTopSource()
  612. {
  613. // Relative path conversion inside the source tree is not used to
  614. // construct relative paths passed to build tools so it is safe to use
  615. // even when the source is a network path.
  616. cmState::Snapshot snapshot = this->Snapshot_;
  617. std::vector<cmState::Snapshot> snapshots;
  618. snapshots.push_back(snapshot);
  619. while (true)
  620. {
  621. snapshot = snapshot.GetBuildsystemDirectoryParent();
  622. if (snapshot.IsValid())
  623. {
  624. snapshots.push_back(snapshot);
  625. }
  626. else
  627. {
  628. break;
  629. }
  630. }
  631. std::string result = snapshots.front().GetDirectory().GetCurrentSource();
  632. for (std::vector<cmState::Snapshot>::const_iterator it =
  633. snapshots.begin() + 1; it != snapshots.end(); ++it)
  634. {
  635. std::string currentSource = it->GetDirectory().GetCurrentSource();
  636. if(cmSystemTools::IsSubDirectory(result, currentSource))
  637. {
  638. result = currentSource;
  639. }
  640. }
  641. this->DirectoryState->RelativePathTopSource = result;
  642. }
  643. void cmState::Directory::ComputeRelativePathTopBinary()
  644. {
  645. cmState::Snapshot snapshot = this->Snapshot_;
  646. std::vector<cmState::Snapshot> snapshots;
  647. snapshots.push_back(snapshot);
  648. while (true)
  649. {
  650. snapshot = snapshot.GetBuildsystemDirectoryParent();
  651. if (snapshot.IsValid())
  652. {
  653. snapshots.push_back(snapshot);
  654. }
  655. else
  656. {
  657. break;
  658. }
  659. }
  660. std::string result =
  661. snapshots.front().GetDirectory().GetCurrentBinary();
  662. for (std::vector<cmState::Snapshot>::const_iterator it =
  663. snapshots.begin() + 1; it != snapshots.end(); ++it)
  664. {
  665. std::string currentBinary = it->GetDirectory().GetCurrentBinary();
  666. if(cmSystemTools::IsSubDirectory(result, currentBinary))
  667. {
  668. result = currentBinary;
  669. }
  670. }
  671. // The current working directory on Windows cannot be a network
  672. // path. Therefore relative paths cannot work when the binary tree
  673. // is a network path.
  674. if(result.size() < 2 || result.substr(0, 2) != "//")
  675. {
  676. this->DirectoryState->RelativePathTopBinary = result;
  677. }
  678. else
  679. {
  680. this->DirectoryState->RelativePathTopBinary = "";
  681. }
  682. }
  683. cmState::Snapshot cmState::CreateBaseSnapshot()
  684. {
  685. PositionType pos = this->SnapshotData.Extend(this->SnapshotData.Root());
  686. pos->DirectoryParent = this->SnapshotData.Root();
  687. pos->ScopeParent = this->SnapshotData.Root();
  688. pos->SnapshotType = BaseType;
  689. pos->BuildSystemDirectory =
  690. this->BuildsystemDirectory.Extend(this->BuildsystemDirectory.Root());
  691. pos->ExecutionListFile =
  692. this->ExecutionListFiles.Extend(this->ExecutionListFiles.Root());
  693. pos->IncludeDirectoryPosition = 0;
  694. pos->CompileDefinitionsPosition = 0;
  695. pos->CompileOptionsPosition = 0;
  696. pos->BuildSystemDirectory->DirectoryEnd = pos;
  697. pos->Policies = this->PolicyStack.Root();
  698. pos->PolicyRoot = this->PolicyStack.Root();
  699. pos->PolicyScope = this->PolicyStack.Root();
  700. assert(pos->Policies.IsValid());
  701. assert(pos->PolicyRoot.IsValid());
  702. pos->Vars = this->VarTree.Extend(this->VarTree.Root());
  703. assert(pos->Vars.IsValid());
  704. pos->Parent = this->VarTree.Root();
  705. pos->Root = this->VarTree.Root();
  706. return cmState::Snapshot(this, pos);
  707. }
  708. cmState::Snapshot
  709. cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
  710. std::string const& entryPointCommand,
  711. long entryPointLine)
  712. {
  713. assert(originSnapshot.IsValid());
  714. PositionType pos = this->SnapshotData.Extend(originSnapshot.Position);
  715. pos->EntryPointLine = entryPointLine;
  716. pos->EntryPointCommand = entryPointCommand;
  717. pos->DirectoryParent = originSnapshot.Position;
  718. pos->ScopeParent = originSnapshot.Position;
  719. pos->SnapshotType = BuildsystemDirectoryType;
  720. pos->BuildSystemDirectory =
  721. this->BuildsystemDirectory.Extend(
  722. originSnapshot.Position->BuildSystemDirectory);
  723. pos->ExecutionListFile =
  724. this->ExecutionListFiles.Extend(
  725. originSnapshot.Position->ExecutionListFile);
  726. pos->BuildSystemDirectory->DirectoryEnd = pos;
  727. pos->Policies = originSnapshot.Position->Policies;
  728. pos->PolicyRoot = originSnapshot.Position->Policies;
  729. pos->PolicyScope = originSnapshot.Position->Policies;
  730. assert(pos->Policies.IsValid());
  731. assert(pos->PolicyRoot.IsValid());
  732. cmLinkedTree<cmDefinitions>::iterator origin =
  733. originSnapshot.Position->Vars;
  734. pos->Parent = origin;
  735. pos->Root = origin;
  736. pos->Vars = this->VarTree.Extend(origin);
  737. cmState::Snapshot snapshot = cmState::Snapshot(this, pos);
  738. originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
  739. snapshot.InitializeFromParent();
  740. return snapshot;
  741. }
  742. cmState::Snapshot
  743. cmState::CreateFunctionCallSnapshot(cmState::Snapshot originSnapshot,
  744. std::string const& entryPointCommand,
  745. long entryPointLine,
  746. std::string const& fileName)
  747. {
  748. PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
  749. *originSnapshot.Position);
  750. pos->ScopeParent = originSnapshot.Position;
  751. pos->EntryPointLine = entryPointLine;
  752. pos->EntryPointCommand = entryPointCommand;
  753. pos->SnapshotType = FunctionCallType;
  754. pos->ExecutionListFile = this->ExecutionListFiles.Extend(
  755. originSnapshot.Position->ExecutionListFile, fileName);
  756. pos->BuildSystemDirectory->DirectoryEnd = pos;
  757. pos->PolicyScope = originSnapshot.Position->Policies;
  758. assert(originSnapshot.Position->Vars.IsValid());
  759. cmLinkedTree<cmDefinitions>::iterator origin =
  760. originSnapshot.Position->Vars;
  761. pos->Parent = origin;
  762. pos->Vars = this->VarTree.Extend(origin);
  763. return cmState::Snapshot(this, pos);
  764. }
  765. cmState::Snapshot
  766. cmState::CreateMacroCallSnapshot(cmState::Snapshot originSnapshot,
  767. std::string const& entryPointCommand,
  768. long entryPointLine,
  769. std::string const& fileName)
  770. {
  771. PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
  772. *originSnapshot.Position);
  773. pos->EntryPointLine = entryPointLine;
  774. pos->EntryPointCommand = entryPointCommand;
  775. pos->SnapshotType = MacroCallType;
  776. pos->ExecutionListFile = this->ExecutionListFiles.Extend(
  777. originSnapshot.Position->ExecutionListFile, fileName);
  778. assert(originSnapshot.Position->Vars.IsValid());
  779. pos->BuildSystemDirectory->DirectoryEnd = pos;
  780. pos->PolicyScope = originSnapshot.Position->Policies;
  781. return cmState::Snapshot(this, pos);
  782. }
  783. cmState::Snapshot
  784. cmState::CreateCallStackSnapshot(cmState::Snapshot originSnapshot,
  785. const std::string& entryPointCommand,
  786. long entryPointLine,
  787. const std::string& fileName)
  788. {
  789. PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
  790. *originSnapshot.Position);
  791. pos->EntryPointLine = entryPointLine;
  792. pos->EntryPointCommand = entryPointCommand;
  793. pos->SnapshotType = CallStackType;
  794. pos->ExecutionListFile = this->ExecutionListFiles.Extend(
  795. originSnapshot.Position->ExecutionListFile, fileName);
  796. assert(originSnapshot.Position->Vars.IsValid());
  797. pos->BuildSystemDirectory->DirectoryEnd = pos;
  798. pos->PolicyScope = originSnapshot.Position->Policies;
  799. return cmState::Snapshot(this, pos);
  800. }
  801. cmState::Snapshot
  802. cmState::CreateVariableScopeSnapshot(cmState::Snapshot originSnapshot,
  803. std::string const& entryPointCommand,
  804. long entryPointLine)
  805. {
  806. PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
  807. *originSnapshot.Position);
  808. pos->ScopeParent = originSnapshot.Position;
  809. pos->EntryPointLine = entryPointLine;
  810. pos->EntryPointCommand = entryPointCommand;
  811. pos->SnapshotType = VariableScopeType;
  812. assert(originSnapshot.Position->Vars.IsValid());
  813. cmLinkedTree<cmDefinitions>::iterator origin =
  814. originSnapshot.Position->Vars;
  815. pos->Parent = origin;
  816. pos->Vars = this->VarTree.Extend(origin);
  817. assert(pos->Vars.IsValid());
  818. return cmState::Snapshot(this, pos);
  819. }
  820. cmState::Snapshot
  821. cmState::CreateInlineListFileSnapshot(cmState::Snapshot originSnapshot,
  822. const std::string& entryPointCommand,
  823. long entryPointLine,
  824. const std::string& fileName)
  825. {
  826. PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
  827. *originSnapshot.Position);
  828. pos->EntryPointLine = entryPointLine;
  829. pos->EntryPointCommand = entryPointCommand;
  830. pos->SnapshotType = InlineListFileType;
  831. pos->ExecutionListFile = this->ExecutionListFiles.Extend(
  832. originSnapshot.Position->ExecutionListFile, fileName);
  833. pos->BuildSystemDirectory->DirectoryEnd = pos;
  834. pos->PolicyScope = originSnapshot.Position->Policies;
  835. return cmState::Snapshot(this, pos);
  836. }
  837. cmState::Snapshot
  838. cmState::CreatePolicyScopeSnapshot(cmState::Snapshot originSnapshot)
  839. {
  840. PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
  841. *originSnapshot.Position);
  842. pos->SnapshotType = PolicyScopeType;
  843. pos->BuildSystemDirectory->DirectoryEnd = pos;
  844. pos->PolicyScope = originSnapshot.Position->Policies;
  845. return cmState::Snapshot(this, pos);
  846. }
  847. cmState::Snapshot cmState::Pop(cmState::Snapshot originSnapshot)
  848. {
  849. PositionType pos = originSnapshot.Position;
  850. PositionType prevPos = pos;
  851. ++prevPos;
  852. prevPos->IncludeDirectoryPosition =
  853. prevPos->BuildSystemDirectory->IncludeDirectories.size();
  854. prevPos->CompileDefinitionsPosition =
  855. prevPos->BuildSystemDirectory->CompileDefinitions.size();
  856. prevPos->CompileOptionsPosition =
  857. prevPos->BuildSystemDirectory->CompileOptions.size();
  858. prevPos->BuildSystemDirectory->DirectoryEnd = prevPos;
  859. return Snapshot(this, prevPos);
  860. }
  861. cmState::Snapshot::Snapshot(cmState* state)
  862. : State(state)
  863. , Position()
  864. {
  865. }
  866. std::vector<cmState::Snapshot> cmState::Snapshot::GetChildren()
  867. {
  868. return this->Position->BuildSystemDirectory->Children;
  869. }
  870. cmState::Snapshot::Snapshot(cmState* state, PositionType position)
  871. : State(state),
  872. Position(position)
  873. {
  874. }
  875. cmState::SnapshotType cmState::Snapshot::GetType() const
  876. {
  877. return this->Position->SnapshotType;
  878. }
  879. const char* cmState::Directory::GetCurrentSource() const
  880. {
  881. return this->DirectoryState->Location.c_str();
  882. }
  883. void cmState::Directory::SetCurrentSource(std::string const& dir)
  884. {
  885. std::string& loc = this->DirectoryState->Location;
  886. loc = dir;
  887. cmSystemTools::ConvertToUnixSlashes(loc);
  888. loc = cmSystemTools::CollapseFullPath(loc);
  889. cmSystemTools::SplitPath(
  890. loc,
  891. this->DirectoryState->CurrentSourceDirectoryComponents);
  892. this->ComputeRelativePathTopSource();
  893. }
  894. const char* cmState::Directory::GetCurrentBinary() const
  895. {
  896. return this->DirectoryState->OutputLocation.c_str();
  897. }
  898. void cmState::Directory::SetCurrentBinary(std::string const& dir)
  899. {
  900. std::string& loc = this->DirectoryState->OutputLocation;
  901. loc = dir;
  902. cmSystemTools::ConvertToUnixSlashes(loc);
  903. loc = cmSystemTools::CollapseFullPath(loc);
  904. cmSystemTools::SplitPath(
  905. loc,
  906. this->DirectoryState->CurrentBinaryDirectoryComponents);
  907. this->ComputeRelativePathTopBinary();
  908. }
  909. void cmState::Snapshot::SetListFile(const std::string& listfile)
  910. {
  911. *this->Position->ExecutionListFile = listfile;
  912. }
  913. std::vector<std::string> const&
  914. cmState::Directory::GetCurrentSourceComponents() const
  915. {
  916. return this->DirectoryState->CurrentSourceDirectoryComponents;
  917. }
  918. std::vector<std::string> const&
  919. cmState::Directory::GetCurrentBinaryComponents() const
  920. {
  921. return this->DirectoryState->CurrentBinaryDirectoryComponents;
  922. }
  923. const char* cmState::Directory::GetRelativePathTopSource() const
  924. {
  925. return this->DirectoryState->RelativePathTopSource.c_str();
  926. }
  927. const char* cmState::Directory::GetRelativePathTopBinary() const
  928. {
  929. return this->DirectoryState->RelativePathTopBinary.c_str();
  930. }
  931. void cmState::Directory::SetRelativePathTopSource(const char* dir)
  932. {
  933. this->DirectoryState->RelativePathTopSource = dir;
  934. }
  935. void cmState::Directory::SetRelativePathTopBinary(const char* dir)
  936. {
  937. this->DirectoryState->RelativePathTopBinary = dir;
  938. }
  939. std::string cmState::Snapshot::GetExecutionListFile() const
  940. {
  941. return *this->Position->ExecutionListFile;
  942. }
  943. std::string cmState::Snapshot::GetEntryPointCommand() const
  944. {
  945. return this->Position->EntryPointCommand;
  946. }
  947. long cmState::Snapshot::GetEntryPointLine() const
  948. {
  949. return this->Position->EntryPointLine;
  950. }
  951. bool cmState::Snapshot::IsValid() const
  952. {
  953. return this->State && this->Position.IsValid()
  954. ? this->Position != this->State->SnapshotData.Root()
  955. : false;
  956. }
  957. cmState::Snapshot cmState::Snapshot::GetBuildsystemDirectoryParent() const
  958. {
  959. Snapshot snapshot;
  960. if (!this->State || this->Position == this->State->SnapshotData.Root())
  961. {
  962. return snapshot;
  963. }
  964. PositionType parentPos = this->Position->DirectoryParent;
  965. if (parentPos != this->State->SnapshotData.Root())
  966. {
  967. snapshot = Snapshot(this->State,
  968. parentPos->BuildSystemDirectory->DirectoryEnd);
  969. }
  970. return snapshot;
  971. }
  972. cmState::Snapshot cmState::Snapshot::GetCallStackParent() const
  973. {
  974. assert(this->State);
  975. assert(this->Position != this->State->SnapshotData.Root());
  976. Snapshot snapshot;
  977. PositionType parentPos = this->Position;
  978. while(parentPos->SnapshotType == cmState::PolicyScopeType)
  979. {
  980. ++parentPos;
  981. }
  982. if (parentPos->SnapshotType == cmState::BuildsystemDirectoryType
  983. || parentPos->SnapshotType == cmState::BaseType)
  984. {
  985. return snapshot;
  986. }
  987. ++parentPos;
  988. while(parentPos->SnapshotType == cmState::PolicyScopeType)
  989. {
  990. ++parentPos;
  991. }
  992. if (parentPos == this->State->SnapshotData.Root())
  993. {
  994. return snapshot;
  995. }
  996. snapshot = Snapshot(this->State, parentPos);
  997. return snapshot;
  998. }
  999. void cmState::Snapshot::PushPolicy(cmPolicies::PolicyMap entry, bool weak)
  1000. {
  1001. PositionType pos = this->Position;
  1002. pos->Policies =
  1003. this->State->PolicyStack.Extend(pos->Policies,
  1004. PolicyStackEntry(entry, weak));
  1005. }
  1006. bool cmState::Snapshot::PopPolicy()
  1007. {
  1008. PositionType pos = this->Position;
  1009. if (pos->Policies == pos->PolicyScope)
  1010. {
  1011. return false;
  1012. }
  1013. ++pos->Policies;
  1014. return true;
  1015. }
  1016. bool cmState::Snapshot::CanPopPolicyScope()
  1017. {
  1018. return this->Position->Policies == this->Position->PolicyScope;
  1019. }
  1020. void cmState::Snapshot::SetPolicy(cmPolicies::PolicyID id,
  1021. cmPolicies::PolicyStatus status)
  1022. {
  1023. // Update the policy stack from the top to the top-most strong entry.
  1024. bool previous_was_weak = true;
  1025. for(cmLinkedTree<PolicyStackEntry>::iterator psi = this->Position->Policies;
  1026. previous_was_weak && psi != this->Position->PolicyRoot; ++psi)
  1027. {
  1028. psi->Set(id, status);
  1029. previous_was_weak = psi->Weak;
  1030. }
  1031. }
  1032. cmPolicies::PolicyStatus
  1033. cmState::Snapshot::GetPolicy(cmPolicies::PolicyID id) const
  1034. {
  1035. cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id);
  1036. if(status == cmPolicies::REQUIRED_ALWAYS ||
  1037. status == cmPolicies::REQUIRED_IF_USED)
  1038. {
  1039. return status;
  1040. }
  1041. cmLinkedTree<BuildsystemDirectoryStateType>::iterator dir =
  1042. this->Position->BuildSystemDirectory;
  1043. while (true)
  1044. {
  1045. assert(dir.IsValid());
  1046. cmLinkedTree<PolicyStackEntry>::iterator leaf =
  1047. dir->DirectoryEnd->Policies;
  1048. cmLinkedTree<PolicyStackEntry>::iterator root =
  1049. dir->DirectoryEnd->PolicyRoot;
  1050. for( ; leaf != root; ++leaf)
  1051. {
  1052. if(leaf->IsDefined(id))
  1053. {
  1054. status = leaf->Get(id);
  1055. return status;
  1056. }
  1057. }
  1058. cmState::PositionType e = dir->DirectoryEnd;
  1059. cmState::PositionType p = e->DirectoryParent;
  1060. if (p == this->State->SnapshotData.Root())
  1061. {
  1062. break;
  1063. }
  1064. dir = p->BuildSystemDirectory;
  1065. }
  1066. return status;
  1067. }
  1068. bool cmState::Snapshot::HasDefinedPolicyCMP0011()
  1069. {
  1070. return !this->Position->Policies->IsEmpty();
  1071. }
  1072. const char* cmState::Snapshot::GetDefinition(std::string const& name) const
  1073. {
  1074. assert(this->Position->Vars.IsValid());
  1075. return cmDefinitions::Get(name, this->Position->Vars,
  1076. this->Position->Root);
  1077. }
  1078. bool cmState::Snapshot::IsInitialized(std::string const& name) const
  1079. {
  1080. return cmDefinitions::HasKey(name, this->Position->Vars,
  1081. this->Position->Root);
  1082. }
  1083. void cmState::Snapshot::SetDefinition(std::string const& name,
  1084. std::string const& value)
  1085. {
  1086. this->Position->Vars->Set(name, value.c_str());
  1087. }
  1088. void cmState::Snapshot::RemoveDefinition(std::string const& name)
  1089. {
  1090. this->Position->Vars->Set(name, 0);
  1091. }
  1092. std::vector<std::string> cmState::Snapshot::UnusedKeys() const
  1093. {
  1094. return this->Position->Vars->UnusedKeys();
  1095. }
  1096. std::vector<std::string> cmState::Snapshot::ClosureKeys() const
  1097. {
  1098. return cmDefinitions::ClosureKeys(this->Position->Vars,
  1099. this->Position->Root);
  1100. }
  1101. bool cmState::Snapshot::RaiseScope(std::string const& var, const char* varDef)
  1102. {
  1103. if(this->Position->ScopeParent == this->Position->DirectoryParent)
  1104. {
  1105. Snapshot parentDir = this->GetBuildsystemDirectoryParent();
  1106. if(!parentDir.IsValid())
  1107. {
  1108. return false;
  1109. }
  1110. // Update the definition in the parent directory top scope. This
  1111. // directory's scope was initialized by the closure of the parent
  1112. // scope, so we do not need to localize the definition first.
  1113. if (varDef)
  1114. {
  1115. parentDir.SetDefinition(var, varDef);
  1116. }
  1117. else
  1118. {
  1119. parentDir.RemoveDefinition(var);
  1120. }
  1121. return true;
  1122. }
  1123. // First localize the definition in the current scope.
  1124. cmDefinitions::Raise(var, this->Position->Vars,
  1125. this->Position->Root);
  1126. // Now update the definition in the parent scope.
  1127. this->Position->Parent->Set(var, varDef);
  1128. return true;
  1129. }
  1130. static const std::string cmPropertySentinal = std::string();
  1131. template<typename T, typename U, typename V>
  1132. void InitializeContentFromParent(T& parentContent,
  1133. T& thisContent,
  1134. U& parentBacktraces,
  1135. U& thisBacktraces,
  1136. V& contentEndPosition)
  1137. {
  1138. std::vector<std::string>::const_iterator parentBegin =
  1139. parentContent.begin();
  1140. std::vector<std::string>::const_iterator parentEnd =
  1141. parentContent.end();
  1142. std::vector<std::string>::const_reverse_iterator parentRbegin =
  1143. cmMakeReverseIterator(parentEnd);
  1144. std::vector<std::string>::const_reverse_iterator parentRend =
  1145. parentContent.rend();
  1146. parentRbegin = std::find(parentRbegin, parentRend, cmPropertySentinal);
  1147. std::vector<std::string>::const_iterator parentIt = parentRbegin.base();
  1148. thisContent = std::vector<std::string>(parentIt, parentEnd);
  1149. std::vector<cmListFileBacktrace>::const_iterator btIt =
  1150. parentBacktraces.begin() + std::distance(parentBegin, parentIt);
  1151. std::vector<cmListFileBacktrace>::const_iterator btEnd =
  1152. parentBacktraces.end();
  1153. thisBacktraces = std::vector<cmListFileBacktrace>(btIt, btEnd);
  1154. contentEndPosition = thisContent.size();
  1155. }
  1156. void cmState::Snapshot::InitializeFromParent()
  1157. {
  1158. PositionType parent = this->Position->DirectoryParent;
  1159. assert(this->Position->Vars.IsValid());
  1160. assert(parent->Vars.IsValid());
  1161. *this->Position->Vars =
  1162. cmDefinitions::MakeClosure(parent->Vars, parent->Root);
  1163. InitializeContentFromParent(parent->BuildSystemDirectory->IncludeDirectories,
  1164. this->Position->BuildSystemDirectory->IncludeDirectories,
  1165. parent->BuildSystemDirectory->IncludeDirectoryBacktraces,
  1166. this->Position->BuildSystemDirectory->IncludeDirectoryBacktraces,
  1167. this->Position->IncludeDirectoryPosition);
  1168. InitializeContentFromParent(parent->BuildSystemDirectory->CompileDefinitions,
  1169. this->Position->BuildSystemDirectory->CompileDefinitions,
  1170. parent->BuildSystemDirectory->CompileDefinitionsBacktraces,
  1171. this->Position->BuildSystemDirectory->CompileDefinitionsBacktraces,
  1172. this->Position->CompileDefinitionsPosition);
  1173. InitializeContentFromParent(parent->BuildSystemDirectory->CompileOptions,
  1174. this->Position->BuildSystemDirectory->CompileOptions,
  1175. parent->BuildSystemDirectory->CompileOptionsBacktraces,
  1176. this->Position->BuildSystemDirectory->CompileOptionsBacktraces,
  1177. this->Position->CompileOptionsPosition);
  1178. }
  1179. cmState* cmState::Snapshot::GetState() const
  1180. {
  1181. return this->State;
  1182. }
  1183. cmState::Directory cmState::Snapshot::GetDirectory() const
  1184. {
  1185. return Directory(this->Position->BuildSystemDirectory, *this);
  1186. }
  1187. void cmState::Snapshot::SetProjectName(const std::string& name)
  1188. {
  1189. this->Position->BuildSystemDirectory->ProjectName = name;
  1190. }
  1191. std::string cmState::Snapshot::GetProjectName() const
  1192. {
  1193. return this->Position->BuildSystemDirectory->ProjectName;
  1194. }
  1195. cmState::Directory::Directory(
  1196. cmLinkedTree<BuildsystemDirectoryStateType>::iterator iter,
  1197. const cmState::Snapshot& snapshot)
  1198. : DirectoryState(iter), Snapshot_(snapshot)
  1199. {
  1200. }
  1201. template <typename T, typename U>
  1202. cmStringRange GetPropertyContent(T const& content, U contentEndPosition)
  1203. {
  1204. std::vector<std::string>::const_iterator end =
  1205. content.begin() + contentEndPosition;
  1206. std::vector<std::string>::const_reverse_iterator rbegin =
  1207. cmMakeReverseIterator(end);
  1208. rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
  1209. return cmMakeRange(rbegin.base(), end);
  1210. }
  1211. template <typename T, typename U, typename V>
  1212. cmBacktraceRange GetPropertyBacktraces(T const& content,
  1213. U const& backtraces,
  1214. V contentEndPosition)
  1215. {
  1216. std::vector<std::string>::const_iterator entryEnd =
  1217. content.begin() + contentEndPosition;
  1218. std::vector<std::string>::const_reverse_iterator rbegin =
  1219. cmMakeReverseIterator(entryEnd);
  1220. rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
  1221. std::vector<cmListFileBacktrace>::const_iterator it =
  1222. backtraces.begin() + std::distance(content.begin(), rbegin.base());
  1223. std::vector<cmListFileBacktrace>::const_iterator end = backtraces.end();
  1224. return cmMakeRange(it, end);
  1225. }
  1226. template <typename T, typename U, typename V>
  1227. void AppendEntry(T& content, U& backtraces, V& endContentPosition,
  1228. const std::string& value, const cmListFileBacktrace& lfbt)
  1229. {
  1230. if (value.empty())
  1231. {
  1232. return;
  1233. }
  1234. assert(endContentPosition == content.size());
  1235. content.push_back(value);
  1236. backtraces.push_back(lfbt);
  1237. endContentPosition = content.size();
  1238. }
  1239. template <typename T, typename U, typename V>
  1240. void SetContent(T& content, U& backtraces, V& endContentPosition,
  1241. const std::string& vec, const cmListFileBacktrace& lfbt)
  1242. {
  1243. assert(endContentPosition == content.size());
  1244. content.resize(content.size() + 2);
  1245. backtraces.resize(backtraces.size() + 2);
  1246. content.back() = vec;
  1247. backtraces.back() = lfbt;
  1248. endContentPosition = content.size();
  1249. }
  1250. template <typename T, typename U, typename V>
  1251. void ClearContent(T& content, U& backtraces, V& endContentPosition)
  1252. {
  1253. assert(endContentPosition == content.size());
  1254. content.resize(content.size() + 1);
  1255. backtraces.resize(backtraces.size() + 1);
  1256. endContentPosition = content.size();
  1257. }
  1258. cmStringRange
  1259. cmState::Directory::GetIncludeDirectoriesEntries() const
  1260. {
  1261. return GetPropertyContent(this->DirectoryState->IncludeDirectories,
  1262. this->Snapshot_.Position->IncludeDirectoryPosition);
  1263. }
  1264. cmBacktraceRange
  1265. cmState::Directory::GetIncludeDirectoriesEntryBacktraces() const
  1266. {
  1267. return GetPropertyBacktraces(this->DirectoryState->IncludeDirectories,
  1268. this->DirectoryState->IncludeDirectoryBacktraces,
  1269. this->Snapshot_.Position->IncludeDirectoryPosition);
  1270. }
  1271. void cmState::Directory::AppendIncludeDirectoriesEntry(
  1272. const std::string& vec, const cmListFileBacktrace& lfbt)
  1273. {
  1274. AppendEntry(this->DirectoryState->IncludeDirectories,
  1275. this->DirectoryState->IncludeDirectoryBacktraces,
  1276. this->Snapshot_.Position->IncludeDirectoryPosition,
  1277. vec, lfbt);
  1278. }
  1279. void cmState::Directory::PrependIncludeDirectoriesEntry(
  1280. const std::string& vec, const cmListFileBacktrace& lfbt)
  1281. {
  1282. std::vector<std::string>::iterator entryEnd =
  1283. this->DirectoryState->IncludeDirectories.begin()
  1284. + this->Snapshot_.Position->IncludeDirectoryPosition;
  1285. std::vector<std::string>::reverse_iterator rend =
  1286. this->DirectoryState->IncludeDirectories.rend();
  1287. std::vector<std::string>::reverse_iterator rbegin =
  1288. cmMakeReverseIterator(entryEnd);
  1289. rbegin = std::find(rbegin, rend, cmPropertySentinal);
  1290. std::vector<std::string>::iterator entryIt = rbegin.base();
  1291. std::vector<std::string>::iterator entryBegin =
  1292. this->DirectoryState->IncludeDirectories.begin();
  1293. std::vector<cmListFileBacktrace>::iterator btIt =
  1294. this->DirectoryState->IncludeDirectoryBacktraces.begin()
  1295. + std::distance(entryBegin, entryIt);
  1296. this->DirectoryState->IncludeDirectories.insert(entryIt, vec);
  1297. this->DirectoryState->IncludeDirectoryBacktraces.insert(btIt, lfbt);
  1298. this->Snapshot_.Position->IncludeDirectoryPosition =
  1299. this->DirectoryState->IncludeDirectories.size();
  1300. }
  1301. void cmState::Directory::SetIncludeDirectories(
  1302. const std::string& vec, const cmListFileBacktrace& lfbt)
  1303. {
  1304. SetContent(this->DirectoryState->IncludeDirectories,
  1305. this->DirectoryState->IncludeDirectoryBacktraces,
  1306. this->Snapshot_.Position->IncludeDirectoryPosition,
  1307. vec, lfbt);
  1308. }
  1309. void cmState::Directory::ClearIncludeDirectories()
  1310. {
  1311. ClearContent(this->DirectoryState->IncludeDirectories,
  1312. this->DirectoryState->IncludeDirectoryBacktraces,
  1313. this->Snapshot_.Position->IncludeDirectoryPosition);
  1314. }
  1315. cmStringRange cmState::Directory::GetCompileDefinitionsEntries() const
  1316. {
  1317. return GetPropertyContent(this->DirectoryState->CompileDefinitions,
  1318. this->Snapshot_.Position->CompileDefinitionsPosition);
  1319. }
  1320. cmBacktraceRange
  1321. cmState::Directory::GetCompileDefinitionsEntryBacktraces() const
  1322. {
  1323. return GetPropertyBacktraces(this->DirectoryState->CompileDefinitions,
  1324. this->DirectoryState->CompileDefinitionsBacktraces,
  1325. this->Snapshot_.Position->CompileDefinitionsPosition);
  1326. }
  1327. void cmState::Directory::AppendCompileDefinitionsEntry(const std::string& vec,
  1328. const cmListFileBacktrace& lfbt)
  1329. {
  1330. AppendEntry(this->DirectoryState->CompileDefinitions,
  1331. this->DirectoryState->CompileDefinitionsBacktraces,
  1332. this->Snapshot_.Position->CompileDefinitionsPosition,
  1333. vec, lfbt);
  1334. }
  1335. void cmState::Directory::SetCompileDefinitions(const std::string& vec,
  1336. const cmListFileBacktrace& lfbt)
  1337. {
  1338. SetContent(this->DirectoryState->CompileDefinitions,
  1339. this->DirectoryState->CompileDefinitionsBacktraces,
  1340. this->Snapshot_.Position->CompileDefinitionsPosition,
  1341. vec, lfbt);
  1342. }
  1343. void cmState::Directory::ClearCompileDefinitions()
  1344. {
  1345. ClearContent(this->DirectoryState->CompileDefinitions,
  1346. this->DirectoryState->CompileDefinitionsBacktraces,
  1347. this->Snapshot_.Position->CompileDefinitionsPosition);
  1348. }
  1349. cmStringRange cmState::Directory::GetCompileOptionsEntries() const
  1350. {
  1351. return GetPropertyContent(this->DirectoryState->CompileOptions,
  1352. this->Snapshot_.Position->CompileOptionsPosition);
  1353. }
  1354. cmBacktraceRange cmState::Directory::GetCompileOptionsEntryBacktraces() const
  1355. {
  1356. return GetPropertyBacktraces(this->DirectoryState->CompileOptions,
  1357. this->DirectoryState->CompileOptionsBacktraces,
  1358. this->Snapshot_.Position->CompileOptionsPosition);
  1359. }
  1360. void
  1361. cmState::Directory::AppendCompileOptionsEntry(const std::string& vec,
  1362. const cmListFileBacktrace& lfbt)
  1363. {
  1364. AppendEntry(this->DirectoryState->CompileOptions,
  1365. this->DirectoryState->CompileOptionsBacktraces,
  1366. this->Snapshot_.Position->CompileOptionsPosition,
  1367. vec, lfbt);
  1368. }
  1369. void cmState::Directory::SetCompileOptions(const std::string& vec,
  1370. const cmListFileBacktrace& lfbt)
  1371. {
  1372. SetContent(this->DirectoryState->CompileOptions,
  1373. this->DirectoryState->CompileOptionsBacktraces,
  1374. this->Snapshot_.Position->CompileOptionsPosition,
  1375. vec, lfbt);
  1376. }
  1377. void cmState::Directory::ClearCompileOptions()
  1378. {
  1379. ClearContent(this->DirectoryState->CompileOptions,
  1380. this->DirectoryState->CompileOptionsBacktraces,
  1381. this->Snapshot_.Position->CompileOptionsPosition);
  1382. }
  1383. bool cmState::Snapshot::StrictWeakOrder::operator()(
  1384. const cmState::Snapshot& lhs, const cmState::Snapshot& rhs) const
  1385. {
  1386. return lhs.Position.StrictWeakOrdered(rhs.Position);
  1387. }
  1388. void cmState::Directory::SetProperty(const std::string& prop,
  1389. const char* value,
  1390. cmListFileBacktrace lfbt)
  1391. {
  1392. if (prop == "INCLUDE_DIRECTORIES")
  1393. {
  1394. if (!value)
  1395. {
  1396. this->ClearIncludeDirectories();
  1397. return;
  1398. }
  1399. this->SetIncludeDirectories(value, lfbt);
  1400. return;
  1401. }
  1402. if (prop == "COMPILE_OPTIONS")
  1403. {
  1404. if (!value)
  1405. {
  1406. this->ClearCompileOptions();
  1407. return;
  1408. }
  1409. this->SetCompileOptions(value, lfbt);
  1410. return;
  1411. }
  1412. if (prop == "COMPILE_DEFINITIONS")
  1413. {
  1414. if (!value)
  1415. {
  1416. this->ClearCompileDefinitions();
  1417. return;
  1418. }
  1419. this->SetCompileDefinitions(value, lfbt);
  1420. return;
  1421. }
  1422. this->DirectoryState->Properties.SetProperty(prop, value);
  1423. }
  1424. void cmState::Directory::AppendProperty(const std::string& prop,
  1425. const char* value,
  1426. bool asString,
  1427. cmListFileBacktrace lfbt)
  1428. {
  1429. if (prop == "INCLUDE_DIRECTORIES")
  1430. {
  1431. this->AppendIncludeDirectoriesEntry(value, lfbt);
  1432. return;
  1433. }
  1434. if (prop == "COMPILE_OPTIONS")
  1435. {
  1436. this->AppendCompileOptionsEntry(value, lfbt);
  1437. return;
  1438. }
  1439. if (prop == "COMPILE_DEFINITIONS")
  1440. {
  1441. this->AppendCompileDefinitionsEntry(value, lfbt);
  1442. return;
  1443. }
  1444. this->DirectoryState->Properties.AppendProperty(prop, value, asString);
  1445. }
  1446. const char*cmState::Directory::GetProperty(const std::string& prop) const
  1447. {
  1448. const bool chain = this->Snapshot_.State->
  1449. IsPropertyChained(prop, cmProperty::DIRECTORY);
  1450. return this->GetProperty(prop, chain);
  1451. }
  1452. const char*
  1453. cmState::Directory::GetProperty(const std::string& prop, bool chain) const
  1454. {
  1455. static std::string output;
  1456. output = "";
  1457. if (prop == "PARENT_DIRECTORY")
  1458. {
  1459. cmState::Snapshot parent =
  1460. this->Snapshot_.GetBuildsystemDirectoryParent();
  1461. if(parent.IsValid())
  1462. {
  1463. return parent.GetDirectory().GetCurrentSource();
  1464. }
  1465. return "";
  1466. }
  1467. else if (prop == "LISTFILE_STACK")
  1468. {
  1469. std::vector<std::string> listFiles;
  1470. cmState::Snapshot snp = this->Snapshot_;
  1471. while (snp.IsValid())
  1472. {
  1473. listFiles.push_back(snp.GetExecutionListFile());
  1474. snp = snp.GetCallStackParent();
  1475. }
  1476. std::reverse(listFiles.begin(), listFiles.end());
  1477. output = cmJoin(listFiles, ";");
  1478. return output.c_str();
  1479. }
  1480. else if ( prop == "CACHE_VARIABLES" )
  1481. {
  1482. output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
  1483. return output.c_str();
  1484. }
  1485. else if (prop == "VARIABLES")
  1486. {
  1487. std::vector<std::string> res = this->Snapshot_.ClosureKeys();
  1488. std::vector<std::string> cacheKeys =
  1489. this->Snapshot_.State->GetCacheEntryKeys();
  1490. res.insert(res.end(), cacheKeys.begin(), cacheKeys.end());
  1491. std::sort(res.begin(), res.end());
  1492. output = cmJoin(res, ";");
  1493. return output.c_str();
  1494. }
  1495. else if (prop == "INCLUDE_DIRECTORIES")
  1496. {
  1497. output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
  1498. return output.c_str();
  1499. }
  1500. else if (prop == "COMPILE_OPTIONS")
  1501. {
  1502. output = cmJoin(this->GetCompileOptionsEntries(), ";");
  1503. return output.c_str();
  1504. }
  1505. else if (prop == "COMPILE_DEFINITIONS")
  1506. {
  1507. output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
  1508. return output.c_str();
  1509. }
  1510. const char *retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
  1511. if (!retVal && chain)
  1512. {
  1513. Snapshot parentSnapshot = this->Snapshot_.GetBuildsystemDirectoryParent();
  1514. if (parentSnapshot.IsValid())
  1515. {
  1516. return parentSnapshot.GetDirectory().GetProperty(prop, chain);
  1517. }
  1518. return this->Snapshot_.State->GetGlobalProperty(prop);
  1519. }
  1520. return retVal;
  1521. }
  1522. bool cmState::Directory::GetPropertyAsBool(const std::string& prop) const
  1523. {
  1524. return cmSystemTools::IsOn(this->GetProperty(prop));
  1525. }
  1526. std::vector<std::string> cmState::Directory::GetPropertyKeys() const
  1527. {
  1528. std::vector<std::string> keys;
  1529. keys.reserve(this->DirectoryState->Properties.size());
  1530. for(cmPropertyMap::const_iterator it =
  1531. this->DirectoryState->Properties.begin();
  1532. it != this->DirectoryState->Properties.end(); ++it)
  1533. {
  1534. keys.push_back(it->first);
  1535. }
  1536. return keys;
  1537. }
  1538. bool operator==(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs)
  1539. {
  1540. return lhs.Position == rhs.Position;
  1541. }
  1542. bool operator!=(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs)
  1543. {
  1544. return lhs.Position != rhs.Position;
  1545. }
  1546. static bool ParseEntryWithoutType(const std::string& entry,
  1547. std::string& var,
  1548. std::string& value)
  1549. {
  1550. // input line is: key=value
  1551. static cmsys::RegularExpression reg(
  1552. "^([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  1553. // input line is: "key"=value
  1554. static cmsys::RegularExpression regQuoted(
  1555. "^\"([^\"]*)\"=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  1556. bool flag = false;
  1557. if(regQuoted.find(entry))
  1558. {
  1559. var = regQuoted.match(1);
  1560. value = regQuoted.match(2);
  1561. flag = true;
  1562. }
  1563. else if (reg.find(entry))
  1564. {
  1565. var = reg.match(1);
  1566. value = reg.match(2);
  1567. flag = true;
  1568. }
  1569. // if value is enclosed in single quotes ('foo') then remove them
  1570. // it is used to enclose trailing space or tab
  1571. if (flag &&
  1572. value.size() >= 2 &&
  1573. value[0] == '\'' &&
  1574. value[value.size() - 1] == '\'')
  1575. {
  1576. value = value.substr(1,
  1577. value.size() - 2);
  1578. }
  1579. return flag;
  1580. }
  1581. bool cmState::ParseCacheEntry(const std::string& entry,
  1582. std::string& var,
  1583. std::string& value,
  1584. CacheEntryType& type)
  1585. {
  1586. // input line is: key:type=value
  1587. static cmsys::RegularExpression reg(
  1588. "^([^=:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  1589. // input line is: "key":type=value
  1590. static cmsys::RegularExpression regQuoted(
  1591. "^\"([^\"]*)\":([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  1592. bool flag = false;
  1593. if(regQuoted.find(entry))
  1594. {
  1595. var = regQuoted.match(1);
  1596. type = cmState::StringToCacheEntryType(regQuoted.match(2).c_str());
  1597. value = regQuoted.match(3);
  1598. flag = true;
  1599. }
  1600. else if (reg.find(entry))
  1601. {
  1602. var = reg.match(1);
  1603. type = cmState::StringToCacheEntryType(reg.match(2).c_str());
  1604. value = reg.match(3);
  1605. flag = true;
  1606. }
  1607. // if value is enclosed in single quotes ('foo') then remove them
  1608. // it is used to enclose trailing space or tab
  1609. if (flag &&
  1610. value.size() >= 2 &&
  1611. value[0] == '\'' &&
  1612. value[value.size() - 1] == '\'')
  1613. {
  1614. value = value.substr(1,
  1615. value.size() - 2);
  1616. }
  1617. if (!flag)
  1618. {
  1619. return ParseEntryWithoutType(entry, var, value);
  1620. }
  1621. return flag;
  1622. }