Coverage Report

Created: 2026-06-15 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmake.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 <cstddef>
8
#include <functional>
9
#include <map>
10
#include <memory>
11
#include <set>
12
#include <stack>
13
#include <string>
14
#include <unordered_set>
15
#include <utility>
16
#include <vector>
17
18
#include <cm/string_view>
19
#include <cmext/string_view>
20
21
#include "cmBuildArgs.h"
22
#include "cmDiagnosticContext.h"
23
#include "cmDiagnostics.h"
24
#include "cmDocumentationEntry.h" // IWYU pragma: keep
25
#include "cmGeneratedFileStream.h"
26
#include "cmInstalledFile.h"
27
#include "cmListFileCache.h"
28
#include "cmMessageType.h"
29
#include "cmState.h"
30
#include "cmStateSnapshot.h"
31
#include "cmStateTypes.h"
32
#include "cmValue.h"
33
34
#if !defined(CMAKE_BOOTSTRAP)
35
#  include <cm/optional>
36
37
#  include <cm3p/json/value.h>
38
39
#  include "cmCMakePresetsGraph.h"
40
#  include "cmMakefileProfilingData.h"
41
#endif
42
43
class cmConfigureLog;
44
45
#ifdef CMake_ENABLE_DEBUGGER
46
namespace cmDebugger {
47
class cmDebuggerAdapter;
48
}
49
#endif
50
51
class cmExternalMakefileProjectGeneratorFactory;
52
class cmCMakePresetsArgs;
53
class cmCMakePresetsConfigureArgs;
54
class cmCMakePresetsWorkflowArgs;
55
class cmFileAPI;
56
class cmInstrumentation;
57
class cmFileTimeCache;
58
class cmGlobalGenerator;
59
class cmMakefile;
60
class cmMessenger;
61
class cmVariableWatch;
62
class cmGlobalGeneratorFactory;
63
struct cmBuildOptions;
64
struct cmGlobCacheEntry;
65
66
/** \brief Represents a cmake invocation.
67
 *
68
 * This class represents a cmake invocation. It is the top level class when
69
 * running cmake. Most cmake based GUIs should primarily create an instance
70
 * of this class and communicate with it.
71
 *
72
 * The basic process for a GUI is as follows:
73
 *
74
 * -# Create a cmake instance
75
 * -# Set the Home directories, generator, and cmake command. this
76
 *    can be done using the Set methods or by using SetArgs and passing in
77
 *    command line arguments.
78
 * -# Load the cache by calling LoadCache (duh)
79
 * -# if you are using command line arguments with -D or -C flags then
80
 *    call SetCacheArgs (or if for some other reason you want to modify the
81
 *    cache), do it now.
82
 * -# Finally call Configure
83
 * -# Let the user change values and go back to step 5
84
 * -# call Generate
85
86
 * If your GUI allows the user to change the home directories then
87
 * you must at a minimum redo steps 2 through 7.
88
 */
