Coverage Report

Created: 2026-02-09 06:05

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