cmCMakePresetsGraph.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  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. #include "CTest/cmCTestTypes.h"
  14. enum class PackageResolveMode;
  15. class cmCMakePresetsGraph
  16. {
  17. public:
  18. enum class ReadFileResult
  19. {
  20. READ_OK,
  21. FILE_NOT_FOUND,
  22. JSON_PARSE_ERROR,
  23. INVALID_ROOT,
  24. NO_VERSION,
  25. INVALID_VERSION,
  26. UNRECOGNIZED_VERSION,
  27. INVALID_CMAKE_VERSION,
  28. UNRECOGNIZED_CMAKE_VERSION,
  29. INVALID_PRESETS,
  30. INVALID_PRESET,
  31. INVALID_VARIABLE,
  32. DUPLICATE_PRESETS,
  33. CYCLIC_PRESET_INHERITANCE,
  34. INHERITED_PRESET_UNREACHABLE_FROM_FILE,
  35. CONFIGURE_PRESET_UNREACHABLE_FROM_FILE,
  36. INVALID_MACRO_EXPANSION,
  37. BUILD_TEST_PRESETS_UNSUPPORTED,
  38. PACKAGE_PRESETS_UNSUPPORTED,
  39. WORKFLOW_PRESETS_UNSUPPORTED,
  40. INCLUDE_UNSUPPORTED,
  41. INVALID_INCLUDE,
  42. INVALID_CONFIGURE_PRESET,
  43. INSTALL_PREFIX_UNSUPPORTED,
  44. INVALID_CONDITION,
  45. CONDITION_UNSUPPORTED,
  46. TOOLCHAIN_FILE_UNSUPPORTED,
  47. CYCLIC_INCLUDE,
  48. TEST_OUTPUT_TRUNCATION_UNSUPPORTED,
  49. INVALID_WORKFLOW_STEPS,
  50. WORKFLOW_STEP_UNREACHABLE_FROM_FILE,
  51. };
  52. std::string errors;
  53. enum class ArchToolsetStrategy
  54. {
  55. Set,
  56. External,
  57. };
  58. class CacheVariable
  59. {
  60. public:
  61. std::string Type;
  62. std::string Value;
  63. };
  64. class Condition;
  65. class File
  66. {
  67. public:
  68. std::string Filename;
  69. int Version;
  70. std::unordered_set<File*> ReachableFiles;
  71. };
  72. class Preset
  73. {
  74. public:
  75. Preset() = default;
  76. Preset(Preset&& /*other*/) = default;
  77. Preset(const Preset& /*other*/) = default;
  78. Preset& operator=(const Preset& /*other*/) = default;
  79. virtual ~Preset() = default;
  80. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  81. Preset& operator=(Preset&& /*other*/) = default;
  82. #else
  83. // The move assignment operators for several STL classes did not become
  84. // noexcept until C++17, which causes some tools to warn about this move
  85. // assignment operator throwing an exception when it shouldn't.
  86. Preset& operator=(Preset&& /*other*/) = delete;
  87. #endif
  88. std::string Name;
  89. std::vector<std::string> Inherits;
  90. bool Hidden = false;
  91. File* OriginFile;
  92. std::string DisplayName;
  93. std::string Description;
  94. std::shared_ptr<Condition> ConditionEvaluator;
  95. bool ConditionResult = true;
  96. std::map<std::string, cm::optional<std::string>> Environment;
  97. virtual ReadFileResult VisitPresetInherit(const Preset& parent) = 0;
  98. virtual ReadFileResult VisitPresetBeforeInherit()
  99. {
  100. return ReadFileResult::READ_OK;
  101. }
  102. virtual ReadFileResult VisitPresetAfterInherit(int /* version */)
  103. {
  104. return ReadFileResult::READ_OK;
  105. }
  106. };
  107. class ConfigurePreset : public Preset
  108. {
  109. public:
  110. ConfigurePreset() = default;
  111. ConfigurePreset(ConfigurePreset&& /*other*/) = default;
  112. ConfigurePreset(const ConfigurePreset& /*other*/) = default;
  113. ConfigurePreset& operator=(const ConfigurePreset& /*other*/) = default;
  114. ~ConfigurePreset() override = default;
  115. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  116. ConfigurePreset& operator=(ConfigurePreset&& /*other*/) = default;
  117. #else
  118. // The move assignment operators for several STL classes did not become
  119. // noexcept until C++17, which causes some tools to warn about this move
  120. // assignment operator throwing an exception when it shouldn't.
  121. ConfigurePreset& operator=(ConfigurePreset&& /*other*/) = delete;
  122. #endif
  123. std::string Generator;
  124. std::string Architecture;
  125. cm::optional<ArchToolsetStrategy> ArchitectureStrategy;
  126. std::string Toolset;
  127. cm::optional<ArchToolsetStrategy> ToolsetStrategy;
  128. std::string ToolchainFile;
  129. std::string BinaryDir;
  130. std::string InstallDir;
  131. std::map<std::string, cm::optional<CacheVariable>> CacheVariables;
  132. cm::optional<bool> WarnDev;
  133. cm::optional<bool> ErrorDev;
  134. cm::optional<bool> WarnDeprecated;
  135. cm::optional<bool> ErrorDeprecated;
  136. cm::optional<bool> WarnUninitialized;
  137. cm::optional<bool> WarnUnusedCli;
  138. cm::optional<bool> WarnSystemVars;
  139. cm::optional<bool> DebugOutput;
  140. cm::optional<bool> DebugTryCompile;
  141. cm::optional<bool> DebugFind;
  142. ReadFileResult VisitPresetInherit(const Preset& parent) override;
  143. ReadFileResult VisitPresetBeforeInherit() override;
  144. ReadFileResult VisitPresetAfterInherit(int version) override;
  145. };
  146. class BuildPreset : public Preset
  147. {
  148. public:
  149. BuildPreset() = default;
  150. BuildPreset(BuildPreset&& /*other*/) = default;
  151. BuildPreset(const BuildPreset& /*other*/) = default;
  152. BuildPreset& operator=(const BuildPreset& /*other*/) = default;
  153. ~BuildPreset() override = default;
  154. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  155. BuildPreset& operator=(BuildPreset&& /*other*/) = default;
  156. #else
  157. // The move assignment operators for several STL classes did not become
  158. // noexcept until C++17, which causes some tools to warn about this move
  159. // assignment operator throwing an exception when it shouldn't.
  160. BuildPreset& operator=(BuildPreset&& /*other*/) = delete;
  161. #endif
  162. std::string ConfigurePreset;
  163. cm::optional<bool> InheritConfigureEnvironment;
  164. cm::optional<int> Jobs;
  165. std::vector<std::string> Targets;
  166. std::string Configuration;
  167. cm::optional<bool> CleanFirst;
  168. cm::optional<bool> Verbose;
  169. std::vector<std::string> NativeToolOptions;
  170. cm::optional<PackageResolveMode> ResolvePackageReferences;
  171. ReadFileResult VisitPresetInherit(const Preset& parent) override;
  172. ReadFileResult VisitPresetAfterInherit(int /* version */) override;
  173. };
  174. class TestPreset : public Preset
  175. {
  176. public:
  177. TestPreset() = default;
  178. TestPreset(TestPreset&& /*other*/) = default;
  179. TestPreset(const TestPreset& /*other*/) = default;
  180. TestPreset& operator=(const TestPreset& /*other*/) = default;
  181. ~TestPreset() override = default;
  182. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  183. TestPreset& operator=(TestPreset&& /*other*/) = default;
  184. #else
  185. // The move assignment operators for several STL classes did not become
  186. // noexcept until C++17, which causes some tools to warn about this move
  187. // assignment operator throwing an exception when it shouldn't.
  188. TestPreset& operator=(TestPreset&& /*other*/) = delete;
  189. #endif
  190. struct OutputOptions
  191. {
  192. enum class VerbosityEnum
  193. {
  194. Default,
  195. Verbose,
  196. Extra
  197. };
  198. cm::optional<bool> ShortProgress;
  199. cm::optional<VerbosityEnum> Verbosity;
  200. cm::optional<bool> Debug;
  201. cm::optional<bool> OutputOnFailure;
  202. cm::optional<bool> Quiet;
  203. std::string OutputLogFile;
  204. cm::optional<bool> LabelSummary;
  205. cm::optional<bool> SubprojectSummary;
  206. cm::optional<int> MaxPassedTestOutputSize;
  207. cm::optional<int> MaxFailedTestOutputSize;
  208. cm::optional<cmCTestTypes::TruncationMode> TestOutputTruncation;
  209. cm::optional<int> MaxTestNameWidth;
  210. };
  211. struct IncludeOptions
  212. {
  213. struct IndexOptions
  214. {
  215. cm::optional<int> Start;
  216. cm::optional<int> End;
  217. cm::optional<int> Stride;
  218. std::vector<int> SpecificTests;
  219. std::string IndexFile;
  220. };
  221. std::string Name;
  222. std::string Label;
  223. cm::optional<IndexOptions> Index;
  224. cm::optional<bool> UseUnion;
  225. };
  226. struct ExcludeOptions
  227. {
  228. struct FixturesOptions
  229. {
  230. std::string Any;
  231. std::string Setup;
  232. std::string Cleanup;
  233. };
  234. std::string Name;
  235. std::string Label;
  236. cm::optional<FixturesOptions> Fixtures;
  237. };
  238. struct FilterOptions
  239. {
  240. cm::optional<IncludeOptions> Include;
  241. cm::optional<ExcludeOptions> Exclude;
  242. };
  243. struct ExecutionOptions
  244. {
  245. enum class ShowOnlyEnum
  246. {
  247. Human,
  248. JsonV1
  249. };
  250. struct RepeatOptions
  251. {
  252. enum class ModeEnum
  253. {
  254. UntilFail,
  255. UntilPass,
  256. AfterTimeout
  257. };
  258. ModeEnum Mode;
  259. int Count;
  260. };
  261. enum class NoTestsActionEnum
  262. {
  263. Default,
  264. Error,
  265. Ignore
  266. };
  267. cm::optional<bool> StopOnFailure;
  268. cm::optional<bool> EnableFailover;
  269. cm::optional<int> Jobs;
  270. std::string ResourceSpecFile;
  271. cm::optional<int> TestLoad;
  272. cm::optional<ShowOnlyEnum> ShowOnly;
  273. cm::optional<RepeatOptions> Repeat;
  274. cm::optional<bool> InteractiveDebugging;
  275. cm::optional<bool> ScheduleRandom;
  276. cm::optional<int> Timeout;
  277. cm::optional<NoTestsActionEnum> NoTestsAction;
  278. };
  279. std::string ConfigurePreset;
  280. cm::optional<bool> InheritConfigureEnvironment;
  281. std::string Configuration;
  282. std::vector<std::string> OverwriteConfigurationFile;
  283. cm::optional<OutputOptions> Output;
  284. cm::optional<FilterOptions> Filter;
  285. cm::optional<ExecutionOptions> Execution;
  286. ReadFileResult VisitPresetInherit(const Preset& parent) override;
  287. ReadFileResult VisitPresetAfterInherit(int /* version */) override;
  288. };
  289. class PackagePreset : public Preset
  290. {
  291. public:
  292. PackagePreset() = default;
  293. PackagePreset(PackagePreset&& /*other*/) = default;
  294. PackagePreset(const PackagePreset& /*other*/) = default;
  295. PackagePreset& operator=(const PackagePreset& /*other*/) = default;
  296. ~PackagePreset() override = default;
  297. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  298. PackagePreset& operator=(PackagePreset&& /*other*/) = default;
  299. #else
  300. // The move assignment operators for several STL classes did not become
  301. // noexcept until C++17, which causes some tools to warn about this move
  302. // assignment operator throwing an exception when it shouldn't.
  303. PackagePreset& operator=(PackagePreset&& /*other*/) = delete;
  304. #endif
  305. std::string ConfigurePreset;
  306. cm::optional<bool> InheritConfigureEnvironment;
  307. std::vector<std::string> Generators;
  308. std::vector<std::string> Configurations;
  309. std::map<std::string, std::string> Variables;
  310. std::string ConfigFile;
  311. cm::optional<bool> DebugOutput;
  312. cm::optional<bool> VerboseOutput;
  313. std::string PackageName;
  314. std::string PackageVersion;
  315. std::string PackageDirectory;
  316. std::string VendorName;
  317. ReadFileResult VisitPresetInherit(const Preset& parent) override;
  318. ReadFileResult VisitPresetAfterInherit(int /* version */) override;
  319. };
  320. class WorkflowPreset : public Preset
  321. {
  322. public:
  323. WorkflowPreset() = default;
  324. WorkflowPreset(WorkflowPreset&& /*other*/) = default;
  325. WorkflowPreset(const WorkflowPreset& /*other*/) = default;
  326. WorkflowPreset& operator=(const WorkflowPreset& /*other*/) = default;
  327. ~WorkflowPreset() override = default;
  328. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  329. WorkflowPreset& operator=(WorkflowPreset&& /*other*/) = default;
  330. #else
  331. // The move assignment operators for several STL classes did not become
  332. // noexcept until C++17, which causes some tools to warn about this move
  333. // assignment operator throwing an exception when it shouldn't.
  334. WorkflowPreset& operator=(WorkflowPreset&& /*other*/) = delete;
  335. #endif
  336. class WorkflowStep
  337. {
  338. public:
  339. enum class Type
  340. {
  341. Configure,
  342. Build,
  343. Test,
  344. Package,
  345. };
  346. Type PresetType;
  347. std::string PresetName;
  348. };
  349. std::vector<WorkflowStep> Steps;
  350. ReadFileResult VisitPresetInherit(const Preset& parent) override;
  351. ReadFileResult VisitPresetAfterInherit(int /* version */) override;
  352. };
  353. template <class T>
  354. class PresetPair
  355. {
  356. public:
  357. T Unexpanded;
  358. cm::optional<T> Expanded;
  359. };
  360. std::map<std::string, PresetPair<ConfigurePreset>> ConfigurePresets;
  361. std::map<std::string, PresetPair<BuildPreset>> BuildPresets;
  362. std::map<std::string, PresetPair<TestPreset>> TestPresets;
  363. std::map<std::string, PresetPair<PackagePreset>> PackagePresets;
  364. std::map<std::string, PresetPair<WorkflowPreset>> WorkflowPresets;
  365. std::vector<std::string> ConfigurePresetOrder;
  366. std::vector<std::string> BuildPresetOrder;
  367. std::vector<std::string> TestPresetOrder;
  368. std::vector<std::string> PackagePresetOrder;
  369. std::vector<std::string> WorkflowPresetOrder;
  370. std::string SourceDir;
  371. std::vector<std::unique_ptr<File>> Files;
  372. int GetVersion(const Preset& preset) const
  373. {
  374. return preset.OriginFile->Version;
  375. }
  376. static std::string GetFilename(const std::string& sourceDir);
  377. static std::string GetUserFilename(const std::string& sourceDir);
  378. ReadFileResult ReadProjectPresets(const std::string& sourceDir,
  379. bool allowNoFiles = false);
  380. static const char* ResultToString(ReadFileResult result);
  381. std::string GetGeneratorForPreset(const std::string& presetName) const
  382. {
  383. auto configurePresetName = presetName;
  384. auto buildPresetIterator = this->BuildPresets.find(presetName);
  385. if (buildPresetIterator != this->BuildPresets.end()) {
  386. configurePresetName =
  387. buildPresetIterator->second.Unexpanded.ConfigurePreset;
  388. } else {
  389. auto testPresetIterator = this->TestPresets.find(presetName);
  390. if (testPresetIterator != this->TestPresets.end()) {
  391. configurePresetName =
  392. testPresetIterator->second.Unexpanded.ConfigurePreset;
  393. }
  394. }
  395. auto configurePresetIterator =
  396. this->ConfigurePresets.find(configurePresetName);
  397. if (configurePresetIterator != this->ConfigurePresets.end()) {
  398. return configurePresetIterator->second.Unexpanded.Generator;
  399. }
  400. // This should only happen if the preset is hidden
  401. // or (for build or test presets) if ConfigurePreset is invalid.
  402. return "";
  403. }
  404. enum class PrintPrecedingNewline
  405. {
  406. False,
  407. True,
  408. };
  409. static void printPrecedingNewline(PrintPrecedingNewline* p);
  410. static void PrintPresets(
  411. const std::vector<const cmCMakePresetsGraph::Preset*>& presets);
  412. void PrintConfigurePresetList(
  413. PrintPrecedingNewline* newline = nullptr) const;
  414. void PrintConfigurePresetList(
  415. const std::function<bool(const ConfigurePreset&)>& filter,
  416. PrintPrecedingNewline* newline = nullptr) const;
  417. void PrintBuildPresetList(PrintPrecedingNewline* newline = nullptr) const;
  418. void PrintTestPresetList(PrintPrecedingNewline* newline = nullptr) const;
  419. void PrintPackagePresetList(PrintPrecedingNewline* newline = nullptr) const;
  420. void PrintPackagePresetList(
  421. const std::function<bool(const PackagePreset&)>& filter,
  422. PrintPrecedingNewline* newline = nullptr) const;
  423. void PrintWorkflowPresetList(PrintPrecedingNewline* newline = nullptr) const;
  424. void PrintAllPresets() const;
  425. private:
  426. enum class RootType
  427. {
  428. Project,
  429. User,
  430. };
  431. enum class ReadReason
  432. {
  433. Root,
  434. Included,
  435. };
  436. ReadFileResult ReadProjectPresetsInternal(bool allowNoFiles);
  437. ReadFileResult ReadJSONFile(const std::string& filename, RootType rootType,
  438. ReadReason readReason,
  439. std::vector<File*>& inProgressFiles, File*& file,
  440. std::string& errMsg);
  441. void ClearPresets();
  442. };