89
90
class cmake
91
{
92
public:
93
  /** \brief Describes the working modes of cmake */
94
  enum WorkingMode
95
  {
96
    NORMAL_MODE, ///< Cmake runs to create project files
97
98
    /** \brief Script mode (started by using -P).
99
     *
100
     * In script mode there is no generator and no cache. Also,
101
     * languages are not enabled, so add_executable and things do
102
     * nothing.
103
     */
104
    SCRIPT_MODE,
105
106
    /** \brief Help mode
107
     *
108
     * Used to print help for things that can only be determined after finding
109
     * the source directory, for example, the list of presets.
110
     */
111
    HELP_MODE,
112
113
    /** \brief A pkg-config like mode
114
     *
115
     * In this mode cmake just searches for a package and prints the results to
116
     * stdout. This is similar to SCRIPT_MODE, but commands like add_library()
117
     * work too, since they may be used e.g. in exported target files. Started
118
     * via --find-package.
119
     */
120
    FIND_PACKAGE_MODE
121
  };
122
123
  enum class CommandFailureAction
124
  {
125
    // When a command fails to execute, treat it as a fatal error.
126
    FATAL_ERROR,
127
128
    // When a command fails to execute, continue execution, but set the exit
129
    // code accordingly.
130
    EXIT_CODE,
131
  };
132
133
  using TraceFormat = cmTraceEnums::TraceOutputFormat;
134
135
  struct GeneratorInfo
136
  {
137
    std::string name;
138
    std::string baseName;
139
    std::string extraName;
140
    bool supportsToolset;
141
    bool supportsPlatform;
142
    std::vector<std::string> supportedPlatforms;
143
    std::string defaultPlatform;
144
    bool isAlias;
145
  };
146
147
  struct FileExtensions
148
  {
149
    bool Test(cm::string_view ext) const
150
0
    {
151
0
      return (this->unordered.find(ext) != this->unordered.end());
152
0
    }
153
154
    std::vector<std::string> ordered;
155
    std::unordered_set<cm::string_view> unordered;
156
  };
157
158
  using InstalledFilesMap = std::map<std::string, cmInstalledFile>;
159
160
  static int const NO_BUILD_PARALLEL_LEVEL =
161
    cmBuildArgs::NO_BUILD_PARALLEL_LEVEL;
162
  static int const DEFAULT_BUILD_PARALLEL_LEVEL =
163
    cmBuildArgs::DEFAULT_BUILD_PARALLEL_LEVEL;
164
165
  /// Default constructor
166
  cmake(cmState::Role role,
167
        cmState::TryCompile isTryCompile = cmState::TryCompile::No);
168
  /// Destructor
169
  ~cmake();
170
171
  cmake(cmake const&) = delete;
172
  cmake& operator=(cmake const&) = delete;
173
174
#if !defined(CMAKE_BOOTSTRAP)
175
  Json::Value ReportVersionJson() const;
176
  Json::Value ReportCapabilitiesJson() const;
177
#endif
178
  std::string ReportCapabilities() const;
179
180
  /**
181
   * Set the home directory from `-S` or from a known location
182
   * that contains a CMakeLists.txt. Will generate warnings
183
   * when overriding an existing source directory.
184
   *
185
   *  |    args           | src dir| warning        |
186
   *  | ----------------- | ------ | -------------- |
187
   *  | `dirA dirA`       | dirA   | N/A            |
188
   *  | `-S dirA -S dirA` | dirA   | N/A            |
189
   *  | `-S dirA -S dirB` | dirB   | Ignoring dirA  |
190
   *  | `-S dirA dirB`    | dirB   | Ignoring dirA  |
191
   *  | `dirA -S dirB`    | dirB   | Ignoring dirA  |
192
   *  | `dirA dirB`       | dirB   | Ignoring dirA  |
193
   */
194
  void SetHomeDirectoryViaCommandLine(std::string const& path);
195
196
  //@{
197
  /**
198
   * Set/Get the home directory (or output directory) in the project. The
199
   * home directory is the top directory of the project. It is the
200
   * path-to-source cmake was run with.
201
   */
202
  void SetHomeDirectory(std::string const& dir);
203
  std::string const& GetHomeDirectory() const;
204
  void SetHomeOutputDirectory(std::string const& dir);
205
  std::string const& GetHomeOutputDirectory() const;
206
  //@}
207
208
  /**
209
   * Working directory at CMake launch
210
   */
211
  std::string const& GetCMakeWorkingDirectory() const
212
0
  {
213
0
    return this->CMakeWorkingDirectory;
214
0
  }
215
216
  /**
217
   * Handle a command line invocation of cmake.
218
   */
219
  int Run(std::vector<std::string> const& args)
220
0
  {
221
0
    return this->Run(args, false);
222
0
  }
223
  int Run(std::vector<std::string> const& args, bool noconfigure);
224
225
  /**
226
   * Run the global generator Generate step.
227
   */
228
  int Generate();
229
230
  /**
231
   * Configure the cmMakefiles. This routine will create a GlobalGenerator if
232
   * one has not already been set. It will then Call Configure on the
233
   * GlobalGenerator. This in turn will read in an process all the CMakeList
234
   * files for the tree. It will not produce any actual Makefiles, or
235
   * workspaces. Generate does that.  */
236
  int Configure();
237
  int ActualConfigure();
238
239
  //! Break up a line like VAR:type="value" into var, type and value
240
  static bool ParseCacheEntry(std::string const& entry, std::string& var,
241
                              std::string& value,
242
                              cmStateEnums::CacheEntryType& type);
243
244
  int LoadCache();
245
  bool LoadCache(std::string const& path);
246
  bool LoadCache(std::string const& path, bool internal,
247
                 std::set<std::string>& excludes,
248
                 std::set<std::string>& includes);
249
  bool SaveCache(std::string const& path);
250
  bool DeleteCache(std::string const& path);
251
  void PreLoadCMakeFiles();
252
253
  //! Create a GlobalGenerator
254
  std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
255
    std::string const& name);
256
257
  //! Create a GlobalGenerator and set it as our own
258
  bool CreateAndSetGlobalGenerator(std::string const& name);
259
260
#ifndef CMAKE_BOOTSTRAP
261
  bool SetArgsFromPreset(cmCMakePresetsConfigureArgs const& args,
262
                         bool haveBinaryDirArg);
263
264
  void PrintPresetList(cmCMakePresetsGraph const& graph) const;
265
#endif
266
267
  //! Return the global generator assigned to this instance of cmake
268
  cmGlobalGenerator* GetGlobalGenerator()
269
1
  {
270
1
    return this->GlobalGenerator.get();
271
1
  }
272
  //! Return the global generator assigned to this instance of cmake, const
273
  cmGlobalGenerator const* GetGlobalGenerator() const
274
0
  {
275
0
    return this->GlobalGenerator.get();
276
0
  }
277
278
  //! Return the full path to where the CMakeCache.txt file should be.
279
  static std::string FindCacheFile(std::string const& binaryDir);
280
281
  //! Return the global generator assigned to this instance of cmake
282
  void SetGlobalGenerator(std::unique_ptr<cmGlobalGenerator>);
283
284
  //! Get the names of the current registered generators
285
  void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators) const;
286
287
  //! Set the name of the selected generator-specific instance.
288
  void SetGeneratorInstance(std::string const& instance)
289
0
  {
290
0
    this->GeneratorInstance = instance;
291
0
    this->GeneratorInstanceSet = true;
292
0
  }
293
294
  //! Set the name of the selected generator-specific platform.
295
  void SetGeneratorPlatform(std::string const& ts)
296
0
  {
297
0
    this->GeneratorPlatform = ts;
298
0
    this->GeneratorPlatformSet = true;
299
0
  }
300
301
  //! Set the name of the selected generator-specific toolset.
302
  void SetGeneratorToolset(std::string const& ts)
303
0
  {
304
0
    this->GeneratorToolset = ts;
305
0
    this->GeneratorToolsetSet = true;
306
0
  }
