Coverage Report

Created: 2026-06-15 07:03

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 <vector>
13
14
#include <cm/optional>
15
16
#include "cmDiagnostics.h"
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
  struct CacheVariable
44
  {
45
    std::string Type;
46
    std::string Value;
47
  };
48
49
  class Condition;
50
51
  struct File
52
  {
53
    std::unordered_set<File*> ReachableFiles;
54
    std::string Filename;
55
    int Version;
56
  };
57
58
  class Preset
59
  {
60
  public:
61
0
    Preset() = default;
62
0
    Preset(Preset&& /*other*/) = default;
63
0
    Preset(Preset const& /*other*/) = default;
64
0
    Preset& operator=(Preset const& /*other*/) = default;
65
0
    virtual ~Preset() = default;
66
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
67
    Preset& operator=(Preset&& /*other*/) = default;
68
#else
69
    // The move assignment operators for several STL classes did not become
70
    // noexcept until C++17, which causes some tools to warn about this move
71
    // assignment operator throwing an exception when it shouldn't.
72
    Preset& operator=(Preset&& /*other*/) = delete;
73
#endif
74
75
    std::string Name;
76
    std::vector<std::string> Inherits;
77
    bool Hidden = false;
78
    File* OriginFile;
79
    std::string DisplayName;
80
    std::string Description;
81
82
    std::shared_ptr<Condition> ConditionEvaluator;
83
    bool ConditionResult = true;
84
85
    std::map<std::string, cm::optional<std::string>> Environment;
86
87
    std::string ErrorDetail;
88
89
    virtual bool VisitPresetInherit(Preset const& parent) = 0;
90
0
    virtual bool VisitPresetBeforeInherit() { return true; }
91
92
    virtual bool VisitPresetAfterInherit(int /* version */,
93
                                         cmJSONState* /*state*/)
94
0
    {
95
0
      return true;
96
0
    }
97
  };
98
99
  class ConfigurePreset : public Preset
100
  {
101
  public:
102
0
    ConfigurePreset() = default;
103
0
    ConfigurePreset(ConfigurePreset&& /*other*/) = default;
104
0
    ConfigurePreset(ConfigurePreset const& /*other*/) = default;
105
0
    ConfigurePreset& operator=(ConfigurePreset const& /*other*/) = default;
106
0
    ~ConfigurePreset() override = default;
107
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
108
    ConfigurePreset& operator=(ConfigurePreset&& /*other*/) = default;
109
#else
110
    // The move assignment operators for several STL classes did not become
111
    // noexcept until C++17, which causes some tools to warn about this move
112
    // assignment operator throwing an exception when it shouldn't.
113
    ConfigurePreset& operator=(ConfigurePreset&& /*other*/) = delete;
114
#endif
115
116
    std::string Generator;
117
    std::string Architecture;
118
    cm::optional<ArchToolsetStrategy> ArchitectureStrategy;
119
    std::string Toolset;
120
    cm::optional<ArchToolsetStrategy> ToolsetStrategy;
121
    std::string ToolchainFile;
122
    std::string GraphVizFile;
123
    std::string BinaryDir;
124
    std::string InstallDir;
125
126
    std::map<std::string, cm::optional<CacheVariable>> CacheVariables;
127
128
    std::map<cmDiagnosticCategory, bool> Warnings;
129
    std::map<cmDiagnosticCategory, bool> Errors;
130
    cm::optional<bool> WarnSystemVars;
131
    cm::optional<bool> WarnDev;  // Deprecated synonym for Warnings.CMD_AUTHOR
132
    cm::optional<bool> ErrorDev; // Deprecated synonym for Errors.CMD_AUTHOR
133
134
    cm::optional<bool> DebugOutput;
135
    cm::optional<bool> DebugTryCompile;
136
    cm::optional<bool> DebugFind;
137
138
    cm::optional<TraceEnableMode> TraceMode;
139
    cm::optional<cmTraceEnums::TraceOutputFormat> TraceFormat;
140
    std::vector<std::string> TraceSource;
141
    std::string TraceRedirect;
142
143
    bool VisitPresetInherit(Preset const& parent) override;
144
    bool VisitPresetBeforeInherit() override;
145
    bool VisitPresetAfterInherit(int version, cmJSONState* state) override;
146
147
0
    static char const* kind() { return "configure"; }
148
  };
