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