307
308
  //! Set the name of the graphviz file.
309
0
  void SetGraphVizFile(std::string const& ts) { this->GraphVizFile = ts; }
310
311
  bool IsAKnownSourceExtension(cm::string_view ext) const
312
0
  {
313
0
    return this->CLikeSourceFileExtensions.Test(ext) ||
314
0
      this->CudaFileExtensions.Test(ext) ||
315
0
      this->FortranFileExtensions.Test(ext) ||
316
0
      this->HipFileExtensions.Test(ext) || this->ISPCFileExtensions.Test(ext);
317
0
  }
318
319
  bool IsACLikeSourceExtension(cm::string_view ext) const
320
0
  {
321
0
    return this->CLikeSourceFileExtensions.Test(ext);
322
0
  }
323
324
  bool IsAKnownExtension(cm::string_view ext) const
325
0
  {
326
0
    return this->IsAKnownSourceExtension(ext) || this->IsAHeaderExtension(ext);
327
0
  }
328
329
  std::vector<std::string> GetAllExtensions() const;
330
331
  std::vector<std::string> const& GetHeaderExtensions() const
332
0
  {
333
0
    return this->HeaderFileExtensions.ordered;
334
0
  }
335
336
  bool IsAHeaderExtension(cm::string_view ext) const
337
0
  {
338
0
    return this->HeaderFileExtensions.Test(ext);
339
0
  }
340
341
  // Strips the extension (if present and known) from a filename
342
  std::string StripExtension(std::string const& file) const;
343
344
  /**
345
   * Given a variable name, return its value (as a string).
346
   */
347
  cmValue GetCacheDefinition(std::string const&) const;
348
  //! Add an entry into the cache
349
  void AddCacheEntry(std::string const& key, std::string const& value,
350
                     std::string const& helpString, int type)
351
3
  {
352
3
    this->AddCacheEntry(key, cmValue{ value }, cmValue{ helpString }, type);
353
3
  }
354
  void AddCacheEntry(std::string const& key, cmValue value,
355
                     std::string const& helpString, int type)
356
0
  {
357
0
    this->AddCacheEntry(key, value, cmValue{ helpString }, type);
358
0
  }
359
  void AddCacheEntry(std::string const& key, cmValue value, cmValue helpString,
360
                     int type);
361
362
  bool DoWriteGlobVerifyTarget() const;
363
  std::string const& GetGlobVerifyScript() const;
364
  std::string const& GetGlobVerifyStamp() const;
365
  void AddGlobCacheEntry(cmGlobCacheEntry const& entry,
366
                         std::string const& variable,
367
                         cmListFileBacktrace const& bt);
368
  std::vector<cmGlobCacheEntry> GetGlobCacheEntries() const;
369
370
  /**
371
   * Get the system information and write it to the file specified
372
   */
373
  int GetSystemInformation(std::vector<std::string>&);
374
375
  //! Parse environment variables
376
  void LoadEnvironmentPresets();
377
378
  //! Parse command line arguments
379
  void SetArgs(std::vector<std::string> const& args);
380
381
  //! Is this cmake running as a result of a TRY_COMPILE command
382
  bool GetIsInTryCompile() const;
383
384
#ifndef CMAKE_BOOTSTRAP
385
  void SetDiagnosticsFromPreset(
386
    std::map<cmDiagnosticCategory, bool> const& warnings,
387
    std::map<cmDiagnosticCategory, bool> const& errors);
388
  void ProcessPresetVariables();
389
  void PrintPresetVariables();
390
  void ProcessPresetEnvironment();
391
  void PrintPresetEnvironment();
392
#endif
393
394
  //! Parse command line arguments that might set cache values
395
  bool SetCacheArgs(std::vector<std::string> const&);
396
397
  void ProcessCacheArg(std::string const& var, std::string const& value,
398
                       cmStateEnums::CacheEntryType type);
399
400
  using ProgressCallbackType = std::function<void(std::string const&, float)>;
401
  /**
402
   *  Set the function used by GUIs to receive progress updates
403
   *  Function gets passed: message as a const char*, a progress
404
   *  amount ranging from 0 to 1.0 and client data. The progress
405
   *  number provided may be negative in cases where a message is
406
   *  to be displayed without any progress percentage.
407
   */
408
  void SetProgressCallback(ProgressCallbackType f);
409
410
  //! this is called by generators to update the progress
411
  void UpdateProgress(std::string const& msg, float prog);
412
413
#if !defined(CMAKE_BOOTSTRAP)
414
  //! Get the variable watch object
415
12
  cmVariableWatch* GetVariableWatch() { return this->VariableWatch.get(); }
416
#endif
417
418
  std::vector<cmDocumentationEntry> GetGeneratorsDocumentation();
419
420
  //! Set/Get a property of this target file
421
  void SetProperty(std::string const& prop, cmValue value);
422
  void SetProperty(std::string const& prop, std::nullptr_t)
423
0
  {
424
0
    this->SetProperty(prop, cmValue{ nullptr });
425
0
  }
426
  void SetProperty(std::string const& prop, std::string const& value)
427
0
  {
428
0
    this->SetProperty(prop, cmValue(value));
429
0
  }
430
  void AppendProperty(std::string const& prop, std::string const& value,
431
                      bool asString = false);
432
  cmValue GetProperty(std::string const& prop);
433
  bool GetPropertyAsBool(std::string const& prop);
434
435
  //! Get or create an cmInstalledFile instance and return a pointer to it
