cmFindPackageCommand.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file LICENSE.rst or https://cmake.org/licensing for details. */
  3. #pragma once
  4. #include "cmConfigure.h" // IWYU pragma: keep
  5. #include <cstddef>
  6. #include <functional>
  7. #include <map>
  8. #include <memory>
  9. #include <set>
  10. #include <string>
  11. #include <utility>
  12. #include <vector>
  13. #include <cm/string_view>
  14. #include <cm3p/kwiml/int.h>
  15. #include "cmFindCommon.h"
  16. #include "cmPackageInfoReader.h"
  17. #include "cmPolicies.h"
  18. // IWYU insists we should forward-declare instead of including <functional>,
  19. // but we cannot forward-declare reliably because some C++ standard libraries
  20. // put the template in an inline namespace.
  21. #ifdef CMAKE_IWYU_FORWARD_STD_HASH
  22. /* clang-format off */
  23. namespace std {
  24. template <class T> struct hash;
  25. }
  26. /* clang-format on */
  27. #endif
  28. class cmConfigureLog;
  29. class cmExecutionStatus;
  30. class cmMakefile;
  31. class cmPackageState;
  32. class cmSearchPath;
  33. /** \class cmFindPackageCommand
  34. * \brief Load settings from an external project.
  35. *
  36. * cmFindPackageCommand
  37. */
  38. class cmFindPackageCommand : public cmFindCommon
  39. {
  40. public:
  41. /*! A sorting order strategy to be applied to recovered package folders (see
  42. * FIND_PACKAGE_SORT_ORDER)*/
  43. enum /*class*/ SortOrderType
  44. {
  45. None,
  46. Name_order,
  47. Natural
  48. };
  49. /*! A sorting direction to be applied to recovered package folders (see
  50. * FIND_PACKAGE_SORT_DIRECTION)*/
  51. enum /*class*/ SortDirectionType
  52. {
  53. Asc,
  54. Dec
  55. };
  56. enum class PackageDescriptionType
  57. {
  58. Any,
  59. CMake,
  60. Cps,
  61. };
  62. /*! sorts a given list of string based on the input sort parameters */
  63. static void Sort(std::vector<std::string>::iterator begin,
  64. std::vector<std::string>::iterator end, SortOrderType order,
  65. SortDirectionType dir);
  66. cmFindPackageCommand(cmExecutionStatus& status);
  67. ~cmFindPackageCommand() override;
  68. bool InitialPass(std::vector<std::string> const& args);
  69. private:
  70. class PathLabel : public cmFindCommon::PathLabel
  71. {
  72. protected:
  73. PathLabel();
  74. public:
  75. PathLabel(std::string const& label)
  76. : cmFindCommon::PathLabel(label)
  77. {
  78. }
  79. static PathLabel PackageRedirect;
  80. static PathLabel UserRegistry;
  81. static PathLabel Builds;
  82. static PathLabel SystemRegistry;
  83. };
  84. void InheritOptions(cmFindPackageCommand* other);
  85. bool IsFound() const override;
  86. bool IsDefined() const override;
  87. // Try to find a package, assuming most state has already been set up. This
  88. // is used for recursive dependency solving, particularly when importing
  89. // packages via CPS. Bypasses providers if argsForProvider is empty.
  90. bool FindPackage(std::vector<std::string> const& argsForProvider = {});
  91. bool FindPackageUsingModuleMode();
  92. bool FindPackageUsingConfigMode();
  93. // Add additional search path labels and groups not present in the
  94. // parent class
  95. void AppendSearchPathGroups();
  96. void AppendSuccessInformation();
  97. void AppendToFoundProperty(bool found);
  98. void SetVersionVariables(
  99. std::function<void(std::string const&, cm::string_view)> const&
  100. addDefinition,
  101. std::string const& prefix, std::string const& version, unsigned int count,
  102. unsigned int major, unsigned int minor, unsigned int patch,
  103. unsigned int tweak);
  104. void SetModuleVariables();
  105. bool FindModule(bool& found);
  106. void AddFindDefinition(std::string const& var, cm::string_view value);
  107. void RestoreFindDefinitions();
  108. class SetRestoreFindDefinitions;
  109. enum /*class*/ HandlePackageModeType
  110. {
  111. Module,
  112. Config
  113. };
  114. bool HandlePackageMode(HandlePackageModeType type);
  115. bool FindConfig();
  116. bool FindPrefixedConfig();
  117. bool FindFrameworkConfig();
  118. bool FindAppBundleConfig();
  119. bool FindEnvironmentConfig();
  120. enum PolicyScopeRule
  121. {
  122. NoPolicyScope,
  123. DoPolicyScope
  124. };
  125. bool ReadListFile(std::string const& f, PolicyScopeRule psr);
  126. bool ReadPackage();
  127. struct Appendix
  128. {
  129. std::unique_ptr<cmPackageInfoReader> Reader;
  130. std::vector<std::string> Components;
  131. operator cmPackageInfoReader&() const { return *this->Reader; }
  132. };
  133. using AppendixMap = std::map<std::string, Appendix>;
  134. AppendixMap FindAppendices(std::string const& base,
  135. cmPackageInfoReader const& baseReader) const;
  136. enum RequiredStatus
  137. {
  138. Optional,
  139. OptionalExplicit,
  140. RequiredExplicit,
  141. RequiredFromPackageVar,
  142. RequiredFromFindVar
  143. };
  144. bool FindPackageDependencies(std::string const& filePath,
  145. cmPackageInfoReader const& reader,
  146. RequiredStatus required);
  147. bool ImportPackageTargets(cmPackageState& packageState,
  148. std::string const& filePath,
  149. cmPackageInfoReader& reader);
  150. void StoreVersionFound();
  151. void SetConfigDirCacheVariable(std::string const& value);
  152. void PushFindPackageRootPathStack();
  153. void PopFindPackageRootPathStack();
  154. class PushPopRootPathStack;
  155. enum class FoundPackageMode
  156. {
  157. None,
  158. Module,
  159. Config,
  160. Cps,
  161. Provider,
  162. };
  163. void ComputePrefixes();
  164. void FillPrefixesPackageRedirect();
  165. void FillPrefixesPackageRoot();
  166. void FillPrefixesCMakeEnvironment();
  167. void FillPrefixesCMakeVariable();
  168. void FillPrefixesSystemEnvironment();
  169. void FillPrefixesUserRegistry();
  170. void FillPrefixesSystemRegistry();
  171. void FillPrefixesCMakeSystemVariable();
  172. void FillPrefixesUserGuess();
  173. void FillPrefixesUserHints();
  174. void LoadPackageRegistryDir(std::string const& dir, cmSearchPath& outPaths);
  175. void LoadPackageRegistryWinUser();
  176. void LoadPackageRegistryWinSystem();
  177. void LoadPackageRegistryWin(bool user, unsigned int view,
  178. cmSearchPath& outPaths);
  179. bool CheckPackageRegistryEntry(std::string const& fname,
  180. cmSearchPath& outPaths);
  181. bool SearchDirectory(std::string const& dir, PackageDescriptionType type);
  182. bool CheckDirectory(std::string const& dir, PackageDescriptionType type);
  183. bool FindConfigFile(std::string const& dir, PackageDescriptionType type,
  184. std::string& file, FoundPackageMode& foundMode);
  185. bool CheckVersion(std::string const& config_file);
  186. bool CheckVersionFile(std::string const& version_file,
  187. std::string& result_version);
  188. bool SearchPrefix(std::string const& prefix);
  189. bool SearchFrameworkPrefix(std::string const& prefix);
  190. bool SearchAppBundlePrefix(std::string const& prefix);
  191. bool SearchEnvironmentPrefix(std::string const& prefix);
  192. bool IsRequired() const;
  193. struct OriginalDef
  194. {
  195. bool exists;
  196. std::string value;
  197. };
  198. std::map<std::string, OriginalDef> OriginalDefs;
  199. std::map<std::string, cmPolicies::PolicyID> DeprecatedFindModules;
  200. static cm::string_view const VERSION_ENDPOINT_INCLUDED;
  201. static cm::string_view const VERSION_ENDPOINT_EXCLUDED;
  202. std::string Name;
  203. std::string Variable;
  204. std::string VersionComplete;
  205. std::string VersionRange;
  206. cm::string_view VersionRangeMin;
  207. cm::string_view VersionRangeMax;
  208. std::string Version;
  209. unsigned int VersionMajor = 0;
  210. unsigned int VersionMinor = 0;
  211. unsigned int VersionPatch = 0;
  212. unsigned int VersionTweak = 0;
  213. unsigned int VersionCount = 0;
  214. std::string VersionMax;
  215. unsigned int VersionMaxMajor = 0;
  216. unsigned int VersionMaxMinor = 0;
  217. unsigned int VersionMaxPatch = 0;
  218. unsigned int VersionMaxTweak = 0;
  219. unsigned int VersionMaxCount = 0;
  220. bool VersionExact = false;
  221. std::string FileFound;
  222. FoundPackageMode FileFoundMode = FoundPackageMode::None;
  223. std::string VersionFound;
  224. unsigned int VersionFoundMajor = 0;
  225. unsigned int VersionFoundMinor = 0;
  226. unsigned int VersionFoundPatch = 0;
  227. unsigned int VersionFoundTweak = 0;
  228. unsigned int VersionFoundCount = 0;
  229. KWIML_INT_uint64_t RequiredCMakeVersion = 0;
  230. bool BypassProvider = false;
  231. bool Quiet = false;
  232. RequiredStatus Required = RequiredStatus::Optional;
  233. bool UseCpsFiles = false;
  234. bool UseConfigFiles = true;
  235. bool UseFindModules = true;
  236. bool NoUserRegistry = false;
  237. bool NoSystemRegistry = false;
  238. bool UseLib32Paths = false;
  239. bool UseLib64Paths = false;
  240. bool UseLibx32Paths = false;
  241. bool UseRealPath = false;
  242. bool PolicyScope = true;
  243. bool GlobalScope = false;
  244. bool RegistryViewDefined = false;
  245. std::string LibraryArchitecture;
  246. std::vector<std::string> Names;
  247. std::set<std::string> IgnoredPaths;
  248. std::set<std::string> IgnoredPrefixPaths;
  249. std::string Components;
  250. std::set<std::string> RequiredComponents;
  251. std::set<std::string> OptionalComponents;
  252. std::set<std::string> RequiredTargets;
  253. std::string DebugBuffer;
  254. enum class SearchResult
  255. {
  256. InsufficientVersion,
  257. NoExist,
  258. Ignored,
  259. NoConfigFile,
  260. NotFound,
  261. };
  262. struct ConsideredPath
  263. {
  264. ConsideredPath(std::string path, FoundPackageMode mode,
  265. SearchResult reason)
  266. : Path(std::move(path))
  267. , Mode(mode)
  268. , Reason(reason)
  269. {
  270. }
  271. std::string Path;
  272. FoundPackageMode Mode;
  273. SearchResult Reason;
  274. std::string Message;
  275. };
  276. std::vector<ConsideredPath> ConsideredPaths;
  277. static FoundPackageMode FoundMode(PackageDescriptionType type);
  278. struct ConfigName
  279. {
  280. ConfigName(std::string const& name, PackageDescriptionType type)
  281. : Name{ name }
  282. , Type{ type }
  283. {
  284. }
  285. ConfigName(std::string&& name, PackageDescriptionType type)
  286. : Name{ std::move(name) }
  287. , Type{ type }
  288. {
  289. }
  290. ConfigName(ConfigName const&) = default;
  291. ConfigName(ConfigName&&) = default;
  292. std::string Name;
  293. PackageDescriptionType Type;
  294. };
  295. std::vector<ConfigName> Configs;
  296. class FlushDebugBufferOnExit;
  297. /*! the selected sortOrder (None by default)*/
  298. SortOrderType SortOrder = None;
  299. /*! the selected sortDirection (Asc by default)*/
  300. SortDirectionType SortDirection = Asc;
  301. struct ConfigFileInfo
  302. {
  303. std::string filename;
  304. std::string version;
  305. bool operator<(ConfigFileInfo const& rhs) const
  306. {
  307. return this->filename < rhs.filename;
  308. }
  309. bool operator==(ConfigFileInfo const& rhs) const
  310. {
  311. return this->filename == rhs.filename;
  312. }
  313. bool operator!=(ConfigFileInfo const& rhs) const
  314. {
  315. return !(*this == rhs);
  316. }
  317. };
  318. std::vector<ConfigFileInfo> ConsideredConfigs;
  319. std::unique_ptr<cmPackageInfoReader> CpsReader;
  320. AppendixMap CpsAppendices;
  321. friend struct std::hash<ConfigFileInfo>;
  322. friend class cmFindPackageDebugState;
  323. };
  324. namespace std {
  325. template <>
  326. struct hash<cmFindPackageCommand::ConfigFileInfo>
  327. {
  328. using argument_type = cmFindPackageCommand::ConfigFileInfo;
  329. using result_type = size_t;
  330. result_type operator()(argument_type const& s) const noexcept
  331. {
  332. result_type const h(std::hash<std::string>{}(s.filename));
  333. return h;
  334. }
  335. };
  336. }
  337. bool cmFindPackage(std::vector<std::string> const& args,
  338. cmExecutionStatus& status);
  339. class cmFindPackageDebugState : public cmFindCommonDebugState
  340. {
  341. public:
  342. explicit cmFindPackageDebugState(cmFindPackageCommand const* findPackage);
  343. ~cmFindPackageDebugState() override;
  344. private:
  345. void FoundAtImpl(std::string const& path, std::string regexName) override;
  346. void FailedAtImpl(std::string const& path, std::string regexName) override;
  347. void WriteDebug() const override;
  348. #ifndef CMAKE_BOOTSTRAP
  349. void WriteEvent(cmConfigureLog& log, cmMakefile const& mf) const override;
  350. std::vector<std::pair<VariableSource, std::string>> ExtraSearchVariables()
  351. const override;
  352. #endif
  353. cmFindPackageCommand const* const FindPackageCommand;
  354. };