Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Source / cmake.h
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt 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 "cmGeneratedFileStream.h"
22 #include "cmInstalledFile.h"
23 #include "cmListFileCache.h"
24 #include "cmMessageType.h"
25 #include "cmState.h"
26 #include "cmStateSnapshot.h"
27 #include "cmStateTypes.h"
28 #include "cmValue.h"
29
30 #if !defined(CMAKE_BOOTSTRAP)
31 #  include <cm/optional>
32
33 #  include <cm3p/json/value.h>
34
35 #  include "cmCMakePresetsGraph.h"
36 #endif
37
38 class cmExternalMakefileProjectGeneratorFactory;
39 class cmFileAPI;
40 class cmFileTimeCache;
41 class cmGlobalGenerator;
42 class cmGlobalGeneratorFactory;
43 class cmMakefile;
44 #if !defined(CMAKE_BOOTSTRAP)
45 class cmMakefileProfilingData;
46 #endif
47 class cmMessenger;
48 class cmVariableWatch;
49 struct cmBuildOptions;
50 struct cmDocumentationEntry;
51
52 /** \brief Represents a cmake invocation.
53  *
54  * This class represents a cmake invocation. It is the top level class when
55  * running cmake. Most cmake based GUIs should primarily create an instance
56  * of this class and communicate with it.
57  *
58  * The basic process for a GUI is as follows:
59  *
60  * -# Create a cmake instance
61  * -# Set the Home directories, generator, and cmake command. this
62  *    can be done using the Set methods or by using SetArgs and passing in
63  *    command line arguments.
64  * -# Load the cache by calling LoadCache (duh)
65  * -# if you are using command line arguments with -D or -C flags then
66  *    call SetCacheArgs (or if for some other reason you want to modify the
67  *    cache), do it now.
68  * -# Finally call Configure
69  * -# Let the user change values and go back to step 5
70  * -# call Generate
71
72  * If your GUI allows the user to change the home directories then
73  * you must at a minimum redo steps 2 through 7.
74  */
75
76 class cmake
77 {
78 public:
79   enum Role
80   {
81     RoleInternal, // no commands
82     RoleScript,   // script commands
83     RoleProject   // all commands
84   };
85
86   enum DiagLevel
87   {
88     DIAG_IGNORE,
89     DIAG_WARN,
90     DIAG_ERROR
91   };
92
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   /** \brief Define supported trace formats **/
124   enum TraceFormat
125   {
126     TRACE_UNDEFINED,
127     TRACE_HUMAN,
128     TRACE_JSON_V1,
129   };
130
131   struct GeneratorInfo
132   {
133     std::string name;
134     std::string baseName;
135     std::string extraName;
136     bool supportsToolset;
137     bool supportsPlatform;
138     std::vector<std::string> supportedPlatforms;
139     std::string defaultPlatform;
140     bool isAlias;
141   };
142
143   struct FileExtensions
144   {
145     bool Test(cm::string_view ext) const
146     {
147       return (this->unordered.find(ext) != this->unordered.end());
148     }
149
150     std::vector<std::string> ordered;
151     std::unordered_set<cm::string_view> unordered;
152   };
153
154   using InstalledFilesMap = std::map<std::string, cmInstalledFile>;
155
156   static const int NO_BUILD_PARALLEL_LEVEL = -1;
157   static const int DEFAULT_BUILD_PARALLEL_LEVEL = 0;
158
159   /// Default constructor
160   cmake(Role role, cmState::Mode mode,
161         cmState::ProjectKind projectKind = cmState::ProjectKind::Normal);
162   /// Destructor
163   ~cmake();
164
165   cmake(cmake const&) = delete;
166   cmake& operator=(cmake const&) = delete;
167
168 #if !defined(CMAKE_BOOTSTRAP)
169   Json::Value ReportVersionJson() const;
170   Json::Value ReportCapabilitiesJson() const;
171 #endif
172   std::string ReportCapabilities() const;
173
174   /**
175    * Set the home directory from `-S` or from a known location
176    * that contains a CMakeLists.txt. Will generate warnings
177    * when overriding an existing source directory.
178    *
179    *  |    args           | src dir| warning        |
180    *  | ----------------- | ------ | -------------- |
181    *  | `dirA dirA`       | dirA   | N/A            |
182    *  | `-S dirA -S dirA` | dirA   | N/A            |
183    *  | `-S dirA -S dirB` | dirB   | Ignoring dirA  |
184    *  | `-S dirA dirB`    | dirB   | Ignoring dirA  |
185    *  | `dirA -S dirB`    | dirB   | Ignoring dirA  |
186    *  | `dirA dirB`       | dirB   | Ignoring dirA  |
187    */
188   void SetHomeDirectoryViaCommandLine(std::string const& path);
189
190   //@{
191   /**
192    * Set/Get the home directory (or output directory) in the project. The
193    * home directory is the top directory of the project. It is the
194    * path-to-source cmake was run with.
195    */
196   void SetHomeDirectory(const std::string& dir);
197   std::string const& GetHomeDirectory() const;
198   void SetHomeOutputDirectory(const std::string& dir);
199   std::string const& GetHomeOutputDirectory() const;
200   //@}
201
202   /**
203    * Working directory at CMake launch
204    */
205   std::string const& GetCMakeWorkingDirectory() const
206   {
207     return this->CMakeWorkingDirectory;
208   }
209
210   /**
211    * Handle a command line invocation of cmake.
212    */
213   int Run(const std::vector<std::string>& args)
214   {
215     return this->Run(args, false);
216   }
217   int Run(const std::vector<std::string>& args, bool noconfigure);
218
219   /**
220    * Run the global generator Generate step.
221    */
222   int Generate();
223
224   /**
225    * Configure the cmMakefiles. This routine will create a GlobalGenerator if
226    * one has not already been set. It will then Call Configure on the
227    * GlobalGenerator. This in turn will read in an process all the CMakeList
228    * files for the tree. It will not produce any actual Makefiles, or
229    * workspaces. Generate does that.  */
230   int Configure();
231   int ActualConfigure();
232
233   //! Break up a line like VAR:type="value" into var, type and value
234   static bool ParseCacheEntry(const std::string& entry, std::string& var,
235                               std::string& value,
236                               cmStateEnums::CacheEntryType& type);
237
238   int LoadCache();
239   bool LoadCache(const std::string& path);
240   bool LoadCache(const std::string& path, bool internal,
241                  std::set<std::string>& excludes,
242                  std::set<std::string>& includes);
243   bool SaveCache(const std::string& path);
244   bool DeleteCache(const std::string& path);
245   void PreLoadCMakeFiles();
246
247   //! Create a GlobalGenerator
248   std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
249     const std::string& name, bool allowArch = true);
250
251   //! Create a GlobalGenerator and set it as our own
252   bool CreateAndSetGlobalGenerator(const std::string& name, bool allowArch);
253
254 #ifndef CMAKE_BOOTSTRAP
255   //! Print list of configure presets
256   void PrintPresetList(const cmCMakePresetsGraph& graph) const;
257 #endif
258
259   //! Return the global generator assigned to this instance of cmake
260   cmGlobalGenerator* GetGlobalGenerator()
261   {
262     return this->GlobalGenerator.get();
263   }
264   //! Return the global generator assigned to this instance of cmake, const
265   const cmGlobalGenerator* GetGlobalGenerator() const
266   {
267     return this->GlobalGenerator.get();
268   }
269
270   //! Return the full path to where the CMakeCache.txt file should be.
271   static std::string FindCacheFile(const std::string& binaryDir);
272
273   //! Return the global generator assigned to this instance of cmake
274   void SetGlobalGenerator(std::unique_ptr<cmGlobalGenerator>);
275
276   //! Get the names of the current registered generators
277   void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
278                                bool includeNamesWithPlatform = true) const;
279
280   //! Set the name of the selected generator-specific instance.
281   void SetGeneratorInstance(std::string const& instance)
282   {
283     this->GeneratorInstance = instance;
284     this->GeneratorInstanceSet = true;
285   }
286
287   //! Set the name of the selected generator-specific platform.
288   void SetGeneratorPlatform(std::string const& ts)
289   {
290     this->GeneratorPlatform = ts;
291     this->GeneratorPlatformSet = true;
292   }
293
294   //! Set the name of the selected generator-specific toolset.
295   void SetGeneratorToolset(std::string const& ts)
296   {
297     this->GeneratorToolset = ts;
298     this->GeneratorToolsetSet = true;
299   }
300
301   bool IsAKnownSourceExtension(cm::string_view ext) const
302   {
303     return this->CLikeSourceFileExtensions.Test(ext) ||
304       this->CudaFileExtensions.Test(ext) ||
305       this->FortranFileExtensions.Test(ext) ||
306       this->HipFileExtensions.Test(ext) || this->ISPCFileExtensions.Test(ext);
307   }
308
309   bool IsACLikeSourceExtension(cm::string_view ext) const
310   {
311     return this->CLikeSourceFileExtensions.Test(ext);
312   }
313
314   bool IsAKnownExtension(cm::string_view ext) const
315   {
316     return this->IsAKnownSourceExtension(ext) || this->IsAHeaderExtension(ext);
317   }
318
319   std::vector<std::string> GetAllExtensions() const;
320
321   const std::vector<std::string>& GetHeaderExtensions() const
322   {
323     return this->HeaderFileExtensions.ordered;
324   }
325
326   bool IsAHeaderExtension(cm::string_view ext) const
327   {
328     return this->HeaderFileExtensions.Test(ext);
329   }
330
331   // Strips the extension (if present and known) from a filename
332   std::string StripExtension(const std::string& file) const;
333
334   /**
335    * Given a variable name, return its value (as a string).
336    */
337   cmValue GetCacheDefinition(const std::string&) const;
338   //! Add an entry into the cache
339   void AddCacheEntry(const std::string& key, const char* value,
340                      const char* helpString, int type)
341   {
342     this->AddCacheEntry(key,
343                         value ? cmValue(std::string(value)) : cmValue(nullptr),
344                         helpString, type);
345   }
346   void AddCacheEntry(const std::string& key, const std::string& value,
347                      const char* helpString, int type)
348   {
349     this->AddCacheEntry(key, cmValue(value), helpString, type);
350   }
351   void AddCacheEntry(const std::string& key, cmValue value,
352                      const char* helpString, int type);
353
354   bool DoWriteGlobVerifyTarget() const;
355   std::string const& GetGlobVerifyScript() const;
356   std::string const& GetGlobVerifyStamp() const;
357   void AddGlobCacheEntry(bool recurse, bool listDirectories,
358                          bool followSymlinks, const std::string& relative,
359                          const std::string& expression,
360                          const std::vector<std::string>& files,
361                          const std::string& variable,
362                          cmListFileBacktrace const& bt);
363
364   /**
365    * Get the system information and write it to the file specified
366    */
367   int GetSystemInformation(std::vector<std::string>&);
368
369   //! Parse environment variables
370   void LoadEnvironmentPresets();
371
372   //! Parse command line arguments
373   void SetArgs(const std::vector<std::string>& args);
374
375   //! Is this cmake running as a result of a TRY_COMPILE command
376   bool GetIsInTryCompile() const;
377
378 #ifndef CMAKE_BOOTSTRAP
379   void SetWarningFromPreset(const std::string& name,
380                             const cm::optional<bool>& warning,
381                             const cm::optional<bool>& error);
382   void ProcessPresetVariables();
383   void PrintPresetVariables();
384   void ProcessPresetEnvironment();
385   void PrintPresetEnvironment();
386 #endif
387
388   //! Parse command line arguments that might set cache values
389   bool SetCacheArgs(const std::vector<std::string>&);
390
391   void ProcessCacheArg(const std::string& var, const std::string& value,
392                        cmStateEnums::CacheEntryType type);
393
394   using ProgressCallbackType = std::function<void(const std::string&, float)>;
395   /**
396    *  Set the function used by GUIs to receive progress updates
397    *  Function gets passed: message as a const char*, a progress
398    *  amount ranging from 0 to 1.0 and client data. The progress
399    *  number provided may be negative in cases where a message is
400    *  to be displayed without any progress percentage.
401    */
402   void SetProgressCallback(ProgressCallbackType f);
403
404   //! this is called by generators to update the progress
405   void UpdateProgress(const std::string& msg, float prog);
406
407 #if !defined(CMAKE_BOOTSTRAP)
408   //! Get the variable watch object
409   cmVariableWatch* GetVariableWatch() { return this->VariableWatch.get(); }
410 #endif
411
412   std::vector<cmDocumentationEntry> GetGeneratorsDocumentation();
413
414   //! Set/Get a property of this target file
415   void SetProperty(const std::string& prop, const char* value);
416   void SetProperty(const std::string& prop, cmValue value);
417   void SetProperty(const std::string& prop, const std::string& value)
418   {
419     this->SetProperty(prop, cmValue(value));
420   }
421   void AppendProperty(const std::string& prop, const std::string& value,
422                       bool asString = false);
423   cmValue GetProperty(const std::string& prop);
424   bool GetPropertyAsBool(const std::string& prop);
425
426   //! Get or create an cmInstalledFile instance and return a pointer to it
427   cmInstalledFile* GetOrCreateInstalledFile(cmMakefile* mf,
428                                             const std::string& name);
429
430   cmInstalledFile const* GetInstalledFile(const std::string& name) const;
431
432   InstalledFilesMap const& GetInstalledFiles() const
433   {
434     return this->InstalledFiles;
435   }
436
437   //! Do all the checks before running configure
438   int DoPreConfigureChecks();
439
440   void SetWorkingMode(WorkingMode mode) { this->CurrentWorkingMode = mode; }
441   WorkingMode GetWorkingMode() { return this->CurrentWorkingMode; }
442
443   //! Debug the try compile stuff by not deleting the files
444   bool GetDebugTryCompile() const { return this->DebugTryCompile; }
445   void DebugTryCompileOn() { this->DebugTryCompile = true; }
446
447   /**
448    * Generate CMAKE_ROOT and CMAKE_COMMAND cache entries
449    */
450   int AddCMakePaths();
451
452   /**
453    * Get the file comparison class
454    */
455   cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache.get(); }
456
457   bool WasLogLevelSetViaCLI() const { return this->LogLevelWasSetViaCLI; }
458
459   //! Get the selected log level for `message()` commands during the cmake run.
460   Message::LogLevel GetLogLevel() const { return this->MessageLogLevel; }
461   void SetLogLevel(Message::LogLevel level) { this->MessageLogLevel = level; }
462   static Message::LogLevel StringToLogLevel(cm::string_view levelStr);
463   static std::string LogLevelToString(Message::LogLevel level);
464   static TraceFormat StringToTraceFormat(const std::string& levelStr);
465
466   bool HasCheckInProgress() const
467   {
468     return !this->CheckInProgressMessages.empty();
469   }
470   std::size_t GetCheckInProgressSize() const
471   {
472     return this->CheckInProgressMessages.size();
473   }
474   std::string GetTopCheckInProgressMessage()
475   {
476     auto message = this->CheckInProgressMessages.top();
477     this->CheckInProgressMessages.pop();
478     return message;
479   }
480   void PushCheckInProgressMessage(std::string message)
481   {
482     this->CheckInProgressMessages.emplace(std::move(message));
483   }
484
485   //! Should `message` command display context.
486   bool GetShowLogContext() const { return this->LogContext; }
487   void SetShowLogContext(bool b) { this->LogContext = b; }
488
489   //! Do we want debug output during the cmake run.
490   bool GetDebugOutput() const { return this->DebugOutput; }
491   void SetDebugOutputOn(bool b) { this->DebugOutput = b; }
492
493   //! Do we want debug output from the find commands during the cmake run.
494   bool GetDebugFindOutput() const { return this->DebugFindOutput; }
495   bool GetDebugFindOutput(std::string const& var) const;
496   bool GetDebugFindPkgOutput(std::string const& pkg) const;
497   void SetDebugFindOutput(bool b) { this->DebugFindOutput = b; }
498   void SetDebugFindOutputPkgs(std::string const& args);
499   void SetDebugFindOutputVars(std::string const& args);
500
501   //! Do we want trace output during the cmake run.
502   bool GetTrace() const { return this->Trace; }
503   void SetTrace(bool b) { this->Trace = b; }
504   bool GetTraceExpand() const { return this->TraceExpand; }
505   void SetTraceExpand(bool b) { this->TraceExpand = b; }
506   TraceFormat GetTraceFormat() const { return this->TraceFormatVar; }
507   void SetTraceFormat(TraceFormat f) { this->TraceFormatVar = f; }
508   void AddTraceSource(std::string const& file)
509   {
510     this->TraceOnlyThisSources.push_back(file);
511   }
512   std::vector<std::string> const& GetTraceSources() const
513   {
514     return this->TraceOnlyThisSources;
515   }
516   cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; }
517   void SetTraceFile(std::string const& file);
518   void PrintTraceFormatVersion();
519
520   bool GetWarnUninitialized() const { return this->WarnUninitialized; }
521   void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
522   bool GetWarnUnusedCli() const { return this->WarnUnusedCli; }
523   void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b; }
524   bool GetCheckSystemVars() const { return this->CheckSystemVars; }
525   void SetCheckSystemVars(bool b) { this->CheckSystemVars = b; }
526   bool GetIgnoreWarningAsError() const { return this->IgnoreWarningAsError; }
527   void SetIgnoreWarningAsError(bool b) { this->IgnoreWarningAsError = b; }
528
529   void MarkCliAsUsed(const std::string& variable);
530
531   /** Get the list of configurations (in upper case) considered to be
532       debugging configurations.*/
533   std::vector<std::string> GetDebugConfigs();
534
535   void SetCMakeEditCommand(std::string const& s)
536   {
537     this->CMakeEditCommand = s;
538   }
539   std::string const& GetCMakeEditCommand() const
540   {
541     return this->CMakeEditCommand;
542   }
543
544   cmMessenger* GetMessenger() const { return this->Messenger.get(); }
545
546   /**
547    * Get the state of the suppression of developer (author) warnings.
548    * Returns false, by default, if developer warnings should be shown, true
549    * otherwise.
550    */
551   bool GetSuppressDevWarnings() const;
552   /**
553    * Set the state of the suppression of developer (author) warnings.
554    */
555   void SetSuppressDevWarnings(bool v);
556
557   /**
558    * Get the state of the suppression of deprecated warnings.
559    * Returns false, by default, if deprecated warnings should be shown, true
560    * otherwise.
561    */
562   bool GetSuppressDeprecatedWarnings() const;
563   /**
564    * Set the state of the suppression of deprecated warnings.
565    */
566   void SetSuppressDeprecatedWarnings(bool v);
567
568   /**
569    * Get the state of treating developer (author) warnings as errors.
570    * Returns false, by default, if warnings should not be treated as errors,
571    * true otherwise.
572    */
573   bool GetDevWarningsAsErrors() const;
574   /**
575    * Set the state of treating developer (author) warnings as errors.
576    */
577   void SetDevWarningsAsErrors(bool v);
578
579   /**
580    * Get the state of treating deprecated warnings as errors.
581    * Returns false, by default, if warnings should not be treated as errors,
582    * true otherwise.
583    */
584   bool GetDeprecatedWarningsAsErrors() const;
585   /**
586    * Set the state of treating developer (author) warnings as errors.
587    */
588   void SetDeprecatedWarningsAsErrors(bool v);
589
590   /** Display a message to the user.  */
591   void IssueMessage(
592     MessageType t, std::string const& text,
593     cmListFileBacktrace const& backtrace = cmListFileBacktrace()) const;
594
595   //! run the --build option
596   int Build(int jobs, std::string dir, std::vector<std::string> targets,
597             std::string config, std::vector<std::string> nativeOptions,
598             cmBuildOptions& buildOptions, bool verbose,
599             const std::string& presetName, bool listPresets);
600
601   //! run the --open option
602   bool Open(const std::string& dir, bool dryRun);
603
604   //! run the --workflow option
605   enum class WorkflowListPresets
606   {
607     No,
608     Yes,
609   };
610   enum class WorkflowFresh
611   {
612     No,
613     Yes,
614   };
615   int Workflow(const std::string& presetName, WorkflowListPresets listPresets,
616                WorkflowFresh fresh);
617
618   void UnwatchUnusedCli(const std::string& var);
619   void WatchUnusedCli(const std::string& var);
620
621   cmState* GetState() const { return this->State.get(); }
622   void SetCurrentSnapshot(cmStateSnapshot const& snapshot)
623   {
624     this->CurrentSnapshot = snapshot;
625   }
626   cmStateSnapshot GetCurrentSnapshot() const { return this->CurrentSnapshot; }
627
628   bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; }
629
630 #if !defined(CMAKE_BOOTSTRAP)
631   cmMakefileProfilingData& GetProfilingOutput();
632   bool IsProfilingEnabled() const;
633 #endif
634
635 protected:
636   void RunCheckForUnusedVariables();
637   int HandleDeleteCacheVariables(const std::string& var);
638
639   using RegisteredGeneratorsVector =
640     std::vector<std::unique_ptr<cmGlobalGeneratorFactory>>;
641   RegisteredGeneratorsVector Generators;
642   using RegisteredExtraGeneratorsVector =
643     std::vector<cmExternalMakefileProjectGeneratorFactory*>;
644   RegisteredExtraGeneratorsVector ExtraGenerators;
645   void AddScriptingCommands() const;
646   void AddProjectCommands() const;
647   void AddDefaultGenerators();
648   void AddDefaultExtraGenerators();
649
650   std::map<std::string, DiagLevel> DiagLevels;
651   std::string GeneratorInstance;
652   std::string GeneratorPlatform;
653   std::string GeneratorToolset;
654   bool GeneratorInstanceSet = false;
655   bool GeneratorPlatformSet = false;
656   bool GeneratorToolsetSet = false;
657
658   //! read in a cmake list file to initialize the cache
659   void ReadListFile(const std::vector<std::string>& args,
660                     const std::string& path);
661   bool FindPackage(const std::vector<std::string>& args);
662
663   //! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file.
664   ///  If it is set, truncate it to 50kb
665   void TruncateOutputLog(const char* fname);
666
667   /**
668    * Method called to check build system integrity at build time.
669    * Returns 1 if CMake should rerun and 0 otherwise.
670    */
671   int CheckBuildSystem();
672
673   bool SetDirectoriesFromFile(const std::string& arg);
674
675   //! Make sure all commands are what they say they are and there is no
676   /// macros.
677   void CleanupCommandsAndMacros();
678
679   void GenerateGraphViz(const std::string& fileName) const;
680
681 private:
682   std::string CMakeWorkingDirectory;
683   ProgressCallbackType ProgressCallback;
684   WorkingMode CurrentWorkingMode = NORMAL_MODE;
685   bool DebugOutput = false;
686   bool DebugFindOutput = false;
687   bool Trace = false;
688   bool TraceExpand = false;
689   TraceFormat TraceFormatVar = TRACE_HUMAN;
690   cmGeneratedFileStream TraceFile;
691   bool WarnUninitialized = false;
692   bool WarnUnusedCli = true;
693   bool CheckSystemVars = false;
694   bool IgnoreWarningAsError = false;
695   std::map<std::string, bool> UsedCliVariables;
696   std::string CMakeEditCommand;
697   std::string CXXEnvironment;
698   std::string CCEnvironment;
699   std::string CheckBuildSystemArgument;
700   std::string CheckStampFile;
701   std::string CheckStampList;
702   std::string VSSolutionFile;
703   std::string EnvironmentGenerator;
704   FileExtensions CLikeSourceFileExtensions;
705   FileExtensions HeaderFileExtensions;
706   FileExtensions CudaFileExtensions;
707   FileExtensions ISPCFileExtensions;
708   FileExtensions FortranFileExtensions;
709   FileExtensions HipFileExtensions;
710   bool ClearBuildSystem = false;
711   bool DebugTryCompile = false;
712   bool FreshCache = false;
713   bool RegenerateDuringBuild = false;
714   std::unique_ptr<cmFileTimeCache> FileTimeCache;
715   std::string GraphVizFile;
716   InstalledFilesMap InstalledFiles;
717 #ifndef CMAKE_BOOTSTRAP
718   std::map<std::string, cm::optional<cmCMakePresetsGraph::CacheVariable>>
719     UnprocessedPresetVariables;
720   std::map<std::string, cm::optional<std::string>>
721     UnprocessedPresetEnvironment;
722 #endif
723
724 #if !defined(CMAKE_BOOTSTRAP)
725   std::unique_ptr<cmVariableWatch> VariableWatch;
726   std::unique_ptr<cmFileAPI> FileAPI;
727 #endif
728
729   std::unique_ptr<cmState> State;
730   cmStateSnapshot CurrentSnapshot;
731   std::unique_ptr<cmMessenger> Messenger;
732
733   std::vector<std::string> TraceOnlyThisSources;
734
735   std::set<std::string> DebugFindPkgs;
736   std::set<std::string> DebugFindVars;
737
738   Message::LogLevel MessageLogLevel = Message::LogLevel::LOG_STATUS;
739   bool LogLevelWasSetViaCLI = false;
740   bool LogContext = false;
741
742   std::stack<std::string> CheckInProgressMessages;
743
744   std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
745
746   void UpdateConversionPathTable();
747
748   //! Print a list of valid generators to stderr.
749   void PrintGeneratorList();
750
751   std::unique_ptr<cmGlobalGenerator> EvaluateDefaultGlobalGenerator();
752   void CreateDefaultGlobalGenerator();
753
754   void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
755   void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
756
757 #if !defined(CMAKE_BOOTSTRAP)
758   template <typename T>
759   const T* FindPresetForWorkflow(
760     cm::static_string_view type,
761     const std::map<std::string, cmCMakePresetsGraph::PresetPair<T>>& presets,
762     const cmCMakePresetsGraph::WorkflowPreset::WorkflowStep& step);
763
764   std::function<int()> BuildWorkflowStep(const std::vector<std::string>& args);
765 #endif
766
767 #if !defined(CMAKE_BOOTSTRAP)
768   std::unique_ptr<cmMakefileProfilingData> ProfilingOutput;
769 #endif
770 };
771
772 #define CMAKE_STANDARD_OPTIONS_TABLE                                          \
773   { "-S <path-to-source>", "Explicitly specify a source directory." },        \
774     { "-B <path-to-build>", "Explicitly specify a build directory." },        \
775     { "-C <initial-cache>", "Pre-load a script to populate the cache." },     \
776     { "-D <var>[:<type>]=<value>", "Create or update a cmake cache entry." }, \
777     { "-U <globbing_expr>", "Remove matching entries from CMake cache." },    \
778     { "-G <generator-name>", "Specify a build system generator." },           \
779     { "-T <toolset-name>",                                                    \
780       "Specify toolset name if supported by generator." },                    \
781     { "-A <platform-name>",                                                   \
782       "Specify platform name if supported by generator." },                   \
783     { "--toolchain <file>",                                                   \
784       "Specify toolchain file [CMAKE_TOOLCHAIN_FILE]." },                     \
785     { "--install-prefix <directory>",                                         \
786       "Specify install directory [CMAKE_INSTALL_PREFIX]." },                  \
787     { "-Wdev", "Enable developer warnings." },                                \
788     { "-Wno-dev", "Suppress developer warnings." },                           \
789     { "-Werror=dev", "Make developer warnings errors." },                     \
790     { "-Wno-error=dev", "Make developer warnings not errors." },              \
791     { "-Wdeprecated", "Enable deprecation warnings." },                       \
792     { "-Wno-deprecated", "Suppress deprecation warnings." },                  \
793     { "-Werror=deprecated",                                                   \
794       "Make deprecated macro and function warnings "                          \
795       "errors." },                                                            \
796   {                                                                           \
797     "-Wno-error=deprecated",                                                  \
798       "Make deprecated macro and function warnings "                          \
799       "not errors."                                                           \
800   }
801
802 #define FOR_EACH_C90_FEATURE(F) F(c_function_prototypes)
803
804 #define FOR_EACH_C99_FEATURE(F)                                               \
805   F(c_restrict)                                                               \
806   F(c_variadic_macros)
807
808 #define FOR_EACH_C11_FEATURE(F) F(c_static_assert)
809
810 #define FOR_EACH_C_FEATURE(F)                                                 \
811   F(c_std_90)                                                                 \
812   F(c_std_99)                                                                 \
813   F(c_std_11)                                                                 \
814   F(c_std_17)                                                                 \
815   F(c_std_23)                                                                 \
816   FOR_EACH_C90_FEATURE(F)                                                     \
817   FOR_EACH_C99_FEATURE(F)                                                     \
818   FOR_EACH_C11_FEATURE(F)
819
820 #define FOR_EACH_CXX98_FEATURE(F) F(cxx_template_template_parameters)
821
822 #define FOR_EACH_CXX11_FEATURE(F)                                             \
823   F(cxx_alias_templates)                                                      \
824   F(cxx_alignas)                                                              \
825   F(cxx_alignof)                                                              \
826   F(cxx_attributes)                                                           \
827   F(cxx_auto_type)                                                            \
828   F(cxx_constexpr)                                                            \
829   F(cxx_decltype)                                                             \
830   F(cxx_decltype_incomplete_return_types)                                     \
831   F(cxx_default_function_template_args)                                       \
832   F(cxx_defaulted_functions)                                                  \
833   F(cxx_defaulted_move_initializers)                                          \
834   F(cxx_delegating_constructors)                                              \
835   F(cxx_deleted_functions)                                                    \
836   F(cxx_enum_forward_declarations)                                            \
837   F(cxx_explicit_conversions)                                                 \
838   F(cxx_extended_friend_declarations)                                         \
839   F(cxx_extern_templates)                                                     \
840   F(cxx_final)                                                                \
841   F(cxx_func_identifier)                                                      \
842   F(cxx_generalized_initializers)                                             \
843   F(cxx_inheriting_constructors)                                              \
844   F(cxx_inline_namespaces)                                                    \
845   F(cxx_lambdas)                                                              \
846   F(cxx_local_type_template_args)                                             \
847   F(cxx_long_long_type)                                                       \
848   F(cxx_noexcept)                                                             \
849   F(cxx_nonstatic_member_init)                                                \
850   F(cxx_nullptr)                                                              \
851   F(cxx_override)                                                             \
852   F(cxx_range_for)                                                            \
853   F(cxx_raw_string_literals)                                                  \
854   F(cxx_reference_qualified_functions)                                        \
855   F(cxx_right_angle_brackets)                                                 \
856   F(cxx_rvalue_references)                                                    \
857   F(cxx_sizeof_member)                                                        \
858   F(cxx_static_assert)                                                        \
859   F(cxx_strong_enums)                                                         \
860   F(cxx_thread_local)                                                         \
861   F(cxx_trailing_return_types)                                                \
862   F(cxx_unicode_literals)                                                     \
863   F(cxx_uniform_initialization)                                               \
864   F(cxx_unrestricted_unions)                                                  \
865   F(cxx_user_literals)                                                        \
866   F(cxx_variadic_macros)                                                      \
867   F(cxx_variadic_templates)
868
869 #define FOR_EACH_CXX14_FEATURE(F)                                             \
870   F(cxx_aggregate_default_initializers)                                       \
871   F(cxx_attribute_deprecated)                                                 \
872   F(cxx_binary_literals)                                                      \
873   F(cxx_contextual_conversions)                                               \
874   F(cxx_decltype_auto)                                                        \
875   F(cxx_digit_separators)                                                     \
876   F(cxx_generic_lambdas)                                                      \
877   F(cxx_lambda_init_captures)                                                 \
878   F(cxx_relaxed_constexpr)                                                    \
879   F(cxx_return_type_deduction)                                                \
880   F(cxx_variable_templates)
881
882 #define FOR_EACH_CXX_FEATURE(F)                                               \
883   F(cxx_std_98)                                                               \
884   F(cxx_std_11)                                                               \
885   F(cxx_std_14)                                                               \
886   F(cxx_std_17)                                                               \
887   F(cxx_std_20)                                                               \
888   F(cxx_std_23)                                                               \
889   F(cxx_std_26)                                                               \
890   FOR_EACH_CXX98_FEATURE(F)                                                   \
891   FOR_EACH_CXX11_FEATURE(F)                                                   \
892   FOR_EACH_CXX14_FEATURE(F)
893
894 #define FOR_EACH_CUDA_FEATURE(F)                                              \
895   F(cuda_std_03)                                                              \
896   F(cuda_std_11)                                                              \
897   F(cuda_std_14)                                                              \
898   F(cuda_std_17)                                                              \
899   F(cuda_std_20)                                                              \
900   F(cuda_std_23)                                                              \
901   F(cuda_std_26)
902
903 #define FOR_EACH_HIP_FEATURE(F)                                               \
904   F(hip_std_98)                                                               \
905   F(hip_std_11)                                                               \
906   F(hip_std_14)                                                               \
907   F(hip_std_17)                                                               \
908   F(hip_std_20)                                                               \
909   F(hip_std_23)                                                               \
910   F(hip_std_26)