cmStateDirectory.cxx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmStateDirectory.h"
  4. #include <algorithm>
  5. #include <cassert>
  6. #include <vector>
  7. #include <cm/iterator>
  8. #include <cm/string_view>
  9. #include <cmext/algorithm>
  10. #include <cmext/string_view>
  11. #include "cmAlgorithms.h"
  12. #include "cmProperty.h"
  13. #include "cmPropertyMap.h"
  14. #include "cmRange.h"
  15. #include "cmState.h"
  16. #include "cmStatePrivate.h"
  17. #include "cmStateTypes.h"
  18. #include "cmSystemTools.h"
  19. static std::string const kBINARY_DIR = "BINARY_DIR";
  20. static std::string const kBUILDSYSTEM_TARGETS = "BUILDSYSTEM_TARGETS";
  21. static std::string const kSOURCE_DIR = "SOURCE_DIR";
  22. static std::string const kSUBDIRECTORIES = "SUBDIRECTORIES";
  23. std::string const& cmStateDirectory::GetCurrentSource() const
  24. {
  25. return this->DirectoryState->Location;
  26. }
  27. void cmStateDirectory::SetCurrentSource(std::string const& dir)
  28. {
  29. std::string& loc = this->DirectoryState->Location;
  30. loc = dir;
  31. cmSystemTools::ConvertToUnixSlashes(loc);
  32. loc = cmSystemTools::CollapseFullPath(loc);
  33. this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc);
  34. }
  35. std::string const& cmStateDirectory::GetCurrentBinary() const
  36. {
  37. return this->DirectoryState->OutputLocation;
  38. }
  39. void cmStateDirectory::SetCurrentBinary(std::string const& dir)
  40. {
  41. std::string& loc = this->DirectoryState->OutputLocation;
  42. loc = dir;
  43. cmSystemTools::ConvertToUnixSlashes(loc);
  44. loc = cmSystemTools::CollapseFullPath(loc);
  45. this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc);
  46. }
  47. cmStateDirectory::cmStateDirectory(
  48. cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator iter,
  49. const cmStateSnapshot& snapshot)
  50. : DirectoryState(iter)
  51. , Snapshot_(snapshot)
  52. {
  53. }
  54. template <typename T, typename U>
  55. cmStringRange GetPropertyContent(T const& content, U contentEndPosition)
  56. {
  57. auto end = content.begin() + contentEndPosition;
  58. auto rbegin = cm::make_reverse_iterator(end);
  59. rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
  60. return cmMakeRange(rbegin.base(), end);
  61. }
  62. template <typename T, typename U, typename V>
  63. cmBacktraceRange GetPropertyBacktraces(T const& content, U const& backtraces,
  64. V contentEndPosition)
  65. {
  66. auto entryEnd = content.begin() + contentEndPosition;
  67. auto rbegin = cm::make_reverse_iterator(entryEnd);
  68. rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
  69. auto it = backtraces.begin() + std::distance(content.begin(), rbegin.base());
  70. auto end = backtraces.end();
  71. return cmMakeRange(it, end);
  72. }
  73. template <typename T, typename U, typename V>
  74. void AppendEntry(T& content, U& backtraces, V& endContentPosition,
  75. const std::string& value, const cmListFileBacktrace& lfbt)
  76. {
  77. if (value.empty()) {
  78. return;
  79. }
  80. assert(endContentPosition == content.size());
  81. content.push_back(value);
  82. backtraces.push_back(lfbt);
  83. endContentPosition = content.size();
  84. }
  85. template <typename T, typename U, typename V>
  86. void SetContent(T& content, U& backtraces, V& endContentPosition,
  87. const std::string& vec, const cmListFileBacktrace& lfbt)
  88. {
  89. assert(endContentPosition == content.size());
  90. content.resize(content.size() + 2);
  91. backtraces.resize(backtraces.size() + 2);
  92. content.back() = vec;
  93. backtraces.back() = lfbt;
  94. endContentPosition = content.size();
  95. }
  96. template <typename T, typename U, typename V>
  97. void ClearContent(T& content, U& backtraces, V& endContentPosition)
  98. {
  99. assert(endContentPosition == content.size());
  100. content.resize(content.size() + 1);
  101. backtraces.resize(backtraces.size() + 1);
  102. endContentPosition = content.size();
  103. }
  104. cmStringRange cmStateDirectory::GetIncludeDirectoriesEntries() const
  105. {
  106. return GetPropertyContent(
  107. this->DirectoryState->IncludeDirectories,
  108. this->Snapshot_.Position->IncludeDirectoryPosition);
  109. }
  110. cmBacktraceRange cmStateDirectory::GetIncludeDirectoriesEntryBacktraces() const
  111. {
  112. return GetPropertyBacktraces(
  113. this->DirectoryState->IncludeDirectories,
  114. this->DirectoryState->IncludeDirectoryBacktraces,
  115. this->Snapshot_.Position->IncludeDirectoryPosition);
  116. }
  117. void cmStateDirectory::AppendIncludeDirectoriesEntry(
  118. const std::string& vec, const cmListFileBacktrace& lfbt)
  119. {
  120. AppendEntry(this->DirectoryState->IncludeDirectories,
  121. this->DirectoryState->IncludeDirectoryBacktraces,
  122. this->Snapshot_.Position->IncludeDirectoryPosition, vec, lfbt);
  123. }
  124. void cmStateDirectory::PrependIncludeDirectoriesEntry(
  125. const std::string& vec, const cmListFileBacktrace& lfbt)
  126. {
  127. auto entryEnd = this->DirectoryState->IncludeDirectories.begin() +
  128. this->Snapshot_.Position->IncludeDirectoryPosition;
  129. auto rend = this->DirectoryState->IncludeDirectories.rend();
  130. auto rbegin = cm::make_reverse_iterator(entryEnd);
  131. rbegin = std::find(rbegin, rend, cmPropertySentinal);
  132. auto entryIt = rbegin.base();
  133. auto entryBegin = this->DirectoryState->IncludeDirectories.begin();
  134. auto btIt = this->DirectoryState->IncludeDirectoryBacktraces.begin() +
  135. std::distance(entryBegin, entryIt);
  136. this->DirectoryState->IncludeDirectories.insert(entryIt, vec);
  137. this->DirectoryState->IncludeDirectoryBacktraces.insert(btIt, lfbt);
  138. this->Snapshot_.Position->IncludeDirectoryPosition =
  139. this->DirectoryState->IncludeDirectories.size();
  140. }
  141. void cmStateDirectory::SetIncludeDirectories(const std::string& vec,
  142. const cmListFileBacktrace& lfbt)
  143. {
  144. SetContent(this->DirectoryState->IncludeDirectories,
  145. this->DirectoryState->IncludeDirectoryBacktraces,
  146. this->Snapshot_.Position->IncludeDirectoryPosition, vec, lfbt);
  147. }
  148. void cmStateDirectory::ClearIncludeDirectories()
  149. {
  150. ClearContent(this->DirectoryState->IncludeDirectories,
  151. this->DirectoryState->IncludeDirectoryBacktraces,
  152. this->Snapshot_.Position->IncludeDirectoryPosition);
  153. }
  154. cmStringRange cmStateDirectory::GetCompileDefinitionsEntries() const
  155. {
  156. return GetPropertyContent(
  157. this->DirectoryState->CompileDefinitions,
  158. this->Snapshot_.Position->CompileDefinitionsPosition);
  159. }
  160. cmBacktraceRange cmStateDirectory::GetCompileDefinitionsEntryBacktraces() const
  161. {
  162. return GetPropertyBacktraces(
  163. this->DirectoryState->CompileDefinitions,
  164. this->DirectoryState->CompileDefinitionsBacktraces,
  165. this->Snapshot_.Position->CompileDefinitionsPosition);
  166. }
  167. void cmStateDirectory::AppendCompileDefinitionsEntry(
  168. const std::string& vec, const cmListFileBacktrace& lfbt)
  169. {
  170. AppendEntry(this->DirectoryState->CompileDefinitions,
  171. this->DirectoryState->CompileDefinitionsBacktraces,
  172. this->Snapshot_.Position->CompileDefinitionsPosition, vec, lfbt);
  173. }
  174. void cmStateDirectory::SetCompileDefinitions(const std::string& vec,
  175. const cmListFileBacktrace& lfbt)
  176. {
  177. SetContent(this->DirectoryState->CompileDefinitions,
  178. this->DirectoryState->CompileDefinitionsBacktraces,
  179. this->Snapshot_.Position->CompileDefinitionsPosition, vec, lfbt);
  180. }
  181. void cmStateDirectory::ClearCompileDefinitions()
  182. {
  183. ClearContent(this->DirectoryState->CompileDefinitions,
  184. this->DirectoryState->CompileDefinitionsBacktraces,
  185. this->Snapshot_.Position->CompileDefinitionsPosition);
  186. }
  187. cmStringRange cmStateDirectory::GetCompileOptionsEntries() const
  188. {
  189. return GetPropertyContent(this->DirectoryState->CompileOptions,
  190. this->Snapshot_.Position->CompileOptionsPosition);
  191. }
  192. cmBacktraceRange cmStateDirectory::GetCompileOptionsEntryBacktraces() const
  193. {
  194. return GetPropertyBacktraces(
  195. this->DirectoryState->CompileOptions,
  196. this->DirectoryState->CompileOptionsBacktraces,
  197. this->Snapshot_.Position->CompileOptionsPosition);
  198. }
  199. void cmStateDirectory::AppendCompileOptionsEntry(
  200. const std::string& vec, const cmListFileBacktrace& lfbt)
  201. {
  202. AppendEntry(this->DirectoryState->CompileOptions,
  203. this->DirectoryState->CompileOptionsBacktraces,
  204. this->Snapshot_.Position->CompileOptionsPosition, vec, lfbt);
  205. }
  206. void cmStateDirectory::SetCompileOptions(const std::string& vec,
  207. const cmListFileBacktrace& lfbt)
  208. {
  209. SetContent(this->DirectoryState->CompileOptions,
  210. this->DirectoryState->CompileOptionsBacktraces,
  211. this->Snapshot_.Position->CompileOptionsPosition, vec, lfbt);
  212. }
  213. void cmStateDirectory::ClearCompileOptions()
  214. {
  215. ClearContent(this->DirectoryState->CompileOptions,
  216. this->DirectoryState->CompileOptionsBacktraces,
  217. this->Snapshot_.Position->CompileOptionsPosition);
  218. }
  219. cmStringRange cmStateDirectory::GetLinkOptionsEntries() const
  220. {
  221. return GetPropertyContent(this->DirectoryState->LinkOptions,
  222. this->Snapshot_.Position->LinkOptionsPosition);
  223. }
  224. cmBacktraceRange cmStateDirectory::GetLinkOptionsEntryBacktraces() const
  225. {
  226. return GetPropertyBacktraces(this->DirectoryState->LinkOptions,
  227. this->DirectoryState->LinkOptionsBacktraces,
  228. this->Snapshot_.Position->LinkOptionsPosition);
  229. }
  230. void cmStateDirectory::AppendLinkOptionsEntry(const std::string& vec,
  231. const cmListFileBacktrace& lfbt)
  232. {
  233. AppendEntry(this->DirectoryState->LinkOptions,
  234. this->DirectoryState->LinkOptionsBacktraces,
  235. this->Snapshot_.Position->LinkOptionsPosition, vec, lfbt);
  236. }
  237. void cmStateDirectory::SetLinkOptions(const std::string& vec,
  238. const cmListFileBacktrace& lfbt)
  239. {
  240. SetContent(this->DirectoryState->LinkOptions,
  241. this->DirectoryState->LinkOptionsBacktraces,
  242. this->Snapshot_.Position->LinkOptionsPosition, vec, lfbt);
  243. }
  244. void cmStateDirectory::ClearLinkOptions()
  245. {
  246. ClearContent(this->DirectoryState->LinkOptions,
  247. this->DirectoryState->LinkOptionsBacktraces,
  248. this->Snapshot_.Position->LinkOptionsPosition);
  249. }
  250. cmStringRange cmStateDirectory::GetLinkDirectoriesEntries() const
  251. {
  252. return GetPropertyContent(this->DirectoryState->LinkDirectories,
  253. this->Snapshot_.Position->LinkDirectoriesPosition);
  254. }
  255. cmBacktraceRange cmStateDirectory::GetLinkDirectoriesEntryBacktraces() const
  256. {
  257. return GetPropertyBacktraces(
  258. this->DirectoryState->LinkDirectories,
  259. this->DirectoryState->LinkDirectoriesBacktraces,
  260. this->Snapshot_.Position->LinkDirectoriesPosition);
  261. }
  262. void cmStateDirectory::AppendLinkDirectoriesEntry(
  263. const std::string& vec, const cmListFileBacktrace& lfbt)
  264. {
  265. AppendEntry(this->DirectoryState->LinkDirectories,
  266. this->DirectoryState->LinkDirectoriesBacktraces,
  267. this->Snapshot_.Position->LinkDirectoriesPosition, vec, lfbt);
  268. }
  269. void cmStateDirectory::PrependLinkDirectoriesEntry(
  270. const std::string& vec, const cmListFileBacktrace& lfbt)
  271. {
  272. auto entryEnd = this->DirectoryState->LinkDirectories.begin() +
  273. this->Snapshot_.Position->LinkDirectoriesPosition;
  274. auto rend = this->DirectoryState->LinkDirectories.rend();
  275. auto rbegin = cm::make_reverse_iterator(entryEnd);
  276. rbegin = std::find(rbegin, rend, cmPropertySentinal);
  277. auto entryIt = rbegin.base();
  278. auto entryBegin = this->DirectoryState->LinkDirectories.begin();
  279. auto btIt = this->DirectoryState->LinkDirectoriesBacktraces.begin() +
  280. std::distance(entryBegin, entryIt);
  281. this->DirectoryState->LinkDirectories.insert(entryIt, vec);
  282. this->DirectoryState->LinkDirectoriesBacktraces.insert(btIt, lfbt);
  283. this->Snapshot_.Position->LinkDirectoriesPosition =
  284. this->DirectoryState->LinkDirectories.size();
  285. }
  286. void cmStateDirectory::SetLinkDirectories(const std::string& vec,
  287. const cmListFileBacktrace& lfbt)
  288. {
  289. SetContent(this->DirectoryState->LinkDirectories,
  290. this->DirectoryState->LinkDirectoriesBacktraces,
  291. this->Snapshot_.Position->LinkDirectoriesPosition, vec, lfbt);
  292. }
  293. void cmStateDirectory::ClearLinkDirectories()
  294. {
  295. ClearContent(this->DirectoryState->LinkDirectories,
  296. this->DirectoryState->LinkDirectoriesBacktraces,
  297. this->Snapshot_.Position->LinkDirectoriesPosition);
  298. }
  299. void cmStateDirectory::SetProperty(const std::string& prop, const char* value,
  300. cmListFileBacktrace const& lfbt)
  301. {
  302. if (prop == "INCLUDE_DIRECTORIES") {
  303. if (!value) {
  304. this->ClearIncludeDirectories();
  305. return;
  306. }
  307. this->SetIncludeDirectories(value, lfbt);
  308. return;
  309. }
  310. if (prop == "COMPILE_OPTIONS") {
  311. if (!value) {
  312. this->ClearCompileOptions();
  313. return;
  314. }
  315. this->SetCompileOptions(value, lfbt);
  316. return;
  317. }
  318. if (prop == "COMPILE_DEFINITIONS") {
  319. if (!value) {
  320. this->ClearCompileDefinitions();
  321. return;
  322. }
  323. this->SetCompileDefinitions(value, lfbt);
  324. return;
  325. }
  326. if (prop == "LINK_OPTIONS") {
  327. if (!value) {
  328. this->ClearLinkOptions();
  329. return;
  330. }
  331. this->SetLinkOptions(value, lfbt);
  332. return;
  333. }
  334. if (prop == "LINK_DIRECTORIES") {
  335. if (!value) {
  336. this->ClearLinkDirectories();
  337. return;
  338. }
  339. this->SetLinkDirectories(value, lfbt);
  340. return;
  341. }
  342. this->DirectoryState->Properties.SetProperty(prop, value);
  343. }
  344. void cmStateDirectory::AppendProperty(const std::string& prop,
  345. const std::string& value, bool asString,
  346. cmListFileBacktrace const& lfbt)
  347. {
  348. if (prop == "INCLUDE_DIRECTORIES") {
  349. this->AppendIncludeDirectoriesEntry(value, lfbt);
  350. return;
  351. }
  352. if (prop == "COMPILE_OPTIONS") {
  353. this->AppendCompileOptionsEntry(value, lfbt);
  354. return;
  355. }
  356. if (prop == "COMPILE_DEFINITIONS") {
  357. this->AppendCompileDefinitionsEntry(value, lfbt);
  358. return;
  359. }
  360. if (prop == "LINK_OPTIONS") {
  361. this->AppendLinkOptionsEntry(value, lfbt);
  362. return;
  363. }
  364. if (prop == "LINK_DIRECTORIES") {
  365. this->AppendLinkDirectoriesEntry(value, lfbt);
  366. return;
  367. }
  368. this->DirectoryState->Properties.AppendProperty(prop, value, asString);
  369. }
  370. cmProp cmStateDirectory::GetProperty(const std::string& prop) const
  371. {
  372. const bool chain =
  373. this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY);
  374. return this->GetProperty(prop, chain);
  375. }
  376. cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const
  377. {
  378. static std::string output;
  379. output.clear();
  380. if (prop == "PARENT_DIRECTORY") {
  381. cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent();
  382. if (parent.IsValid()) {
  383. return cmProp(parent.GetDirectory().GetCurrentSource());
  384. }
  385. return cmProp(output);
  386. }
  387. if (prop == kBINARY_DIR) {
  388. output = this->GetCurrentBinary();
  389. return cmProp(output);
  390. }
  391. if (prop == kSOURCE_DIR) {
  392. output = this->GetCurrentSource();
  393. return cmProp(output);
  394. }
  395. if (prop == kSUBDIRECTORIES) {
  396. std::vector<std::string> child_dirs;
  397. std::vector<cmStateSnapshot> const& children =
  398. this->DirectoryState->Children;
  399. child_dirs.reserve(children.size());
  400. for (cmStateSnapshot const& ci : children) {
  401. child_dirs.push_back(ci.GetDirectory().GetCurrentSource());
  402. }
  403. output = cmJoin(child_dirs, ";");
  404. return cmProp(output);
  405. }
  406. if (prop == kBUILDSYSTEM_TARGETS) {
  407. output = cmJoin(this->DirectoryState->NormalTargetNames, ";");
  408. return cmProp(output);
  409. }
  410. if (prop == "IMPORTED_TARGETS"_s) {
  411. output = cmJoin(this->DirectoryState->ImportedTargetNames, ";");
  412. return cmProp(output);
  413. }
  414. if (prop == "LISTFILE_STACK") {
  415. std::vector<std::string> listFiles;
  416. cmStateSnapshot snp = this->Snapshot_;
  417. while (snp.IsValid()) {
  418. listFiles.push_back(snp.GetExecutionListFile());
  419. snp = snp.GetCallStackParent();
  420. }
  421. std::reverse(listFiles.begin(), listFiles.end());
  422. output = cmJoin(listFiles, ";");
  423. return cmProp(output);
  424. }
  425. if (prop == "CACHE_VARIABLES") {
  426. output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
  427. return cmProp(output);
  428. }
  429. if (prop == "VARIABLES") {
  430. std::vector<std::string> res = this->Snapshot_.ClosureKeys();
  431. cm::append(res, this->Snapshot_.State->GetCacheEntryKeys());
  432. std::sort(res.begin(), res.end());
  433. output = cmJoin(res, ";");
  434. return cmProp(output);
  435. }
  436. if (prop == "INCLUDE_DIRECTORIES") {
  437. output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
  438. return cmProp(output);
  439. }
  440. if (prop == "COMPILE_OPTIONS") {
  441. output = cmJoin(this->GetCompileOptionsEntries(), ";");
  442. return cmProp(output);
  443. }
  444. if (prop == "COMPILE_DEFINITIONS") {
  445. output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
  446. return cmProp(output);
  447. }
  448. if (prop == "LINK_OPTIONS") {
  449. output = cmJoin(this->GetLinkOptionsEntries(), ";");
  450. return cmProp(output);
  451. }
  452. if (prop == "LINK_DIRECTORIES") {
  453. output = cmJoin(this->GetLinkDirectoriesEntries(), ";");
  454. return cmProp(output);
  455. }
  456. cmProp retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
  457. if (!retVal && chain) {
  458. cmStateSnapshot parentSnapshot =
  459. this->Snapshot_.GetBuildsystemDirectoryParent();
  460. if (parentSnapshot.IsValid()) {
  461. return parentSnapshot.GetDirectory().GetProperty(prop, chain);
  462. }
  463. return this->Snapshot_.State->GetGlobalProperty(prop);
  464. }
  465. return retVal;
  466. }
  467. bool cmStateDirectory::GetPropertyAsBool(const std::string& prop) const
  468. {
  469. return cmIsOn(this->GetProperty(prop));
  470. }
  471. std::vector<std::string> cmStateDirectory::GetPropertyKeys() const
  472. {
  473. return this->DirectoryState->Properties.GetKeys();
  474. }
  475. void cmStateDirectory::AddNormalTargetName(std::string const& name)
  476. {
  477. this->DirectoryState->NormalTargetNames.push_back(name);
  478. }
  479. void cmStateDirectory::AddImportedTargetName(std::string const& name)
  480. {
  481. this->DirectoryState->ImportedTargetNames.emplace_back(name);
  482. }