Coverage Report

Created: 2026-09-14 06:43

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