cmCMakePresetsGraph.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #pragma once
  4. #include "cmConfigure.h" // IWYU pragma: keep
  5. #include <functional>
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include <unordered_set>
  10. #include <utility>
  11. #include <vector>
  12. #include <cm/optional>
  13. class cmCMakePresetsGraph
  14. {
  15. public:
  16. enum class ReadFileResult
  17. {
  18. READ_OK,
  19. FILE_NOT_FOUND,
  20. JSON_PARSE_ERROR,
  21. INVALID_ROOT,
  22. NO_VERSION,
  23. INVALID_VERSION,
  24. UNRECOGNIZED_VERSION,
  25. INVALID_CMAKE_VERSION,
  26. UNRECOGNIZED_CMAKE_VERSION,
  27. INVALID_PRESETS,
  28. INVALID_PRESET,
  29. INVALID_VARIABLE,
  30. DUPLICATE_PRESETS,
  31. CYCLIC_PRESET_INHERITANCE,
  32. PRESET_UNREACHABLE_FROM_FILE,
  33. INVALID_MACRO_EXPANSION,
  34. BUILD_TEST_PRESETS_UNSUPPORTED,
  35. INVALID_CONFIGURE_PRESET,
  36. INSTALL_PREFIX_UNSUPPORTED,
  37. INVALID_CONDITION,
  38. CONDITION_UNSUPPORTED,
  39. TOOLCHAIN_FILE_UNSUPPORTED,
  40. CYCLIC_INCLUDE,
  41. };
  42. enum class ArchToolsetStrategy
  43. {
  44. Set,
  45. External,
  46. };
  47. class CacheVariable
  48. {
  49. public:
  50. std::string Type;
  51. std::string Value;
  52. };
  53. class Condition;
  54. class File
  55. {
  56. public:
  57. std::string Filename;
  58. int Version;
  59. std::unordered_set<File*> ReachableFiles;
  60. };
  61. class Preset
  62. {
  63. public:
  64. Preset() = default;
  65. Preset(Preset&& /*other*/) = default;
  66. Preset(const Preset& /*other*/) = default;
  67. Preset& operator=(const Preset& /*other*/) = default;
  68. virtual ~Preset() = default;
  69. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  70. Preset& operator=(Preset&& /*other*/) = default;
  71. #else
  72. // The move assignment operators for several STL classes did not become
  73. // noexcept until C++17, which causes some tools to warn about this move
  74. // assignment operator throwing an exception when it shouldn't.
  75. Preset& operator=(Preset&& /*other*/) = delete;
  76. #endif
  77. std::string Name;
  78. std::vector<std::string> Inherits;
  79. bool Hidden;
  80. File* OriginFile;
  81. std::string DisplayName;
  82. std::string Description;
  83. std::shared_ptr<Condition> ConditionEvaluator;
  84. bool ConditionResult = true;
  85. std::map<std::string, cm::optional<std::string>> Environment;
  86. virtual ReadFileResult VisitPresetInherit(const Preset& parent) = 0;
  87. virtual ReadFileResult VisitPresetBeforeInherit()
  88. {
  89. return ReadFileResult::READ_OK;
  90. }
  91. virtual ReadFileResult VisitPresetAfterInherit(int /* version */)
  92. {
  93. return ReadFileResult::READ_OK;
  94. }
  95. };
  96. class ConfigurePreset : public Preset
  97. {
  98. public:
  99. ConfigurePreset() = default;
  100. ConfigurePreset(ConfigurePreset&& /*other*/) = default;
  101. ConfigurePreset(const ConfigurePreset& /*other*/) = default;
  102. ConfigurePreset& operator=(const ConfigurePreset& /*other*/) = default;
  103. ~ConfigurePreset() override = default;
  104. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  105. ConfigurePreset& operator=(ConfigurePreset&& /*other*/) = default;
  106. #else
  107. // The move assignment operators for several STL classes did not become
  108. // noexcept until C++17, which causes some tools to warn about this move
  109. // assignment operator throwing an exception when it shouldn't.
  110. ConfigurePreset& operator=(ConfigurePreset&& /*other*/) = delete;
  111. #endif
  112. std::string Generator;
  113. std::string Architecture;
  114. cm::optional<ArchToolsetStrategy> ArchitectureStrategy;
  115. std::string Toolset;
  116. cm::optional<ArchToolsetStrategy> ToolsetStrategy;
  117. std::string ToolchainFile;
  118. std::string BinaryDir;
  119. std::string InstallDir;
  120. std::map<std::string, cm::optional<CacheVariable>> CacheVariables;
  121. cm::optional<bool> WarnDev;
  122. cm::optional<bool> ErrorDev;
  123. cm::optional<bool> WarnDeprecated;
  124. cm::optional<bool> ErrorDeprecated;
  125. cm::optional<bool> WarnUninitialized;
  126. cm::optional<bool> WarnUnusedCli;
  127. cm::optional<bool> WarnSystemVars;
  128. cm::optional<bool> DebugOutput;
  129. cm::optional<bool> DebugTryCompile;
  130. cm::optional<bool> DebugFind;
  131. ReadFileResult VisitPresetInherit(const Preset& parent) override;
  132. ReadFileResult VisitPresetBeforeInherit() override;
  133. ReadFileResult VisitPresetAfterInherit(int version) override;
  134. };
  135. class BuildPreset : public Preset
  136. {
  137. public:
  138. BuildPreset() = default;
  139. BuildPreset(BuildPreset&& /*other*/) = default;
  140. BuildPreset(const BuildPreset& /*other*/) = default;
  141. BuildPreset& operator=(const BuildPreset& /*other*/) = default;
  142. ~BuildPreset() override = default;
  143. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  144. BuildPreset& operator=(BuildPreset&& /*other*/) = default;
  145. #else
  146. // The move assignment operators for several STL classes did not become
  147. // noexcept until C++17, which causes some tools to warn about this move
  148. // assignment operator throwing an exception when it shouldn't.
  149. BuildPreset& operator=(BuildPreset&& /*other*/) = delete;
  150. #endif
  151. std::string ConfigurePreset;
  152. cm::optional<bool> InheritConfigureEnvironment;
  153. cm::optional<int> Jobs;
  154. std::vector<std::string> Targets;
  155. std::string Configuration;
  156. cm::optional<bool> CleanFirst;
  157. cm::optional<bool> Verbose;
  158. std::vector<std::string> NativeToolOptions;
  159. ReadFileResult VisitPresetInherit(const Preset& parent) override;
  160. ReadFileResult VisitPresetAfterInherit(int /* version */) override;
  161. };
  162. class TestPreset : public Preset
  163. {
  164. public:
  165. TestPreset() = default;
  166. TestPreset(TestPreset&& /*other*/) = default;
  167. TestPreset(const TestPreset& /*other*/) = default;
  168. TestPreset& operator=(const TestPreset& /*other*/) = default;
  169. ~TestPreset() override = default;
  170. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  171. TestPreset& operator=(TestPreset&& /*other*/) = default;
  172. #else
  173. // The move assignment operators for several STL classes did not become
  174. // noexcept until C++17, which causes some tools to warn about this move
  175. // assignment operator throwing an exception when it shouldn't.
  176. TestPreset& operator=(TestPreset&& /*other*/) = delete;
  177. #endif
  178. struct OutputOptions
  179. {
  180. enum class VerbosityEnum
  181. {
  182. Default,
  183. Verbose,
  184. Extra
  185. };
  186. cm::optional<bool> ShortProgress;
  187. cm::optional<VerbosityEnum> Verbosity;
  188. cm::optional<bool> Debug;
  189. cm::optional<bool> OutputOnFailure;
  190. cm::optional<bool> Quiet;
  191. std::string OutputLogFile;
  192. cm::optional<bool> LabelSummary;
  193. cm::optional<bool> SubprojectSummary;
  194. cm::optional<int> MaxPassedTestOutputSize;
  195. cm::optional<int> MaxFailedTestOutputSize;
  196. cm::optional<int> MaxTestNameWidth;
  197. };
  198. struct IncludeOptions
  199. {
  200. struct IndexOptions
  201. {
  202. cm::optional<int> Start;
  203. cm::optional<int> End;
  204. cm::optional<int> Stride;
  205. std::vector<int> SpecificTests;
  206. std::string IndexFile;
  207. };
  208. std::string Name;
  209. std::string Label;
  210. cm::optional<IndexOptions> Index;
  211. cm::optional<bool> UseUnion;
  212. };
  213. struct ExcludeOptions
  214. {
  215. struct FixturesOptions
  216. {
  217. std::string Any;
  218. std::string Setup;
  219. std::string Cleanup;
  220. };
  221. std::string Name;
  222. std::string Label;
  223. cm::optional<FixturesOptions> Fixtures;
  224. };
  225. struct FilterOptions
  226. {
  227. cm::optional<IncludeOptions> Include;
  228. cm::optional<ExcludeOptions> Exclude;
  229. };
  230. struct ExecutionOptions
  231. {
  232. enum class ShowOnlyEnum
  233. {
  234. Human,
  235. JsonV1
  236. };
  237. struct RepeatOptions
  238. {
  239. enum class ModeEnum
  240. {
  241. UntilFail,
  242. UntilPass,
  243. AfterTimeout
  244. };
  245. ModeEnum Mode;
  246. int Count;
  247. };
  248. enum class NoTestsActionEnum
  249. {
  250. Default,
  251. Error,
  252. Ignore
  253. };
  254. cm::optional<bool> StopOnFailure;
  255. cm::optional<bool> EnableFailover;
  256. cm::optional<int> Jobs;
  257. std::string ResourceSpecFile;
  258. cm::optional<int> TestLoad;
  259. cm::optional<ShowOnlyEnum> ShowOnly;
  260. cm::optional<RepeatOptions> Repeat;
  261. cm::optional<bool> InteractiveDebugging;
  262. cm::optional<bool> ScheduleRandom;
  263. cm::optional<int> Timeout;
  264. cm::optional<NoTestsActionEnum> NoTestsAction;
  265. };
  266. std::string ConfigurePreset;
  267. cm::optional<bool> InheritConfigureEnvironment;
  268. std::string Configuration;
  269. std::vector<std::string> OverwriteConfigurationFile;
  270. cm::optional<OutputOptions> Output;
  271. cm::optional<FilterOptions> Filter;
  272. cm::optional<ExecutionOptions> Execution;
  273. ReadFileResult VisitPresetInherit(const Preset& parent) override;
  274. ReadFileResult VisitPresetAfterInherit(int /* version */) override;
  275. };
  276. template <class T>
  277. class PresetPair
  278. {
  279. public:
  280. T Unexpanded;
  281. cm::optional<T> Expanded;
  282. };
  283. std::map<std::string, PresetPair<ConfigurePreset>> ConfigurePresets;
  284. std::map<std::string, PresetPair<BuildPreset>> BuildPresets;
  285. std::map<std::string, PresetPair<TestPreset>> TestPresets;
  286. std::vector<std::string> ConfigurePresetOrder;
  287. std::vector<std::string> BuildPresetOrder;
  288. std::vector<std::string> TestPresetOrder;
  289. std::string SourceDir;
  290. std::vector<std::unique_ptr<File>> Files;
  291. int GetVersion(const Preset& preset) const
  292. {
  293. return preset.OriginFile->Version;
  294. }
  295. static std::string GetFilename(const std::string& sourceDir);
  296. static std::string GetUserFilename(const std::string& sourceDir);
  297. ReadFileResult ReadProjectPresets(const std::string& sourceDir,
  298. bool allowNoFiles = false);
  299. static const char* ResultToString(ReadFileResult result);
  300. std::string GetGeneratorForPreset(const std::string& presetName) const
  301. {
  302. auto configurePresetName = presetName;
  303. auto buildPresetIterator = this->BuildPresets.find(presetName);
  304. if (buildPresetIterator != this->BuildPresets.end()) {
  305. configurePresetName =
  306. buildPresetIterator->second.Unexpanded.ConfigurePreset;
  307. } else {
  308. auto testPresetIterator = this->TestPresets.find(presetName);
  309. if (testPresetIterator != this->TestPresets.end()) {
  310. configurePresetName =
  311. testPresetIterator->second.Unexpanded.ConfigurePreset;
  312. }
  313. }
  314. auto configurePresetIterator =
  315. this->ConfigurePresets.find(configurePresetName);
  316. if (configurePresetIterator != this->ConfigurePresets.end()) {
  317. return configurePresetIterator->second.Unexpanded.Generator;
  318. }
  319. // This should only happen if the preset is hidden
  320. // or (for build or test presets) if ConfigurePreset is invalid.
  321. return "";
  322. }
  323. static void PrintPresets(
  324. const std::vector<const cmCMakePresetsGraph::Preset*>& presets);
  325. void PrintConfigurePresetList() const;
  326. void PrintConfigurePresetList(
  327. const std::function<bool(const ConfigurePreset&)>& filter) const;
  328. void PrintBuildPresetList() const;
  329. void PrintTestPresetList() const;
  330. void PrintAllPresets() const;
  331. private:
  332. enum class RootType
  333. {
  334. Project,
  335. User,
  336. };
  337. enum class ReadReason
  338. {
  339. Root,
  340. Included,
  341. };
  342. ReadFileResult ReadProjectPresetsInternal(bool allowNoFiles);
  343. ReadFileResult ReadJSONFile(const std::string& filename, RootType rootType,
  344. ReadReason readReason,
  345. std::vector<File*>& inProgressFiles,
  346. File*& file);
  347. void ClearPresets();
  348. };