149
150
  class BuildPreset : public Preset
151
  {
152
  public:
153
0
    BuildPreset() = default;
154
0
    BuildPreset(BuildPreset&& /*other*/) = default;
155
0
    BuildPreset(BuildPreset const& /*other*/) = default;
156
0
    BuildPreset& operator=(BuildPreset const& /*other*/) = default;
157
0
    ~BuildPreset() override = default;
158
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
159
    BuildPreset& operator=(BuildPreset&& /*other*/) = default;
160
#else
161
    // The move assignment operators for several STL classes did not become
162
    // noexcept until C++17, which causes some tools to warn about this move
163
    // assignment operator throwing an exception when it shouldn't.
164
    BuildPreset& operator=(BuildPreset&& /*other*/) = delete;
165
#endif
166
167
    std::string ConfigurePreset;
168
    cm::optional<bool> InheritConfigureEnvironment;
169
    cm::optional<unsigned int> Jobs;
170
    std::vector<std::string> Targets;
171
    std::string Configuration;
172
    cm::optional<bool> CleanFirst;
173
    cm::optional<bool> Verbose;
174
    std::vector<std::string> NativeToolOptions;
175
    cm::optional<PackageResolveMode> ResolvePackageReferences;
176
177
    bool VisitPresetInherit(Preset const& parent) override;
178
    bool VisitPresetAfterInherit(int /* version */,
179
                                 cmJSONState* /*state*/) override;
180
181
0
    static char const* kind() { return "build"; }
182
  };
183
184
  class TestPreset : public Preset
