1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
5 #include "cmConfigure.h" // IWYU pragma: keep
14 #include <unordered_set>
18 #include <cm/string_view>
19 #include <cmext/string_view>
21 #include "cmGeneratedFileStream.h"
22 #include "cmInstalledFile.h"
23 #include "cmListFileCache.h"
24 #include "cmMessageType.h"
26 #include "cmStateSnapshot.h"
27 #include "cmStateTypes.h"
30 #if !defined(CMAKE_BOOTSTRAP)
31 # include <cm/optional>
33 # include <cm3p/json/value.h>
35 # include "cmCMakePresetsGraph.h"
38 class cmExternalMakefileProjectGeneratorFactory;
40 class cmFileTimeCache;
41 class cmGlobalGenerator;
42 class cmGlobalGeneratorFactory;
44 #if !defined(CMAKE_BOOTSTRAP)
45 class cmMakefileProfilingData;
48 class cmVariableWatch;
49 struct cmBuildOptions;
50 struct cmDocumentationEntry;
52 /** \brief Represents a cmake invocation.
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.
58 * The basic process for a GUI is as follows:
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
68 * -# Finally call Configure
69 * -# Let the user change values and go back to step 5
72 * If your GUI allows the user to change the home directories then
73 * you must at a minimum redo steps 2 through 7.
81 RoleInternal, // no commands
82 RoleScript, // script commands
83 RoleProject // all commands
93 /** \brief Describes the working modes of cmake */
96 NORMAL_MODE, ///< Cmake runs to create project files
98 /** \brief Script mode (started by using -P).
100 * In script mode there is no generator and no cache. Also,
101 * languages are not enabled, so add_executable and things do
108 * Used to print help for things that can only be determined after finding
109 * the source directory, for example, the list of presets.
113 /** \brief A pkg-config like mode
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.
123 /** \brief Define supported trace formats **/
134 std::string baseName;
135 std::string extraName;
136 bool supportsToolset;
137 bool supportsPlatform;
138 std::vector<std::string> supportedPlatforms;
139 std::string defaultPlatform;
143 struct FileExtensions
145 bool Test(cm::string_view ext) const
147 return (this->unordered.find(ext) != this->unordered.end());
150 std::vector<std::string> ordered;
151 std::unordered_set<cm::string_view> unordered;
154 using InstalledFilesMap = std::map<std::string, cmInstalledFile>;
156 static const int NO_BUILD_PARALLEL_LEVEL = -1;
157 static const int DEFAULT_BUILD_PARALLEL_LEVEL = 0;
159 /// Default constructor
160 cmake(Role role, cmState::Mode mode,
161 cmState::ProjectKind projectKind = cmState::ProjectKind::Normal);
165 cmake(cmake const&) = delete;
166 cmake& operator=(cmake const&) = delete;
168 #if !defined(CMAKE_BOOTSTRAP)
169 Json::Value ReportVersionJson() const;
170 Json::Value ReportCapabilitiesJson() const;
172 std::string ReportCapabilities() const;
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.
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 |
188 void SetHomeDirectoryViaCommandLine(std::string const& path);
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.
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;
203 * Working directory at CMake launch
205 std::string const& GetCMakeWorkingDirectory() const
207 return this->CMakeWorkingDirectory;
211 * Handle a command line invocation of cmake.
213 int Run(const std::vector<std::string>& args)
215 return this->Run(args, false);
217 int Run(const std::vector<std::string>& args, bool noconfigure);
220 * Run the global generator Generate step.
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. */
231 int ActualConfigure();
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,
236 cmStateEnums::CacheEntryType& type);
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();
247 //! Create a GlobalGenerator
248 std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
249 const std::string& name, bool allowArch = true);
251 //! Create a GlobalGenerator and set it as our own
252 bool CreateAndSetGlobalGenerator(const std::string& name, bool allowArch);
254 #ifndef CMAKE_BOOTSTRAP
255 //! Print list of configure presets
256 void PrintPresetList(const cmCMakePresetsGraph& graph) const;
259 //! Return the global generator assigned to this instance of cmake
260 cmGlobalGenerator* GetGlobalGenerator()
262 return this->GlobalGenerator.get();
264 //! Return the global generator assigned to this instance of cmake, const
265 const cmGlobalGenerator* GetGlobalGenerator() const
267 return this->GlobalGenerator.get();
270 //! Return the full path to where the CMakeCache.txt file should be.
271 static std::string FindCacheFile(const std::string& binaryDir);
273 //! Return the global generator assigned to this instance of cmake
274 void SetGlobalGenerator(std::unique_ptr<cmGlobalGenerator>);
276 //! Get the names of the current registered generators
277 void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
278 bool includeNamesWithPlatform = true) const;
280 //! Set the name of the selected generator-specific instance.
281 void SetGeneratorInstance(std::string const& instance)
283 this->GeneratorInstance = instance;
284 this->GeneratorInstanceSet = true;
287 //! Set the name of the selected generator-specific platform.
288 void SetGeneratorPlatform(std::string const& ts)
290 this->GeneratorPlatform = ts;
291 this->GeneratorPlatformSet = true;
294 //! Set the name of the selected generator-specific toolset.
295 void SetGeneratorToolset(std::string const& ts)
297 this->GeneratorToolset = ts;
298 this->GeneratorToolsetSet = true;
301 bool IsAKnownSourceExtension(cm::string_view ext) const
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);
309 bool IsACLikeSourceExtension(cm::string_view ext) const
311 return this->CLikeSourceFileExtensions.Test(ext);
314 bool IsAKnownExtension(cm::string_view ext) const
316 return this->IsAKnownSourceExtension(ext) || this->IsAHeaderExtension(ext);
319 std::vector<std::string> GetAllExtensions() const;
321 const std::vector<std::string>& GetHeaderExtensions() const
323 return this->HeaderFileExtensions.ordered;
326 bool IsAHeaderExtension(cm::string_view ext) const
328 return this->HeaderFileExtensions.Test(ext);
331 // Strips the extension (if present and known) from a filename
332 std::string StripExtension(const std::string& file) const;
335 * Given a variable name, return its value (as a string).
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)
342 this->AddCacheEntry(key,
343 value ? cmValue(std::string(value)) : cmValue(nullptr),
346 void AddCacheEntry(const std::string& key, const std::string& value,
347 const char* helpString, int type)
349 this->AddCacheEntry(key, cmValue(value), helpString, type);
351 void AddCacheEntry(const std::string& key, cmValue value,
352 const char* helpString, int type);
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);
365 * Get the system information and write it to the file specified
367 int GetSystemInformation(std::vector<std::string>&);
369 //! Parse environment variables
370 void LoadEnvironmentPresets();
372 //! Parse command line arguments
373 void SetArgs(const std::vector<std::string>& args);
375 //! Is this cmake running as a result of a TRY_COMPILE command
376 bool GetIsInTryCompile() const;
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();
388 //! Parse command line arguments that might set cache values
389 bool SetCacheArgs(const std::vector<std::string>&);
391 void ProcessCacheArg(const std::string& var, const std::string& value,
392 cmStateEnums::CacheEntryType type);
394 using ProgressCallbackType = std::function<void(const std::string&, float)>;
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.
402 void SetProgressCallback(ProgressCallbackType f);
404 //! this is called by generators to update the progress
405 void UpdateProgress(const std::string& msg, float prog);
407 #if !defined(CMAKE_BOOTSTRAP)
408 //! Get the variable watch object
409 cmVariableWatch* GetVariableWatch() { return this->VariableWatch.get(); }
412 std::vector<cmDocumentationEntry> GetGeneratorsDocumentation();
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)
419 this->SetProperty(prop, cmValue(value));
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);
426 //! Get or create an cmInstalledFile instance and return a pointer to it
427 cmInstalledFile* GetOrCreateInstalledFile(cmMakefile* mf,
428 const std::string& name);
430 cmInstalledFile const* GetInstalledFile(const std::string& name) const;
432 InstalledFilesMap const& GetInstalledFiles() const
434 return this->InstalledFiles;
437 //! Do all the checks before running configure
438 int DoPreConfigureChecks();
440 void SetWorkingMode(WorkingMode mode) { this->CurrentWorkingMode = mode; }
441 WorkingMode GetWorkingMode() { return this->CurrentWorkingMode; }
443 //! Debug the try compile stuff by not deleting the files
444 bool GetDebugTryCompile() const { return this->DebugTryCompile; }
445 void DebugTryCompileOn() { this->DebugTryCompile = true; }
448 * Generate CMAKE_ROOT and CMAKE_COMMAND cache entries
453 * Get the file comparison class
455 cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache.get(); }
457 bool WasLogLevelSetViaCLI() const { return this->LogLevelWasSetViaCLI; }
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);
466 bool HasCheckInProgress() const
468 return !this->CheckInProgressMessages.empty();
470 std::size_t GetCheckInProgressSize() const
472 return this->CheckInProgressMessages.size();
474 std::string GetTopCheckInProgressMessage()
476 auto message = this->CheckInProgressMessages.top();
477 this->CheckInProgressMessages.pop();
480 void PushCheckInProgressMessage(std::string message)
482 this->CheckInProgressMessages.emplace(std::move(message));
485 //! Should `message` command display context.
486 bool GetShowLogContext() const { return this->LogContext; }
487 void SetShowLogContext(bool b) { this->LogContext = b; }
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; }
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);
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)
510 this->TraceOnlyThisSources.push_back(file);
512 std::vector<std::string> const& GetTraceSources() const
514 return this->TraceOnlyThisSources;
516 cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; }
517 void SetTraceFile(std::string const& file);
518 void PrintTraceFormatVersion();
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; }
529 void MarkCliAsUsed(const std::string& variable);
531 /** Get the list of configurations (in upper case) considered to be
532 debugging configurations.*/
533 std::vector<std::string> GetDebugConfigs();
535 void SetCMakeEditCommand(std::string const& s)
537 this->CMakeEditCommand = s;
539 std::string const& GetCMakeEditCommand() const
541 return this->CMakeEditCommand;
544 cmMessenger* GetMessenger() const { return this->Messenger.get(); }
547 * Get the state of the suppression of developer (author) warnings.
548 * Returns false, by default, if developer warnings should be shown, true
551 bool GetSuppressDevWarnings() const;
553 * Set the state of the suppression of developer (author) warnings.
555 void SetSuppressDevWarnings(bool v);
558 * Get the state of the suppression of deprecated warnings.
559 * Returns false, by default, if deprecated warnings should be shown, true
562 bool GetSuppressDeprecatedWarnings() const;
564 * Set the state of the suppression of deprecated warnings.
566 void SetSuppressDeprecatedWarnings(bool v);
569 * Get the state of treating developer (author) warnings as errors.
570 * Returns false, by default, if warnings should not be treated as errors,
573 bool GetDevWarningsAsErrors() const;
575 * Set the state of treating developer (author) warnings as errors.
577 void SetDevWarningsAsErrors(bool v);
580 * Get the state of treating deprecated warnings as errors.
581 * Returns false, by default, if warnings should not be treated as errors,
584 bool GetDeprecatedWarningsAsErrors() const;
586 * Set the state of treating developer (author) warnings as errors.
588 void SetDeprecatedWarningsAsErrors(bool v);
590 /** Display a message to the user. */
592 MessageType t, std::string const& text,
593 cmListFileBacktrace const& backtrace = cmListFileBacktrace()) const;
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);
601 //! run the --open option
602 bool Open(const std::string& dir, bool dryRun);
604 //! run the --workflow option
605 enum class WorkflowListPresets
610 enum class WorkflowFresh
615 int Workflow(const std::string& presetName, WorkflowListPresets listPresets,
616 WorkflowFresh fresh);
618 void UnwatchUnusedCli(const std::string& var);
619 void WatchUnusedCli(const std::string& var);
621 cmState* GetState() const { return this->State.get(); }
622 void SetCurrentSnapshot(cmStateSnapshot const& snapshot)
624 this->CurrentSnapshot = snapshot;
626 cmStateSnapshot GetCurrentSnapshot() const { return this->CurrentSnapshot; }
628 bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; }
630 #if !defined(CMAKE_BOOTSTRAP)
631 cmMakefileProfilingData& GetProfilingOutput();
632 bool IsProfilingEnabled() const;
636 void RunCheckForUnusedVariables();
637 int HandleDeleteCacheVariables(const std::string& var);
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();
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;
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);
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);
668 * Method called to check build system integrity at build time.
669 * Returns 1 if CMake should rerun and 0 otherwise.
671 int CheckBuildSystem();
673 bool SetDirectoriesFromFile(const std::string& arg);
675 //! Make sure all commands are what they say they are and there is no
677 void CleanupCommandsAndMacros();
679 void GenerateGraphViz(const std::string& fileName) const;
682 std::string CMakeWorkingDirectory;
683 ProgressCallbackType ProgressCallback;
684 WorkingMode CurrentWorkingMode = NORMAL_MODE;
685 bool DebugOutput = false;
686 bool DebugFindOutput = 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;
724 #if !defined(CMAKE_BOOTSTRAP)
725 std::unique_ptr<cmVariableWatch> VariableWatch;
726 std::unique_ptr<cmFileAPI> FileAPI;
729 std::unique_ptr<cmState> State;
730 cmStateSnapshot CurrentSnapshot;
731 std::unique_ptr<cmMessenger> Messenger;
733 std::vector<std::string> TraceOnlyThisSources;
735 std::set<std::string> DebugFindPkgs;
736 std::set<std::string> DebugFindVars;
738 Message::LogLevel MessageLogLevel = Message::LogLevel::LOG_STATUS;
739 bool LogLevelWasSetViaCLI = false;
740 bool LogContext = false;
742 std::stack<std::string> CheckInProgressMessages;
744 std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
746 void UpdateConversionPathTable();
748 //! Print a list of valid generators to stderr.
749 void PrintGeneratorList();
751 std::unique_ptr<cmGlobalGenerator> EvaluateDefaultGlobalGenerator();
752 void CreateDefaultGlobalGenerator();
754 void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
755 void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
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);
764 std::function<int()> BuildWorkflowStep(const std::vector<std::string>& args);
767 #if !defined(CMAKE_BOOTSTRAP)
768 std::unique_ptr<cmMakefileProfilingData> ProfilingOutput;
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 " \
797 "-Wno-error=deprecated", \
798 "Make deprecated macro and function warnings " \
802 #define FOR_EACH_C90_FEATURE(F) F(c_function_prototypes)
804 #define FOR_EACH_C99_FEATURE(F) \
808 #define FOR_EACH_C11_FEATURE(F) F(c_static_assert)
810 #define FOR_EACH_C_FEATURE(F) \
816 FOR_EACH_C90_FEATURE(F) \
817 FOR_EACH_C99_FEATURE(F) \
818 FOR_EACH_C11_FEATURE(F)
820 #define FOR_EACH_CXX98_FEATURE(F) F(cxx_template_template_parameters)
822 #define FOR_EACH_CXX11_FEATURE(F) \
823 F(cxx_alias_templates) \
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) \
841 F(cxx_func_identifier) \
842 F(cxx_generalized_initializers) \
843 F(cxx_inheriting_constructors) \
844 F(cxx_inline_namespaces) \
846 F(cxx_local_type_template_args) \
847 F(cxx_long_long_type) \
849 F(cxx_nonstatic_member_init) \
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)
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)
882 #define FOR_EACH_CXX_FEATURE(F) \
890 FOR_EACH_CXX98_FEATURE(F) \
891 FOR_EACH_CXX11_FEATURE(F) \
892 FOR_EACH_CXX14_FEATURE(F)
894 #define FOR_EACH_CUDA_FEATURE(F) \
903 #define FOR_EACH_HIP_FEATURE(F) \