436
  cmInstalledFile* GetOrCreateInstalledFile(cmMakefile* mf,
437
                                            std::string const& name);
438
439
  cmInstalledFile const* GetInstalledFile(std::string const& name) const;
440
441
  InstalledFilesMap const& GetInstalledFiles() const
442
0
  {
443
0
    return this->InstalledFiles;
444
0
  }
445
446
  //! Do all the checks before running configure
447
  int DoPreConfigureChecks();
448
449
  bool RoleSupportsExitCode() const;
450
451
  CommandFailureAction GetCommandFailureAction() const;
452
453
  //! Debug the try compile stuff by not deleting the files
454
0
  bool GetDebugTryCompile() const { return this->DebugTryCompile; }
455
0
  void DebugTryCompileOn() { this->DebugTryCompile = true; }
456
457
  /**
458
   * Generate CMAKE_ROOT and CMAKE_COMMAND cache entries
459
   */
460
  int AddCMakePaths();
461
462
  /**
463
   * Get the file comparison class
464
   */
465
0
  cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache.get(); }
466
467
0
  bool WasLogLevelSetViaCLI() const { return this->LogLevelWasSetViaCLI; }
468
469
  //! Get the selected log level for `message()` commands during the cmake run.
470
3
  Message::LogLevel GetLogLevel() const { return this->MessageLogLevel; }
471
0
  void SetLogLevel(Message::LogLevel level) { this->MessageLogLevel = level; }
472
  static Message::LogLevel StringToLogLevel(cm::string_view levelStr);
473
  static std::string LogLevelToString(Message::LogLevel level);
474
  static TraceFormat StringToTraceFormat(std::string const& levelStr);
475
476
  bool HasCheckInProgress() const
477
0
  {
478
0
    return !this->CheckInProgressMessages.empty();
479
0
  }
480
  std::size_t GetCheckInProgressSize() const
481
0
  {
482
0
    return this->CheckInProgressMessages.size();
483
0
  }
484
  std::string GetTopCheckInProgressMessage()
485
0
  {
486
0
    auto message = this->CheckInProgressMessages.back();
487
0
    this->CheckInProgressMessages.pop_back();
488
0
    return message;
489
0
  }
490
  void PushCheckInProgressMessage(std::string message)
491
0
  {
492
0
    this->CheckInProgressMessages.emplace_back(std::move(message));
493
0
  }
494
  std::vector<std::string> const& GetCheckInProgressMessages() const
495
0
  {
496
0
    return this->CheckInProgressMessages;
497
0
  }
498
499
  //! Should `message` command display context.
500
0
  bool GetShowLogContext() const { return this->LogContext; }
501
0
  void SetShowLogContext(bool b) { this->LogContext = b; }
502
503
  //! Do we want debug output during the cmake run.
504
0
  bool GetDebugOutput() const { return this->DebugOutput; }
505
0
  void SetDebugOutputOn(bool b) { this->DebugOutput = b; }
506
507
  //! Do we want debug output from the find commands during the cmake run.
508
0
  bool GetDebugFindOutput() const { return this->DebugFindOutput; }
509
  bool GetDebugFindOutput(std::string const& var) const;
510
  bool GetDebugFindPkgOutput(std::string const& pkg) const;
511
0
  void SetDebugFindOutput(bool b) { this->DebugFindOutput = b; }
512
  void SetDebugFindOutputPkgs(std::string const& args);
513
  void SetDebugFindOutputVars(std::string const& args);
514
515
  //! Do we want trace output during the cmake run.
516
  bool GetTrace() const
517
1
  {
518
1
    return this->Trace || !this->cmakeLangTraceCmdStack.empty();
519
1
  }
520
0
  void SetTrace(bool b) { this->Trace = b; }
521
  void PushTraceCmd(bool expandFlag)
522
0
  {
523
0
    this->cmakeLangTraceCmdStack.emplace(expandFlag);
524
0
  }
525
  bool PopTraceCmd();
526
  bool GetTraceExpand() const
527
0
  {
528
0
    return this->TraceExpand ||
529
0
      (!this->cmakeLangTraceCmdStack.empty() &&
530
0
       this->cmakeLangTraceCmdStack.top());
531
0
  }
532
0
  void SetTraceExpand(bool b) { this->TraceExpand = b; }
533
0
  TraceFormat GetTraceFormat() const { return this->TraceFormatVar; }
534
0
  void SetTraceFormat(TraceFormat f) { this->TraceFormatVar = f; }
535
  void AddTraceSource(std::string const& file)
536
0
  {
537
0
    this->TraceOnlyThisSources.push_back(file);
538
0
  }
539
  std::vector<std::string> const& GetTraceSources() const
540
0
  {
541
0
    return this->TraceOnlyThisSources;
542
0
  }
543
  cmGeneratedFileStream& GetTraceFile()
544
0
  {
545
0
    if (this->TraceRedirect) {
546
0
      return this->TraceRedirect->GetTraceFile();
547
0
    }
548
0
    return this->TraceFile;
549
0
  }
550
  void SetTraceFile(std::string const& file);
551
  void PrintTraceFormatVersion();
552
553
#ifndef CMAKE_BOOTSTRAP
554
0
  cmConfigureLog* GetConfigureLog() const { return this->ConfigureLog.get(); }
555
#endif
556
557
  //! Use trace from another ::cmake instance.
558
  void SetTraceRedirect(cmake* other);
559
560
1
  bool GetCheckSystemVars() const { return this->CheckSystemVars; }