185
  {
186
  public:
187
0
    TestPreset() = default;
188
0
    TestPreset(TestPreset&& /*other*/) = default;
189
0
    TestPreset(TestPreset const& /*other*/) = default;
190
0
    TestPreset& operator=(TestPreset const& /*other*/) = default;
191
0
    ~TestPreset() override = default;
192
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
193
    TestPreset& operator=(TestPreset&& /*other*/) = default;
194
#else
195
    // The move assignment operators for several STL classes did not become
196
    // noexcept until C++17, which causes some tools to warn about this move
197
    // assignment operator throwing an exception when it shouldn't.
198
    TestPreset& operator=(TestPreset&& /*other*/) = delete;
199
#endif
200
201
    struct OutputOptions
202
    {
203
      enum class VerbosityEnum
204
      {
205
        Default,
206
        Verbose,
207
        Extra
208
      };
209
210
      cm::optional<bool> ShortProgress;
211
      cm::optional<VerbosityEnum> Verbosity;
212
      cm::optional<bool> Debug;
213
      cm::optional<bool> OutputOnFailure;
214
      cm::optional<bool> Quiet;
215
      std::string OutputLogFile;
216
      std::string OutputJUnitFile;
217
      cm::optional<bool> LabelSummary;
218
      cm::optional<bool> SubprojectSummary;
219
      cm::optional<int> MaxPassedTestOutputSize;
220
      cm::optional<int> MaxFailedTestOutputSize;
221
      cm::optional<cmCTestTypes::TruncationMode> TestOutputTruncation;
222
      cm::optional<int> MaxTestNameWidth;
223
    };
224
225
    struct IncludeOptions
226
    {
227
      struct IndexOptions
228
      {
229
        cm::optional<int> Start;
230
        cm::optional<int> End;
231
        cm::optional<int> Stride;
232
        std::vector<int> SpecificTests;
233
234
        std::string IndexFile;
235
      };
236
237
      std::string Name;
238
      std::string Label;
239
      cm::optional<IndexOptions> Index;
240
      cm::optional<bool> UseUnion;
241
    };
242
243
    struct ExcludeOptions
244
    {
245
      struct FixturesOptions
246
      {
247
        std::string Any;
248
        std::string Setup;
249
        std::string Cleanup;
250
      };
251
252
      std::string Name;
253
      std::string Label;
254
      cm::optional<FixturesOptions> Fixtures;
255
    };
256
257
    struct FilterOptions
258
    {
259
      cm::optional<IncludeOptions> Include;
260
      cm::optional<ExcludeOptions> Exclude;
261
    };
262
263
    struct ExecutionOptions
264
    {
265
      enum class ShowOnlyEnum
266
      {
267
        Human,
268
        JsonV1
269
      };
270
271
      struct RepeatOptions
272
      {
273
        enum class ModeEnum
274
        {
275
          UntilFail,
276
          UntilPass,
277
          AfterTimeout
278
        };
279
280
        ModeEnum Mode;
281
        int Count;
282
      };
283
284
      enum class NoTestsActionEnum
285
      {
286
        Default,
287
        Error,
288
        Ignore
289
      };
290
291
      cm::optional<bool> StopOnFailure;
292
      cm::optional<bool> EnableFailover;
293
      cm::optional<cm::optional<unsigned int>> Jobs;
294
      std::string ResourceSpecFile;
295
      cm::optional<int> TestLoad;
296
      cm::optional<ShowOnlyEnum> ShowOnly;
297
298
      cm::optional<RepeatOptions> Repeat;
299
      cm::optional<bool> InteractiveDebugging;
300
      cm::optional<bool> ScheduleRandom;
301
      cm::optional<int> Timeout;
302
      cm::optional<NoTestsActionEnum> NoTestsAction;
303
      std::vector<std::string> TestPassthroughArguments;
304
    };
305
306
    std::string ConfigurePreset;
307
    cm::optional<bool> InheritConfigureEnvironment;
308
    std::string Configuration;
309
    std::vector<std::string> OverwriteConfigurationFile;
310
    cm::optional<OutputOptions> Output;
311
    cm::optional<FilterOptions> Filter;
312
    cm::optional<ExecutionOptions> Execution;
313
314
    bool VisitPresetInherit(Preset const& parent) override;
315
    bool VisitPresetAfterInherit(int /* version */,
316
                                 cmJSONState* /*state*/) override;
317
318
0
    static char const* kind() { return "test"; }
319
  };
320
321
  class PackagePreset : public Preset
322
  {
323
  public:
324
0
    PackagePreset() = default;
325
0
    PackagePreset(PackagePreset&& /*other*/) = default;
326
0
    PackagePreset(PackagePreset const& /*other*/) = default;
327
0
    PackagePreset& operator=(PackagePreset const& /*other*/) = default;
328
0
    ~PackagePreset() override = default;
329
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
330
    PackagePreset& operator=(PackagePreset&& /*other*/) = default;
331
#else
332
    // The move assignment operators for several STL classes did not become
333
    // noexcept until C++17, which causes some tools to warn about this move
334
    // assignment operator throwing an exception when it shouldn't.
335
    PackagePreset& operator=(PackagePreset&& /*other*/) = delete;
336
#endif
337
338
    std::string ConfigurePreset;
339
    cm::optional<bool> InheritConfigureEnvironment;
340
    std::vector<std::string> Generators;
341
    std::vector<std::string> Configurations;
342
    std::map<std::string, std::string> Variables;
343
    std::string ConfigFile;
344
345
    cm::optional<bool> DebugOutput;
346
    cm::optional<bool> VerboseOutput;
347
348
    std::string PackageName;
349
    std::string PackageVersion;
350
    std::string PackageDirectory;
351
    std::string VendorName;
352
353
    bool VisitPresetInherit(Preset const& parent) override;
354
    bool VisitPresetAfterInherit(int /* version */,
355
                                 cmJSONState* /*state*/) override;
356
357
0
    static char const* kind() { return "package"; }
358
  };
