cmake.h 36 KB

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