561
0
  void SetCheckSystemVars(bool b) { this->CheckSystemVars = b; }
562
  bool GetIgnoreCompileWarningAsError() const
563
0
  {
564
0
    return this->IgnoreCompileWarningAsError;
565
0
  }
566
  void SetIgnoreCompileWarningAsError(bool b)
567
0
  {
568
0
    this->IgnoreCompileWarningAsError = b;
569
0
  }
570
  bool GetIgnoreLinkWarningAsError() const
571
0
  {
572
0
    return this->IgnoreLinkWarningAsError;
573
0
  }
574
  void SetIgnoreLinkWarningAsError(bool b)
575
0
  {
576
0
    this->IgnoreLinkWarningAsError = b;
577
0
  }
578
579
  void MarkCliAsUsed(std::string const& variable);
580
581
  /** Get the list of configurations (in upper case) considered to be
582
      debugging configurations.*/
583
  std::vector<std::string> GetDebugConfigs();
584
585
  void SetCMakeEditCommand(std::string const& s)
586
0
  {
587
0
    this->CMakeEditCommand = s;
588
0
  }
589
  std::string const& GetCMakeEditCommand() const
590
0
  {
591
0
    return this->CMakeEditCommand;
592
0
  }
593
594
1
  cmMessenger* GetMessenger() const { return this->Messenger.get(); }
595
596
#ifndef CMAKE_BOOTSTRAP
597
  /// Get the SARIF file path if set manually for this run
598
  cm::optional<std::string> GetSarifFilePath() const
599
2
  {
600
2
    return (this->SarifFileOutput ? cm::make_optional(this->SarifFilePath)
601
2
                                  : cm::nullopt);
602
2
  }
603
#endif
604
605
  /** Display a message to the user.  */
606
  void IssueMessage(
607
    MessageType t, std::string const& text,
608
    cmListFileBacktrace const& backtrace = cmListFileBacktrace()) const;
609
  void IssueDiagnostic(cmDiagnosticCategory category, std::string const& text,
610
                       cmStateSnapshot const& state,
611
                       cmDiagnosticContext const& context = {}) const;
612
  void IssueDiagnostic(cmDiagnosticCategory category, std::string const& text,
613
                       cmDiagnosticContext const& context = {}) const
614
0
  {
615
0
    this->IssueDiagnostic(category, text, this->CurrentSnapshot, context);
616
0
  }
617
  void IssueDiagnostic(cmDiagnosticCategory category, std::string const& text,
618
                       cmListFileBacktrace backtrace) const
619
0
  {
620
0
    this->IssueDiagnostic(category, text, this->CurrentSnapshot,
621
0
                          cmDiagnosticContext{ std::move(backtrace) });
622
0
  }
623
624
  //! run the --build option
625
  int Build(cmBuildArgs buildArgs, std::vector<std::string> targets,
626
            std::vector<std::string> nativeOptions,
627
            cmBuildOptions& buildOptions,
628
            cmCMakePresetsArgs const& presetsArgs,
629
            std::vector<std::string> const& args);
630
631
  enum class DryRun
632
  {
633
    No,
634
    Yes,
635
  };
636
637
  //! run the --open option
638
  bool Open(std::string const& dir, DryRun dryRun);
639
640
  //! run the --workflow option
641
  int Workflow(cmCMakePresetsWorkflowArgs const& args);
642
643
  void UnwatchUnusedCli(std::string const& var);
644
  void WatchUnusedCli(std::string const& var);
645
646
#if !defined(CMAKE_BOOTSTRAP)
647
0
  cmFileAPI* GetFileAPI() const { return this->FileAPI.get(); }
648
  cmInstrumentation* GetInstrumentation() const
649
0
  {
650
0
    return this->Instrumentation.get();
651
0
  }
652
#endif
653
  void InitializeFileAPI();
654
  void InitializeInstrumentation();
655
656
0
  bool GetInInitialCache() const { return this->InInitialCache; }
657
0
  void SetInInitialCache(bool v) { this->InInitialCache = v; }
658
659
49
  cmState* GetState() const { return this->State.get(); }
660
  void SetCurrentSnapshot(cmStateSnapshot const& snapshot)
661
0
  {
662
0
    this->CurrentSnapshot = snapshot;
663
0
  }
664
1
  cmStateSnapshot GetCurrentSnapshot() const { return this->CurrentSnapshot; }
665
666
0
  bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; }
667
668
  void SetCMakeListName(std::string const& name);
669
  std::string GetCMakeListFile(std::string const& dir) const;
670
671
#if !defined(CMAKE_BOOTSTRAP)
672
  cmMakefileProfilingData& GetProfilingOutput();
673
  bool IsProfilingEnabled() const;
674
675
  cm::optional<cmMakefileProfilingData::RAII> CreateProfilingEntry(
676
    std::string const& category, std::string const& name)
677
0
  {
678
0
    return this->CreateProfilingEntry(
679
0
      category, name, []() -> cm::nullopt_t { return cm::nullopt; });
680
0
  }
681
682
  template <typename ArgsFunc>
683
  cm::optional<cmMakefileProfilingData::RAII> CreateProfilingEntry(
684
    std::string const& category, std::string const& name, ArgsFunc&& argsFunc)
685
0
  {
686
0
    if (this->IsProfilingEnabled()) {
687
0
      return cm::make_optional<cmMakefileProfilingData::RAII>(
688
0
        this->GetProfilingOutput(), category, name, argsFunc());
689
0
    }
690
0
    return cm::nullopt;
691
0
  }
