cmFindCommon.cxx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file LICENSE.rst or https://cmake.org/licensing for details. */
  3. #include "cmFindCommon.h"
  4. #include <algorithm>
  5. #include <array>
  6. #include <utility>
  7. #include <cmext/algorithm>
  8. #include "cmExecutionStatus.h"
  9. #include "cmList.h"
  10. #include "cmMakefile.h"
  11. #include "cmMessageType.h"
  12. #include "cmPolicies.h"
  13. #include "cmStringAlgorithms.h"
  14. #include "cmSystemTools.h"
  15. #include "cmValue.h"
  16. #include "cmake.h"
  17. #ifndef CMAKE_BOOTSTRAP
  18. # include <deque>
  19. # include <iterator>
  20. # include <cm/optional>
  21. # include <cm/string_view>
  22. # include <cmext/string_view>
  23. # include "cmConfigureLog.h"
  24. # include "cmRange.h"
  25. #endif
  26. cmFindCommon::PathGroup cmFindCommon::PathGroup::All("ALL");
  27. cmFindCommon::PathLabel cmFindCommon::PathLabel::PackageRoot(
  28. "PackageName_ROOT");
  29. cmFindCommon::PathLabel cmFindCommon::PathLabel::CMake("CMAKE");
  30. cmFindCommon::PathLabel cmFindCommon::PathLabel::CMakeEnvironment(
  31. "CMAKE_ENVIRONMENT");
  32. cmFindCommon::PathLabel cmFindCommon::PathLabel::Hints("HINTS");
  33. cmFindCommon::PathLabel cmFindCommon::PathLabel::SystemEnvironment(
  34. "SYSTEM_ENVIRONMENT");
  35. cmFindCommon::PathLabel cmFindCommon::PathLabel::CMakeSystem("CMAKE_SYSTEM");
  36. cmFindCommon::PathLabel cmFindCommon::PathLabel::Guess("GUESS");
  37. cmFindCommon::cmFindCommon(cmExecutionStatus& status)
  38. : Makefile(&status.GetMakefile())
  39. , Status(status)
  40. {
  41. this->FindRootPathMode = RootPathModeBoth;
  42. this->FullDebugMode = false;
  43. this->NoDefaultPath = false;
  44. this->NoPackageRootPath = false;
  45. this->NoCMakePath = false;
  46. this->NoCMakeEnvironmentPath = false;
  47. this->NoSystemEnvironmentPath = false;
  48. this->NoCMakeSystemPath = false;
  49. this->NoCMakeInstallPath = false;
  50. // OS X Bundle and Framework search policy. The default is to
  51. // search frameworks first on apple.
  52. #if defined(__APPLE__)
  53. this->SearchFrameworkFirst = true;
  54. this->SearchAppBundleFirst = true;
  55. #else
  56. this->SearchFrameworkFirst = false;
  57. this->SearchAppBundleFirst = false;
  58. #endif
  59. this->SearchFrameworkOnly = false;
  60. this->SearchFrameworkLast = false;
  61. this->SearchAppBundleOnly = false;
  62. this->SearchAppBundleLast = false;
  63. this->InitializeSearchPathGroups();
  64. // Windows Registry views
  65. // When policy CMP0134 is not NEW, rely on previous behavior:
  66. if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0134) !=
  67. cmPolicies::NEW) {
  68. if (this->Makefile->GetDefinition("CMAKE_SIZEOF_VOID_P") == "8") {
  69. this->RegistryView = cmWindowsRegistry::View::Reg64;
  70. } else {
  71. this->RegistryView = cmWindowsRegistry::View::Reg32;
  72. }
  73. }
  74. }
  75. cmFindCommon::~cmFindCommon() = default;
  76. void cmFindCommon::SetError(std::string const& e)
  77. {
  78. this->Status.SetError(e);
  79. }
  80. bool cmFindCommon::DebugModeEnabled() const
  81. {
  82. return this->FullDebugMode;
  83. }
  84. void cmFindCommon::DebugMessage(std::string const& msg) const
  85. {
  86. if (this->Makefile) {
  87. this->Makefile->IssueMessage(MessageType::LOG, msg);
  88. }
  89. }
  90. bool cmFindCommon::ComputeIfDebugModeWanted()
  91. {
  92. return this->Makefile->GetDebugFindPkgMode() ||
  93. this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE") ||
  94. this->Makefile->GetCMakeInstance()->GetDebugFindOutput();
  95. }
  96. bool cmFindCommon::ComputeIfDebugModeWanted(std::string const& var)
  97. {
  98. return this->ComputeIfDebugModeWanted() ||
  99. this->Makefile->GetCMakeInstance()->GetDebugFindOutput(var);
  100. }
  101. void cmFindCommon::InitializeSearchPathGroups()
  102. {
  103. std::vector<PathLabel>* labels;
  104. // Define the various different groups of path types
  105. // All search paths
  106. labels = &this->PathGroupLabelMap[PathGroup::All];
  107. labels->push_back(PathLabel::PackageRoot);
  108. labels->push_back(PathLabel::CMake);
  109. labels->push_back(PathLabel::CMakeEnvironment);
  110. labels->push_back(PathLabel::Hints);
  111. labels->push_back(PathLabel::SystemEnvironment);
  112. labels->push_back(PathLabel::CMakeSystem);
  113. labels->push_back(PathLabel::Guess);
  114. // Define the search group order
  115. this->PathGroupOrder.push_back(PathGroup::All);
  116. // Create the individual labeled search paths
  117. this->LabeledPaths.emplace(PathLabel::PackageRoot, cmSearchPath(this));
  118. this->LabeledPaths.emplace(PathLabel::CMake, cmSearchPath(this));
  119. this->LabeledPaths.emplace(PathLabel::CMakeEnvironment, cmSearchPath(this));
  120. this->LabeledPaths.emplace(PathLabel::Hints, cmSearchPath(this));
  121. this->LabeledPaths.emplace(PathLabel::SystemEnvironment, cmSearchPath(this));
  122. this->LabeledPaths.emplace(PathLabel::CMakeSystem, cmSearchPath(this));
  123. this->LabeledPaths.emplace(PathLabel::Guess, cmSearchPath(this));
  124. }
  125. void cmFindCommon::SelectDefaultRootPathMode()
  126. {
  127. // Check the policy variable for this find command type.
  128. std::string findRootPathVar =
  129. cmStrCat("CMAKE_FIND_ROOT_PATH_MODE_", this->CMakePathName);
  130. std::string rootPathMode =
  131. this->Makefile->GetSafeDefinition(findRootPathVar);
  132. if (rootPathMode == "NEVER") {
  133. this->FindRootPathMode = RootPathModeNever;
  134. } else if (rootPathMode == "ONLY") {
  135. this->FindRootPathMode = RootPathModeOnly;
  136. } else if (rootPathMode == "BOTH") {
  137. this->FindRootPathMode = RootPathModeBoth;
  138. }
  139. }
  140. void cmFindCommon::SelectDefaultMacMode()
  141. {
  142. std::string ff = this->Makefile->GetSafeDefinition("CMAKE_FIND_FRAMEWORK");
  143. if (ff == "NEVER") {
  144. this->SearchFrameworkLast = false;
  145. this->SearchFrameworkFirst = false;
  146. this->SearchFrameworkOnly = false;
  147. } else if (ff == "ONLY") {
  148. this->SearchFrameworkLast = false;
  149. this->SearchFrameworkFirst = false;
  150. this->SearchFrameworkOnly = true;
  151. } else if (ff == "FIRST") {
  152. this->SearchFrameworkLast = false;
  153. this->SearchFrameworkFirst = true;
  154. this->SearchFrameworkOnly = false;
  155. } else if (ff == "LAST") {
  156. this->SearchFrameworkLast = true;
  157. this->SearchFrameworkFirst = false;
  158. this->SearchFrameworkOnly = false;
  159. }
  160. std::string fab = this->Makefile->GetSafeDefinition("CMAKE_FIND_APPBUNDLE");
  161. if (fab == "NEVER") {
  162. this->SearchAppBundleLast = false;
  163. this->SearchAppBundleFirst = false;
  164. this->SearchAppBundleOnly = false;
  165. } else if (fab == "ONLY") {
  166. this->SearchAppBundleLast = false;
  167. this->SearchAppBundleFirst = false;
  168. this->SearchAppBundleOnly = true;
  169. } else if (fab == "FIRST") {
  170. this->SearchAppBundleLast = false;
  171. this->SearchAppBundleFirst = true;
  172. this->SearchAppBundleOnly = false;
  173. } else if (fab == "LAST") {
  174. this->SearchAppBundleLast = true;
  175. this->SearchAppBundleFirst = false;
  176. this->SearchAppBundleOnly = false;
  177. }
  178. }
  179. void cmFindCommon::SelectDefaultSearchModes()
  180. {
  181. std::array<std::pair<bool&, std::string>, 6> const search_paths = {
  182. { { this->NoPackageRootPath, "CMAKE_FIND_USE_PACKAGE_ROOT_PATH" },
  183. { this->NoCMakePath, "CMAKE_FIND_USE_CMAKE_PATH" },
  184. { this->NoCMakeEnvironmentPath,
  185. "CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH" },
  186. { this->NoSystemEnvironmentPath,
  187. "CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH" },
  188. { this->NoCMakeSystemPath, "CMAKE_FIND_USE_CMAKE_SYSTEM_PATH" },
  189. { this->NoCMakeInstallPath, "CMAKE_FIND_USE_INSTALL_PREFIX" } }
  190. };
  191. for (auto const& path : search_paths) {
  192. cmValue def = this->Makefile->GetDefinition(path.second);
  193. if (def) {
  194. path.first = !def.IsOn();
  195. }
  196. }
  197. }
  198. void cmFindCommon::RerootPaths(std::vector<std::string>& paths,
  199. std::string* debugBuffer)
  200. {
  201. // Short-circuit if there is nothing to do.
  202. if (this->FindRootPathMode == RootPathModeNever) {
  203. return;
  204. }
  205. cmValue sysroot = this->Makefile->GetDefinition("CMAKE_SYSROOT");
  206. cmValue sysrootCompile =
  207. this->Makefile->GetDefinition("CMAKE_SYSROOT_COMPILE");
  208. cmValue sysrootLink = this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK");
  209. cmValue rootPath = this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH");
  210. bool const noSysroot = !cmNonempty(sysroot);
  211. bool const noCompileSysroot = !cmNonempty(sysrootCompile);
  212. bool const noLinkSysroot = !cmNonempty(sysrootLink);
  213. bool const noRootPath = !cmNonempty(rootPath);
  214. if (noSysroot && noCompileSysroot && noLinkSysroot && noRootPath) {
  215. return;
  216. }
  217. if (this->DebugModeEnabled() && debugBuffer) {
  218. *debugBuffer = cmStrCat(
  219. *debugBuffer, "Prepending the following roots to each prefix:\n");
  220. }
  221. auto debugRoot = [this, debugBuffer](std::string const& name,
  222. cmValue value) {
  223. if (this->DebugModeEnabled() && debugBuffer) {
  224. *debugBuffer = cmStrCat(*debugBuffer, name, '\n');
  225. cmList roots{ value };
  226. if (roots.empty()) {
  227. *debugBuffer = cmStrCat(*debugBuffer, " none\n");
  228. }
  229. for (auto const& root : roots) {
  230. *debugBuffer = cmStrCat(*debugBuffer, " ", root, '\n');
  231. }
  232. }
  233. };
  234. // Construct the list of path roots with no trailing slashes.
  235. cmList roots;
  236. debugRoot("CMAKE_FIND_ROOT_PATH", rootPath);
  237. if (cmNonempty(rootPath)) {
  238. roots.assign(*rootPath);
  239. }
  240. debugRoot("CMAKE_SYSROOT_COMPILE", sysrootCompile);
  241. if (cmNonempty(sysrootCompile)) {
  242. roots.emplace_back(*sysrootCompile);
  243. }
  244. debugRoot("CMAKE_SYSROOT_LINK", sysrootLink);
  245. if (cmNonempty(sysrootLink)) {
  246. roots.emplace_back(*sysrootLink);
  247. }
  248. debugRoot("CMAKE_SYSROOT", sysroot);
  249. if (cmNonempty(sysroot)) {
  250. roots.emplace_back(*sysroot);
  251. }
  252. for (auto& r : roots) {
  253. cmSystemTools::ConvertToUnixSlashes(r);
  254. }
  255. cmValue stagePrefix = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX");
  256. // Copy the original set of unrooted paths.
  257. auto unrootedPaths = paths;
  258. paths.clear();
  259. auto isSameDirectoryOrSubDirectory = [](std::string const& l,
  260. std::string const& r) {
  261. return (cmSystemTools::GetRealPath(l) == cmSystemTools::GetRealPath(r)) ||
  262. cmSystemTools::IsSubDirectory(l, r);
  263. };
  264. for (auto const& r : roots) {
  265. for (auto const& up : unrootedPaths) {
  266. // Place the unrooted path under the current root if it is not
  267. // already inside. Skip the unrooted path if it is relative to
  268. // a user home directory or is empty.
  269. std::string rootedDir;
  270. if (isSameDirectoryOrSubDirectory(up, r) ||
  271. (stagePrefix && isSameDirectoryOrSubDirectory(up, *stagePrefix))) {
  272. rootedDir = up;
  273. } else if (!up.empty() && up[0] != '~') {
  274. auto const* split = cmSystemTools::SplitPathRootComponent(up);
  275. if (split && *split) {
  276. // Start with the new root.
  277. rootedDir = cmStrCat(r, '/', split);
  278. } else {
  279. rootedDir = r;
  280. }
  281. }
  282. // Store the new path.
  283. paths.push_back(rootedDir);
  284. }
  285. }
  286. // If searching both rooted and unrooted paths add the original
  287. // paths again.
  288. if (this->FindRootPathMode == RootPathModeBoth) {
  289. cm::append(paths, unrootedPaths);
  290. }
  291. }
  292. void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore)
  293. {
  294. std::array<char const*, 2> const paths = { { "CMAKE_SYSTEM_IGNORE_PATH",
  295. "CMAKE_IGNORE_PATH" } };
  296. // Construct the list of path roots with no trailing slashes.
  297. for (char const* pathName : paths) {
  298. // Get the list of paths to ignore from the variable.
  299. cmList::append(ignore, this->Makefile->GetDefinition(pathName));
  300. }
  301. for (std::string& i : ignore) {
  302. cmSystemTools::ConvertToUnixSlashes(i);
  303. }
  304. }
  305. void cmFindCommon::GetIgnoredPaths(std::set<std::string>& ignore)
  306. {
  307. std::vector<std::string> ignoreVec;
  308. this->GetIgnoredPaths(ignoreVec);
  309. ignore.insert(ignoreVec.begin(), ignoreVec.end());
  310. }
  311. void cmFindCommon::GetIgnoredPrefixPaths(std::vector<std::string>& ignore)
  312. {
  313. std::array<char const*, 2> const paths = {
  314. { "CMAKE_SYSTEM_IGNORE_PREFIX_PATH", "CMAKE_IGNORE_PREFIX_PATH" }
  315. };
  316. // Construct the list of path roots with no trailing slashes.
  317. for (char const* pathName : paths) {
  318. // Get the list of paths to ignore from the variable.
  319. cmList::append(ignore, this->Makefile->GetDefinition(pathName));
  320. }
  321. for (std::string& i : ignore) {
  322. cmSystemTools::ConvertToUnixSlashes(i);
  323. }
  324. }
  325. void cmFindCommon::GetIgnoredPrefixPaths(std::set<std::string>& ignore)
  326. {
  327. std::vector<std::string> ignoreVec;
  328. this->GetIgnoredPrefixPaths(ignoreVec);
  329. ignore.insert(ignoreVec.begin(), ignoreVec.end());
  330. }
  331. bool cmFindCommon::CheckCommonArgument(std::string const& arg)
  332. {
  333. if (arg == "NO_DEFAULT_PATH") {
  334. this->NoDefaultPath = true;
  335. return true;
  336. }
  337. if (arg == "NO_PACKAGE_ROOT_PATH") {
  338. this->NoPackageRootPath = true;
  339. return true;
  340. }
  341. if (arg == "NO_CMAKE_PATH") {
  342. this->NoCMakePath = true;
  343. return true;
  344. }
  345. if (arg == "NO_CMAKE_ENVIRONMENT_PATH") {
  346. this->NoCMakeEnvironmentPath = true;
  347. return true;
  348. }
  349. if (arg == "NO_SYSTEM_ENVIRONMENT_PATH") {
  350. this->NoSystemEnvironmentPath = true;
  351. return true;
  352. }
  353. if (arg == "NO_CMAKE_SYSTEM_PATH") {
  354. this->NoCMakeSystemPath = true;
  355. return true;
  356. }
  357. if (arg == "NO_CMAKE_INSTALL_PREFIX") {
  358. this->NoCMakeInstallPath = true;
  359. return true;
  360. }
  361. if (arg == "NO_CMAKE_FIND_ROOT_PATH") {
  362. this->FindRootPathMode = RootPathModeNever;
  363. return true;
  364. }
  365. if (arg == "ONLY_CMAKE_FIND_ROOT_PATH") {
  366. this->FindRootPathMode = RootPathModeOnly;
  367. return true;
  368. }
  369. if (arg == "CMAKE_FIND_ROOT_PATH_BOTH") {
  370. this->FindRootPathMode = RootPathModeBoth;
  371. return true;
  372. }
  373. // The argument is not one of the above.
  374. return false;
  375. }
  376. void cmFindCommon::AddPathSuffix(std::string const& arg)
  377. {
  378. std::string suffix = arg;
  379. // Strip leading and trailing slashes.
  380. if (suffix.empty()) {
  381. return;
  382. }
  383. if (suffix.front() == '/') {
  384. suffix = suffix.substr(1);
  385. }
  386. if (suffix.empty()) {
  387. return;
  388. }
  389. if (suffix.back() == '/') {
  390. suffix = suffix.substr(0, suffix.size() - 1);
  391. }
  392. if (suffix.empty()) {
  393. return;
  394. }
  395. // Store the suffix.
  396. this->SearchPathSuffixes.push_back(std::move(suffix));
  397. }
  398. void cmFindCommon::ComputeFinalPaths(IgnorePaths ignorePaths,
  399. std::string* debugBuffer)
  400. {
  401. // Filter out ignored paths from the prefix list
  402. std::set<std::string> ignoredPaths;
  403. std::set<std::string> ignoredPrefixes;
  404. if (ignorePaths == IgnorePaths::Yes) {
  405. this->GetIgnoredPaths(ignoredPaths);
  406. this->GetIgnoredPrefixPaths(ignoredPrefixes);
  407. }
  408. // Combine the separate path types, filtering out ignores
  409. this->SearchPaths.clear();
  410. std::vector<PathLabel>& allLabels = this->PathGroupLabelMap[PathGroup::All];
  411. for (PathLabel const& l : allLabels) {
  412. this->LabeledPaths[l].ExtractWithout(ignoredPaths, ignoredPrefixes,
  413. this->SearchPaths);
  414. }
  415. // Expand list of paths inside all search roots.
  416. this->RerootPaths(this->SearchPaths, debugBuffer);
  417. // Add a trailing slash to all paths to aid the search process.
  418. std::for_each(this->SearchPaths.begin(), this->SearchPaths.end(),
  419. [](std::string& s) {
  420. if (!s.empty() && s.back() != '/') {
  421. s += '/';
  422. }
  423. });
  424. }
  425. cmFindCommonDebugState::cmFindCommonDebugState(std::string name,
  426. cmFindCommon const* findCommand)
  427. : FindCommand(findCommand)
  428. , CommandName(std::move(name))
  429. // Strip the `find_` prefix.
  430. , Mode(this->CommandName.substr(5))
  431. {
  432. }
  433. void cmFindCommonDebugState::FoundAt(std::string const& path,
  434. std::string regexName)
  435. {
  436. this->IsFound = true;
  437. if (!this->TrackSearchProgress()) {
  438. return;
  439. }
  440. this->FoundAtImpl(path, regexName);
  441. }
  442. void cmFindCommonDebugState::FailedAt(std::string const& path,
  443. std::string regexName)
  444. {
  445. if (!this->TrackSearchProgress()) {
  446. return;
  447. }
  448. this->FailedAtImpl(path, regexName);
  449. }
  450. void cmFindCommonDebugState::Write()
  451. {
  452. auto const* const fc = this->FindCommand;
  453. #ifndef CMAKE_BOOTSTRAP
  454. // Write find event to the configure log if the log exists
  455. if (cmConfigureLog* log =
  456. fc->Makefile->GetCMakeInstance()->GetConfigureLog()) {
  457. // Write event if any of:
  458. // - debug mode is enabled
  459. // - the variable was not defined (first run)
  460. // - the variable found state does not match the new found state (state
  461. // transition)
  462. if (fc->DebugModeEnabled() || !fc->IsDefined() ||
  463. fc->IsFound() != this->IsFound) {
  464. this->WriteEvent(*log, *fc->Makefile);
  465. }
  466. }
  467. #endif
  468. if (fc->DebugModeEnabled()) {
  469. this->WriteDebug();
  470. }
  471. }
  472. #ifndef CMAKE_BOOTSTRAP
  473. void cmFindCommonDebugState::WriteSearchVariables(cmConfigureLog& log,
  474. cmMakefile const& mf) const
  475. {
  476. auto WriteString = [&log, &mf](std::string const& name) {
  477. if (cmValue value = mf.GetDefinition(name)) {
  478. log.WriteValue(name, *value);
  479. }
  480. };
  481. auto WriteCMakeList = [&log, &mf](std::string const& name) {
  482. if (cmValue value = mf.GetDefinition(name)) {
  483. cmList values{ *value };
  484. if (!values.empty()) {
  485. log.WriteValue(name, values);
  486. }
  487. }
  488. };
  489. auto WriteEnvList = [&log](std::string const& name) {
  490. if (auto value = cmSystemTools::GetEnvVar(name)) {
  491. auto values = cmSystemTools::SplitEnvPath(*value);
  492. if (!values.empty()) {
  493. log.WriteValue(cmStrCat("ENV{", name, '}'), values);
  494. }
  495. }
  496. };
  497. auto const* fc = this->FindCommand;
  498. log.BeginObject("search_context"_s);
  499. auto const& packageRootStack = mf.FindPackageRootPathStack;
  500. if (!packageRootStack.empty()) {
  501. bool havePaths =
  502. std::any_of(packageRootStack.begin(), packageRootStack.end(),
  503. [](std::vector<std::string> const& entry) -> bool {
  504. return !entry.empty();
  505. });
  506. if (havePaths) {
  507. log.BeginObject("package_stack");
  508. log.BeginArray();
  509. for (auto const& pkgPaths : cmReverseRange(packageRootStack)) {
  510. if (!pkgPaths.empty()) {
  511. log.NextArrayElement();
  512. log.WriteValue("package_paths", pkgPaths);
  513. }
  514. }
  515. log.EndArray();
  516. log.EndObject();
  517. }
  518. }
  519. auto cmakePathVar = cmStrCat("CMAKE_", fc->CMakePathName, "_PATH");
  520. WriteCMakeList(cmakePathVar);
  521. WriteCMakeList("CMAKE_PREFIX_PATH");
  522. if (fc->CMakePathName == "PROGRAM"_s) {
  523. WriteCMakeList("CMAKE_APPBUNDLE_PATH");
  524. } else {
  525. WriteCMakeList("CMAKE_FRAMEWORK_PATH");
  526. }
  527. // Same as above, but ask the environment instead.
  528. WriteEnvList(cmakePathVar);
  529. WriteEnvList("CMAKE_PREFIX_PATH");
  530. if (fc->CMakePathName == "PROGRAM"_s) {
  531. WriteEnvList("CMAKE_APPBUNDLE_PATH");
  532. } else {
  533. WriteEnvList("CMAKE_FRAMEWORK_PATH");
  534. }
  535. WriteEnvList("PATH");
  536. WriteString("CMAKE_INSTALL_PREFIX");
  537. WriteString("CMAKE_STAGING_PREFIX");
  538. WriteCMakeList("CMAKE_SYSTEM_PREFIX_PATH");
  539. auto systemPathVar = cmStrCat("CMAKE_SYSTEM_", fc->CMakePathName, "_PATH");
  540. WriteCMakeList(systemPathVar);
  541. // Sysroot paths.
  542. WriteString("CMAKE_SYSROOT");
  543. WriteString("CMAKE_SYSROOT_COMPILE");
  544. WriteString("CMAKE_SYSROOT_LINK");
  545. WriteString("CMAKE_FIND_ROOT_PATH");
  546. // Write out paths which are ignored.
  547. WriteCMakeList("CMAKE_IGNORE_PATH");
  548. WriteCMakeList("CMAKE_IGNORE_PREFIX_PATH");
  549. WriteCMakeList("CMAKE_SYSTEM_IGNORE_PATH");
  550. WriteCMakeList("CMAKE_SYSTEM_IGNORE_PREFIX_PATH");
  551. if (fc->CMakePathName == "PROGRAM"_s) {
  552. WriteCMakeList("CMAKE_SYSTEM_APPBUNDLE_PATH");
  553. } else {
  554. WriteCMakeList("CMAKE_SYSTEM_FRAMEWORK_PATH");
  555. }
  556. for (auto const& extraVar : this->ExtraSearchVariables()) {
  557. switch (extraVar.first) {
  558. case VariableSource::String:
  559. WriteString(extraVar.second);
  560. break;
  561. case VariableSource::PathList:
  562. WriteCMakeList(extraVar.second);
  563. break;
  564. case VariableSource::EnvironmentList:
  565. WriteEnvList(extraVar.second);
  566. break;
  567. }
  568. }
  569. log.EndObject();
  570. }
  571. std::vector<std::pair<cmFindCommonDebugState::VariableSource, std::string>>
  572. cmFindCommonDebugState::ExtraSearchVariables() const
  573. {
  574. return {};
  575. }
  576. #endif
  577. bool cmFindCommonDebugState::TrackSearchProgress() const
  578. {
  579. // Track search progress if debugging or logging the configure.
  580. return this->FindCommand->DebugModeEnabled()
  581. #ifndef CMAKE_BOOTSTRAP
  582. || this->FindCommand->Makefile->GetCMakeInstance()->GetConfigureLog()
  583. #endif
  584. ;
  585. }