cmCMakePresetsGraph.h 15 KB

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