Coverage Report

Created: 2026-04-29 07:01

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