359
360
  class WorkflowPreset : public Preset
361
  {
362
  public:
363
0
    WorkflowPreset() = default;
364
0
    WorkflowPreset(WorkflowPreset&& /*other*/) = default;
365
0
    WorkflowPreset(WorkflowPreset const& /*other*/) = default;
366
0
    WorkflowPreset& operator=(WorkflowPreset const& /*other*/) = default;
367
0
    ~WorkflowPreset() override = default;
368
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
369
    WorkflowPreset& operator=(WorkflowPreset&& /*other*/) = default;
370
#else
371
    // The move assignment operators for several STL classes did not become
372
    // noexcept until C++17, which causes some tools to warn about this move
373
    // assignment operator throwing an exception when it shouldn't.
374
    WorkflowPreset& operator=(WorkflowPreset&& /*other*/) = delete;
375
#endif
376
377
    struct WorkflowStep
378
    {
379
      enum class Type
380
      {
381
        Configure,
382
        Build,
383
        Test,
384
        Package,
385
      };
386
      Type PresetType;
387
      std::string PresetName;
388
    };
389
390
    std::vector<WorkflowStep> Steps;
391
392
    bool VisitPresetInherit(Preset const& parent) override;
393
    bool VisitPresetAfterInherit(int /* version */,
394
                                 cmJSONState* /* state */) override;
395
396
0
    static char const* kind() { return "workflow"; }
397
  };
398
399
  template <typename T>
400
  struct PresetPair
401
  {
402
    T Unexpanded;
403
    cm::optional<T> Expanded;
404
  };
405
406
  enum class PresetResolveStatus
407
  {
408
    Success,
409
    NotFound,
410
    Hidden,
411
    InvalidMacroExpansion,
412
    Disabled,
413
  };
414
415
  // Result type for preset resolution
416
  template <class T>
417
  struct PresetResolveResult
418
  {
419
    using Status = PresetResolveStatus;
420
421
    Status StatusCode = Status::Success;
422
    std::string ErrorPresetName;
423
    T const* Preset = nullptr;
424
  };
425
426
  template <class T>
427
  PresetResolveResult<T> ResolvePreset(
428
    std::string const& presetName,
429
    std::map<std::string, PresetPair<T>> const& presets) const;
430
431
  // Returns an error message for a preset resolve status,
432
  // or cm::nullopt on Success.
433
  template <class T>
434
  static cm::optional<std::string> FormatPresetError(
435
    PresetResolveStatus status, std::string const& errorPresetName,
436
    std::string const& directory);
437
438
  std::map<std::string, PresetPair<ConfigurePreset>> ConfigurePresets;
439
  std::map<std::string, PresetPair<BuildPreset>> BuildPresets;
440
  std::map<std::string, PresetPair<TestPreset>> TestPresets;
441
  std::map<std::string, PresetPair<PackagePreset>> PackagePresets;
442
  std::map<std::string, PresetPair<WorkflowPreset>> WorkflowPresets;
443
444
  std::vector<std::string> ConfigurePresetOrder;
445
  std::vector<std::string> BuildPresetOrder;
446
  std::vector<std::string> TestPresetOrder;
447
  std::vector<std::string> PackagePresetOrder;
448
  std::vector<std::string> WorkflowPresetOrder;
449
450
  std::string SourceDir;
451
  std::vector<std::unique_ptr<File>> Files;
452
453
  int GetVersion(Preset const& preset) const
454
0
  {
455
0
    return preset.OriginFile->Version;
456
0
  }
457
458
  enum class ReadOption
459
  {
460
    RequireFiles,
461
    AllowNoFiles,
462
  };
463
464
  bool ReadProjectPresets(
465
    std::string const& sourceDir, std::string const& presetsFile,
466
    ReadOption readFilesOption = ReadOption::RequireFiles);