Unexecuted instantiation: std::__1::optional<cmMakefileProfilingData::RAII> cmake::CreateProfilingEntry<cmake::CreateProfilingEntry(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::{lambda()#1}>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cmake::CreateProfilingEntry(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::{lambda()#1}&&)
Unexecuted instantiation: cmGeneratorExpressionEvaluator.cxx:std::__1::optional<cmMakefileProfilingData::RAII> cmake::CreateProfilingEntry<GeneratorExpressionContent::Evaluate(cm::GenEx::Evaluation*, cmGeneratorExpressionDAGChecker*) const::$_0>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, GeneratorExpressionContent::Evaluate(cm::GenEx::Evaluation*, cmGeneratorExpressionDAGChecker*) const::$_0&&)
Unexecuted instantiation: std::__1::optional<cmMakefileProfilingData::RAII> cmake::CreateProfilingEntry<cmMakefile::CallScope::CallScope(cmMakefile*, cmListFileFunction const&, cmListFileContext const&, cmExecutionStatus&)::{lambda()#1}>(cmMakefile::CallScope::CallScope(cmMakefile*, cmListFileFunction const&, cmListFileContext const&, cmExecutionStatus&)::{lambda()#1}::basic_string<char, cmMakefile::CallScope::CallScope(cmMakefile*, cmListFileFunction const&, cmListFileContext const&, cmExecutionStatus&)::{lambda()#1}::char_traits<char>, cmMakefile::CallScope::CallScope(cmMakefile*, cmListFileFunction const&, cmListFileContext const&, cmExecutionStatus&)::{lambda()#1}::allocator<char> > const&, cmMakefile::CallScope::CallScope(cmMakefile*, cmListFileFunction const&, cmListFileContext const&, cmExecutionStatus&)::{lambda()#1}::basic_string<char, cmMakefile::CallScope::CallScope(cmMakefile*, cmListFileFunction const&, cmListFileContext const&, cmExecutionStatus&)::{lambda()#1}::char_traits<char>, cmMakefile::CallScope::CallScope(cmMakefile*, cmListFileFunction const&, cmListFileContext const&, cmExecutionStatus&)::{lambda()#1}::allocator<char> > const, cmMakefile::CallScope::CallScope(cmMakefile*, cmListFileFunction const&, cmListFileContext const&, cmExecutionStatus&)::{lambda()#1}&&)
692
#endif
693
694
#ifdef CMake_ENABLE_DEBUGGER
695
1
  bool GetDebuggerOn() const { return this->DebuggerOn; }
696
0
  std::string GetDebuggerPipe() const { return this->DebuggerPipe; }
697
  std::string GetDebuggerDapLogFile() const
698
0
  {
699
0
    return this->DebuggerDapLogFile;
700
0
  }
701
0
  void SetDebuggerOn(bool b) { this->DebuggerOn = b; }
702
  bool StartDebuggerIfEnabled();
703
  void StopDebuggerIfNeeded(int exitCode);
704
  std::shared_ptr<cmDebugger::cmDebuggerAdapter> GetDebugAdapter()
705
    const noexcept
706
2
  {
707
2
    return this->DebugAdapter;
708
2
  }
709
#endif
710
711
protected:
712
  void RunCheckForUnusedVariables();
713
  int HandleDeleteCacheVariables(std::string const& var);
714
715
  using RegisteredGeneratorsVector =
716
    std::vector<std::unique_ptr<cmGlobalGeneratorFactory>>;
717
  RegisteredGeneratorsVector Generators;
718
  using RegisteredExtraGeneratorsVector =
719
    std::vector<cmExternalMakefileProjectGeneratorFactory*>;
720
  RegisteredExtraGeneratorsVector ExtraGenerators;
721
  void AddScriptingCommands() const;
722
  void AddProjectCommands() const;
723
  void AddDefaultGenerators();
724
  void AddDefaultExtraGenerators();
725
726
  std::string GeneratorInstance;
727
  std::string GeneratorPlatform;
728
  std::string GeneratorToolset;
729
  cm::optional<std::string> IntermediateDirStrategy;
730
  cm::optional<std::string> AutogenIntermediateDirStrategy;
731
  bool GeneratorInstanceSet = false;
732
  bool GeneratorPlatformSet = false;
733
  bool GeneratorToolsetSet = false;
734
735
  //! read in a cmake list file to initialize the cache
736
  void ReadListFile(std::vector<std::string> const& args,
737
                    std::string const& path);
738
  bool FindPackage(std::vector<std::string> const& args);
739
740
  //! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file.
741
  ///  If it is set, truncate it to 50kb
742
  void TruncateOutputLog(char const* fname);
743
744
  /**
745
   * Method called to check build system integrity at build time.
746
   * Returns 1 if CMake should rerun and 0 otherwise.
747
   */
748
  int CheckBuildSystem();
749
750
  bool SetDirectoriesFromFile(std::string const& arg);
751
752
  //! Make sure all commands are what they say they are and there is no
753
  /// macros.
754
  void CleanupCommandsAndMacros();
755
756
  void GenerateGraphViz(std::string const& fileName) const;
757
758
private:
759
  std::vector<std::string> cmdArgs;
760
  std::string CMakeWorkingDirectory;
761
  ProgressCallbackType ProgressCallback;
762
  bool DebugOutput = false;
763
  bool DebugFindOutput = false;
764
  // Elements of `cmakeLangTraceCmdStack` are "trace requests" pushed
765
  // by `cmake_language(TRACE ON [EXPAND])` and a boolean value is
766
  // a state of a given `EXPAND` option.
767
  std::stack<bool> cmakeLangTraceCmdStack;
768
  bool Trace = false;
769
  bool TraceExpand = false;
770
  TraceFormat TraceFormatVar = TraceFormat::Human;
771
  cmGeneratedFileStream TraceFile;
772
  cmake* TraceRedirect = nullptr;
773
#ifndef CMAKE_BOOTSTRAP
774
  std::unique_ptr<cmConfigureLog> ConfigureLog;
775
#endif
776
  bool CheckSystemVars = false;
777
  bool IgnoreCompileWarningAsError = false;
778
  bool IgnoreLinkWarningAsError = false;
779
  std::map<std::string, bool> UsedCliVariables;
780
  std::string CMakeEditCommand;
781
  std::string CXXEnvironment;
782
  std::string CCEnvironment;
783
  std::string CheckBuildSystemArgument;
784
  std::string CheckStampFile;
785
  std::string CheckStampList;
786
  std::string VSSolutionFile;
787
  std::string EnvironmentGenerator;
788
  FileExtensions CLikeSourceFileExtensions;
789
  FileExtensions HeaderFileExtensions;
790
  FileExtensions CudaFileExtensions;
791
  FileExtensions ISPCFileExtensions;
792
  FileExtensions FortranFileExtensions;
793
  FileExtensions HipFileExtensions;
794
  bool ClearBuildSystem = false;
795
  bool DebugTryCompile = false;
796
  bool FreshCache = false;
797
  bool RegenerateDuringBuild = false;
798
  bool InInitialCache = false;
799
  std::string CMakeListName;
800
  std::unique_ptr<cmFileTimeCache> FileTimeCache;
801
  std::string GraphVizFile;
802
  InstalledFilesMap InstalledFiles;
803
#ifndef CMAKE_BOOTSTRAP
804
  std::map<std::string, cm::optional<cmCMakePresetsGraph::CacheVariable>>
805
    UnprocessedPresetVariables;
806
  std::map<std::string, cm::optional<std::string>>
807
    UnprocessedPresetEnvironment;
808
#endif
809
810
#if !defined(CMAKE_BOOTSTRAP)
811
  std::unique_ptr<cmVariableWatch> VariableWatch;
812
  std::unique_ptr<cmFileAPI> FileAPI;
813
  std::unique_ptr<cmInstrumentation> Instrumentation;
814
#endif
815
816
  std::unique_ptr<cmState> State;
817
  cmStateSnapshot CurrentSnapshot;
818
  std::unique_ptr<cmMessenger> Messenger;
819
820
#ifndef CMAKE_BOOTSTRAP
821
  bool SarifFileOutput = false;
822
  std::string SarifFilePath;
823
#endif
824
825
  std::vector<std::string> TraceOnlyThisSources;
826
827
  std::set<std::string> DebugFindPkgs;
828
  std::set<std::string> DebugFindVars;
829
830
  Message::LogLevel MessageLogLevel = Message::LogLevel::LOG_STATUS;
831
  bool LogLevelWasSetViaCLI = false;
832
  bool LogContext = false;
833
834
  std::vector<std::string> CheckInProgressMessages;
835
836
  std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
837
838
  //! Print a list of valid generators to stderr.
839
  void PrintGeneratorList();
840
841
  std::unique_ptr<cmGlobalGenerator> EvaluateDefaultGlobalGenerator();
842
  void CreateDefaultGlobalGenerator();
843
844
  void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
845
  void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
846
847
#if !defined(CMAKE_BOOTSTRAP)
848
  template <typename T>
849
  T const* FindPresetForWorkflow(
850
    cm::static_string_view type,
851
    std::map<std::string, cmCMakePresetsGraph::PresetPair<T>> const& presets,
852
    cmCMakePresetsGraph::WorkflowPreset::WorkflowStep const& step);
853
#endif
854
855
#if !defined(CMAKE_BOOTSTRAP)
856
  std::unique_ptr<cmMakefileProfilingData> ProfilingOutput;
857
#endif
858
859
#ifdef CMake_ENABLE_DEBUGGER
860
  std::shared_ptr<cmDebugger::cmDebuggerAdapter> DebugAdapter;
861
  bool DebuggerOn = false;
862
  std::string DebuggerPipe;
863
  std::string DebuggerDapLogFile;
864
#endif
865
866
  cm::optional<int> ScriptModeExitCode;
867
868
public:
869
0
  bool HasScriptModeExitCode() const { return ScriptModeExitCode.has_value(); }
870
0
  void SetScriptModeExitCode(int code) { ScriptModeExitCode = code; }
871
0
  int GetScriptModeExitCode() const { return ScriptModeExitCode.value_or(-1); }
872
873
  static cmDocumentationEntry CMAKE_STANDARD_OPTIONS_TABLE[15];
874
};
875
876
0
#define FOR_EACH_C90_FEATURE(F) F(c_function_prototypes)
877
878
#define FOR_EACH_C99_FEATURE(F)                                               \
879
0
  F(c_restrict)                                                               \
880
0
  F(c_variadic_macros)
881
882
0
#define FOR_EACH_C11_FEATURE(F) F(c_static_assert)
883
884
#define FOR_EACH_C_FEATURE(F)                                                 \
885
0
  F(c_std_90)                                                                 \
886
0
  F(c_std_99)                                                                 \
887
0
  F(c_std_11)                                                                 \
888
0
  F(c_std_17)                                                                 \
889
0
  F(c_std_23)                                                                 \
890
0
  FOR_EACH_C90_FEATURE(F)                                                     \
891
0
  FOR_EACH_C99_FEATURE(F)                                                     \
892
0
  FOR_EACH_C11_FEATURE(F)
893
894
0
#define FOR_EACH_CXX98_FEATURE(F) F(cxx_template_template_parameters)
895
896
#define FOR_EACH_CXX11_FEATURE(F)                                             \
897
0
  F(cxx_alias_templates)                                                      \
898
0
  F(cxx_alignas)                                                              \
899
0
  F(cxx_alignof)                                                              \
900
0
  F(cxx_attributes)                                                           \
901
0
  F(cxx_auto_type)                                                            \
902
0
  F(cxx_constexpr)                                                            \
903
0
  F(cxx_decltype)                                                             \
904
0
  F(cxx_decltype_incomplete_return_types)                                     \
905
0
  F(cxx_default_function_template_args)                                       \
906
0
  F(cxx_defaulted_functions)                                                  \
907
0
  F(cxx_defaulted_move_initializers)                                          \
908
0
  F(cxx_delegating_constructors)                                              \
909
0
  F(cxx_deleted_functions)                                                    \
910
0
  F(cxx_enum_forward_declarations)                                            \
911
0
  F(cxx_explicit_conversions)                                                 \
912
0
  F(cxx_extended_friend_declarations)                                         \
913
0
  F(cxx_extern_templates)                                                     \
914
0
  F(cxx_final)                                                                \
915
0
  F(cxx_func_identifier)                                                      \
916
0
  F(cxx_generalized_initializers)                                             \
917
0
  F(cxx_inheriting_constructors)                                              \
918
0
  F(cxx_inline_namespaces)                                                    \
919
0
  F(cxx_lambdas)                                                              \
920
0
  F(cxx_local_type_template_args)                                             \
921
0
  F(cxx_long_long_type)                                                       \
922
0
  F(cxx_noexcept)                                                             \
923
0
  F(cxx_nonstatic_member_init)                                                \
924
0
  F(cxx_nullptr)                                                              \
925
0
  F(cxx_override)                                                             \
926
0
  F(cxx_range_for)                                                            \
927
0
  F(cxx_raw_string_literals)                                                  \
928
0
  F(cxx_reference_qualified_functions)                                        \
929
0
  F(cxx_right_angle_brackets)                                                 \
930
0
  F(cxx_rvalue_references)                                                    \
931
0
  F(cxx_sizeof_member)                                                        \
932
0
  F(cxx_static_assert)                                                        \
933
0
  F(cxx_strong_enums)                                                         \
934
0
  F(cxx_thread_local)                                                         \
935
0
  F(cxx_trailing_return_types)                                                \
936
0
  F(cxx_unicode_literals)                                                     \
937
0
  F(cxx_uniform_initialization)                                               \
938
0
  F(cxx_unrestricted_unions)                                                  \
939
0
  F(cxx_user_literals)                                                        \
940
0
  F(cxx_variadic_macros)                                                      \
941
0
  F(cxx_variadic_templates)
942
943
#define FOR_EACH_CXX14_FEATURE(F)                                             \
944
0
  F(cxx_aggregate_default_initializers)                                       \
945
0
  F(cxx_attribute_deprecated)                                                 \
946
0
  F(cxx_binary_literals)                                                      \
947
0
  F(cxx_contextual_conversions)                                               \
948
0
  F(cxx_decltype_auto)                                                        \
949
0
  F(cxx_digit_separators)                                                     \
950
0
  F(cxx_generic_lambdas)                                                      \
951
0
  F(cxx_lambda_init_captures)                                                 \
952
0
  F(cxx_relaxed_constexpr)                                                    \
953
0
  F(cxx_return_type_deduction)                                                \
954
0
  F(cxx_variable_templates)
955
956
#define FOR_EACH_CXX_FEATURE(F)                                               \
957
0
  F(cxx_std_98)                                                               \
958
0
  F(cxx_std_11)                                                               \
959
0
  F(cxx_std_14)                                                               \
960
0
  F(cxx_std_17)                                                               \
961
0
  F(cxx_std_20)                                                               \
962
0
  F(cxx_std_23)                                                               \
963
0
  F(cxx_std_26)                                                               \
964
0
  FOR_EACH_CXX98_FEATURE(F)                                                   \
965
0
  FOR_EACH_CXX11_FEATURE(F)                                                   \
966
0
  FOR_EACH_CXX14_FEATURE(F)
967
968
#define FOR_EACH_CUDA_FEATURE(F)                                              \
969
0
  F(cuda_std_03)                                                              \
970
0
  F(cuda_std_11)                                                              \
971
0
  F(cuda_std_14)                                                              \
972
0
  F(cuda_std_17)                                                              \
973
0
  F(cuda_std_20)                                                              \
974
0
  F(cuda_std_23)                                                              \
975
0
  F(cuda_std_26)
976
977
#define FOR_EACH_HIP_FEATURE(F)                                               \
978
0
  F(hip_std_98)                                                               \
979
0
  F(hip_std_11)                                                               \
980
0
  F(hip_std_14)                                                               \
981
0
  F(hip_std_17)                                                               \
982
0
  F(hip_std_20)                                                               \
983
0
  F(hip_std_23)                                                               \
984
0
  F(hip_std_26)