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