467
468
  std::string GetGeneratorForPreset(std::string const& presetName) const;
469
470
  void PrintConfigurePresetList() const;
471
  void PrintConfigurePresetList(
472
    std::function<bool(ConfigurePreset const&)> const& filter) const;
473
  void PrintBuildPresetList() const;
474
  void PrintTestPresetList() const;
475
  void PrintPackagePresetList() const;
476
  void PrintPackagePresetList(
477
    std::function<bool(PackagePreset const&)> const& filter) const;
478
  void PrintWorkflowPresetList() const;
479
  void PrintAllPresets() const;
480
481
private:
482
  enum class RootType
483
  {
484
    Any,
485
    Project,
486
    User,
487
  };
488
489
  enum class ReadReason
490
  {
491
    Root,
492
    Included,
493
  };
494
495
  bool ReadProjectPresetsInternal(std::string const& presetsFile,
496
                                  ReadOption readFilesOption);
497
  bool ReadJSONFile(std::string const& filename, RootType rootType,
498
                    ReadReason readReason, std::vector<File*>& inProgressFiles,
499
                    File*& file, std::string& errMsg);
500
  void ClearPresets();
501
502
  static std::string GetFilename(std::string const& sourceDir);
503
  static std::string GetUserFilename(std::string const& sourceDir);
504
};
505
506
extern template cmCMakePresetsGraph::PresetResolveResult<
507
  cmCMakePresetsGraph::ConfigurePreset>
508
cmCMakePresetsGraph::ResolvePreset(
509
  std::string const&,
510
  std::map<std::string,
511
           cmCMakePresetsGraph::PresetPair<
512
             cmCMakePresetsGraph::ConfigurePreset>> const&) const;
513
514
extern template cmCMakePresetsGraph::PresetResolveResult<
515
  cmCMakePresetsGraph::BuildPreset>
516
cmCMakePresetsGraph::ResolvePreset(
517
  std::string const&,
518
  std::map<
519
    std::string,
520
    cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::BuildPreset>> const&)
521
  const;
522
523
extern template cmCMakePresetsGraph::PresetResolveResult<
524
  cmCMakePresetsGraph::TestPreset>
525
cmCMakePresetsGraph::ResolvePreset(
526
  std::string const&,
527
  std::map<
528
    std::string,
529
    cmCMakePresetsGraph::PresetPair<cmCMakePresetsGraph::TestPreset>> const&)
530
  const;
531
532
extern template cmCMakePresetsGraph::PresetResolveResult<
533
  cmCMakePresetsGraph::PackagePreset>
534
cmCMakePresetsGraph::ResolvePreset(
535
  std::string const&,
536
  std::map<std::string,
537
           cmCMakePresetsGraph::PresetPair<
538
             cmCMakePresetsGraph::PackagePreset>> const&) const;
539
540
extern template cm::optional<std::string>
541
cmCMakePresetsGraph::FormatPresetError<cmCMakePresetsGraph::ConfigurePreset>(
542
  cmCMakePresetsGraph::PresetResolveStatus, std::string const&,
543
  std::string const&);
544
545
extern template cm::optional<std::string>
546
cmCMakePresetsGraph::FormatPresetError<cmCMakePresetsGraph::BuildPreset>(
547
  cmCMakePresetsGraph::PresetResolveStatus, std::string const&,
548
  std::string const&);
549
550
extern template cm::optional<std::string>
551
cmCMakePresetsGraph::FormatPresetError<cmCMakePresetsGraph::TestPreset>(
552
  cmCMakePresetsGraph::PresetResolveStatus, std::string const&,
553
  std::string const&);
554
555
extern template cm::optional<std::string>
556
cmCMakePresetsGraph::FormatPresetError<cmCMakePresetsGraph::PackagePreset>(
557
  cmCMakePresetsGraph::PresetResolveStatus, std::string const&,
558
  std::string const&);