1
0

cmake.h 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037
  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. void SetWorkingMode(WorkingMode mode, CommandFailureAction policy)
  375. {
  376. this->CurrentWorkingMode = mode;
  377. this->CurrentCommandFailureAction = policy;
  378. }
  379. WorkingMode GetWorkingMode() const { return this->CurrentWorkingMode; }
  380. CommandFailureAction GetCommandFailureAction() const
  381. {
  382. return this->CurrentCommandFailureAction;
  383. }
  384. //! Debug the try compile stuff by not deleting the files
  385. bool GetDebugTryCompile() const { return this->DebugTryCompile; }
  386. void DebugTryCompileOn() { this->DebugTryCompile = true; }
  387. /**
  388. * Generate CMAKE_ROOT and CMAKE_COMMAND cache entries
  389. */
  390. int AddCMakePaths();
  391. /**
  392. * Get the file comparison class
  393. */
  394. cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache.get(); }
  395. bool WasLogLevelSetViaCLI() const { return this->LogLevelWasSetViaCLI; }
  396. //! Get the selected log level for `message()` commands during the cmake run.
  397. Message::LogLevel GetLogLevel() const { return this->MessageLogLevel; }
  398. void SetLogLevel(Message::LogLevel level) { this->MessageLogLevel = level; }
  399. static Message::LogLevel StringToLogLevel(cm::string_view levelStr);
  400. static std::string LogLevelToString(Message::LogLevel level);
  401. static TraceFormat StringToTraceFormat(std::string const& levelStr);
  402. bool HasCheckInProgress() const
  403. {
  404. return !this->CheckInProgressMessages.empty();
  405. }
  406. std::size_t GetCheckInProgressSize() const
  407. {
  408. return this->CheckInProgressMessages.size();
  409. }
  410. std::string GetTopCheckInProgressMessage()
  411. {
  412. auto message = this->CheckInProgressMessages.back();
  413. this->CheckInProgressMessages.pop_back();
  414. return message;
  415. }
  416. void PushCheckInProgressMessage(std::string message)
  417. {
  418. this->CheckInProgressMessages.emplace_back(std::move(message));
  419. }
  420. std::vector<std::string> const& GetCheckInProgressMessages() const
  421. {
  422. return this->CheckInProgressMessages;
  423. }
  424. //! Should `message` command display context.
  425. bool GetShowLogContext() const { return this->LogContext; }
  426. void SetShowLogContext(bool b) { this->LogContext = b; }
  427. //! Do we want debug output during the cmake run.
  428. bool GetDebugOutput() const { return this->DebugOutput; }
  429. void SetDebugOutputOn(bool b) { this->DebugOutput = b; }
  430. //! Do we want debug output from the find commands during the cmake run.
  431. bool GetDebugFindOutput() const { return this->DebugFindOutput; }
  432. bool GetDebugFindOutput(std::string const& var) const;
  433. bool GetDebugFindPkgOutput(std::string const& pkg) const;
  434. void SetDebugFindOutput(bool b) { this->DebugFindOutput = b; }
  435. void SetDebugFindOutputPkgs(std::string const& args);
  436. void SetDebugFindOutputVars(std::string const& args);
  437. //! Do we want trace output during the cmake run.
  438. bool GetTrace() const
  439. {
  440. return this->Trace || !this->cmakeLangTraceCmdStack.empty();
  441. }
  442. void SetTrace(bool b) { this->Trace = b; }
  443. void PushTraceCmd(bool expandFlag)
  444. {
  445. this->cmakeLangTraceCmdStack.emplace(expandFlag);
  446. }
  447. bool PopTraceCmd();
  448. bool GetTraceExpand() const
  449. {
  450. return this->TraceExpand ||
  451. (!this->cmakeLangTraceCmdStack.empty() &&
  452. this->cmakeLangTraceCmdStack.top());
  453. }
  454. void SetTraceExpand(bool b) { this->TraceExpand = b; }
  455. TraceFormat GetTraceFormat() const { return this->TraceFormatVar; }
  456. void SetTraceFormat(TraceFormat f) { this->TraceFormatVar = f; }
  457. void AddTraceSource(std::string const& file)
  458. {
  459. this->TraceOnlyThisSources.push_back(file);
  460. }
  461. std::vector<std::string> const& GetTraceSources() const
  462. {
  463. return this->TraceOnlyThisSources;
  464. }
  465. cmGeneratedFileStream& GetTraceFile()
  466. {
  467. if (this->TraceRedirect) {
  468. return this->TraceRedirect->GetTraceFile();
  469. }
  470. return this->TraceFile;
  471. }
  472. void SetTraceFile(std::string const& file);
  473. void PrintTraceFormatVersion();
  474. #ifndef CMAKE_BOOTSTRAP
  475. cmConfigureLog* GetConfigureLog() const { return this->ConfigureLog.get(); }
  476. #endif
  477. //! Use trace from another ::cmake instance.
  478. void SetTraceRedirect(cmake* other);
  479. bool GetWarnUninitialized() const { return this->WarnUninitialized; }
  480. void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
  481. bool GetWarnUnusedCli() const { return this->WarnUnusedCli; }
  482. void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b; }
  483. bool GetCheckSystemVars() const { return this->CheckSystemVars; }
  484. void SetCheckSystemVars(bool b) { this->CheckSystemVars = b; }
  485. bool GetIgnoreCompileWarningAsError() const
  486. {
  487. return this->IgnoreCompileWarningAsError;
  488. }
  489. void SetIgnoreCompileWarningAsError(bool b)
  490. {
  491. this->IgnoreCompileWarningAsError = b;
  492. }
  493. bool GetIgnoreLinkWarningAsError() const
  494. {
  495. return this->IgnoreLinkWarningAsError;
  496. }
  497. void SetIgnoreLinkWarningAsError(bool b)
  498. {
  499. this->IgnoreLinkWarningAsError = b;
  500. }
  501. void MarkCliAsUsed(std::string const& variable);
  502. /** Get the list of configurations (in upper case) considered to be
  503. debugging configurations.*/
  504. std::vector<std::string> GetDebugConfigs();
  505. void SetCMakeEditCommand(std::string const& s)
  506. {
  507. this->CMakeEditCommand = s;
  508. }
  509. std::string const& GetCMakeEditCommand() const
  510. {
  511. return this->CMakeEditCommand;
  512. }
  513. cmMessenger* GetMessenger() const { return this->Messenger.get(); }
  514. #ifndef CMAKE_BOOTSTRAP
  515. /// Get the SARIF file path if set manually for this run
  516. cm::optional<std::string> GetSarifFilePath() const
  517. {
  518. return (this->SarifFileOutput ? cm::make_optional(this->SarifFilePath)
  519. : cm::nullopt);
  520. }
  521. #endif
  522. /**
  523. * Get the state of the suppression of developer (author) warnings.
  524. * Returns false, by default, if developer warnings should be shown, true
  525. * otherwise.
  526. */
  527. bool GetSuppressDevWarnings() const;
  528. /**
  529. * Set the state of the suppression of developer (author) warnings.
  530. */
  531. void SetSuppressDevWarnings(bool v);
  532. /**
  533. * Get the state of the suppression of deprecated warnings.
  534. * Returns false, by default, if deprecated warnings should be shown, true
  535. * otherwise.
  536. */
  537. bool GetSuppressDeprecatedWarnings() const;
  538. /**
  539. * Set the state of the suppression of deprecated warnings.
  540. */
  541. void SetSuppressDeprecatedWarnings(bool v);
  542. /**
  543. * Get the state of treating developer (author) warnings as errors.
  544. * Returns false, by default, if warnings should not be treated as errors,
  545. * true otherwise.
  546. */
  547. bool GetDevWarningsAsErrors() const;
  548. /**
  549. * Set the state of treating developer (author) warnings as errors.
  550. */
  551. void SetDevWarningsAsErrors(bool v);
  552. /**
  553. * Get the state of treating deprecated warnings as errors.
  554. * Returns false, by default, if warnings should not be treated as errors,
  555. * true otherwise.
  556. */
  557. bool GetDeprecatedWarningsAsErrors() const;
  558. /**
  559. * Set the state of treating developer (author) warnings as errors.
  560. */
  561. void SetDeprecatedWarningsAsErrors(bool v);
  562. /** Display a message to the user. */
  563. void IssueMessage(
  564. MessageType t, std::string const& text,
  565. cmListFileBacktrace const& backtrace = cmListFileBacktrace()) const;
  566. //! run the --build option
  567. int Build(int jobs, std::string dir, std::vector<std::string> targets,
  568. std::string config, std::vector<std::string> nativeOptions,
  569. cmBuildOptions& buildOptions, bool verbose,
  570. std::string const& presetName, bool listPresets,
  571. std::vector<std::string> const& args);
  572. enum class DryRun
  573. {
  574. No,
  575. Yes,
  576. };
  577. //! run the --open option
  578. bool Open(std::string const& dir, DryRun dryRun);
  579. //! run the --workflow option
  580. enum class WorkflowListPresets
  581. {
  582. No,
  583. Yes,
  584. };
  585. enum class WorkflowFresh
  586. {
  587. No,
  588. Yes,
  589. };
  590. int Workflow(std::string const& presetName, WorkflowListPresets listPresets,
  591. WorkflowFresh fresh);
  592. void UnwatchUnusedCli(std::string const& var);
  593. void WatchUnusedCli(std::string const& var);
  594. #if !defined(CMAKE_BOOTSTRAP)
  595. cmFileAPI* GetFileAPI() const { return this->FileAPI.get(); }
  596. cmInstrumentation* GetInstrumentation() const
  597. {
  598. return this->Instrumentation.get();
  599. }
  600. #endif
  601. cmState* GetState() const { return this->State.get(); }
  602. void SetCurrentSnapshot(cmStateSnapshot const& snapshot)
  603. {
  604. this->CurrentSnapshot = snapshot;
  605. }
  606. cmStateSnapshot GetCurrentSnapshot() const { return this->CurrentSnapshot; }
  607. bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; }
  608. void SetCMakeListName(std::string const& name);
  609. std::string GetCMakeListFile(std::string const& dir) const;
  610. #if !defined(CMAKE_BOOTSTRAP)
  611. cmMakefileProfilingData& GetProfilingOutput();
  612. bool IsProfilingEnabled() const;
  613. cm::optional<cmMakefileProfilingData::RAII> CreateProfilingEntry(
  614. std::string const& category, std::string const& name)
  615. {
  616. return this->CreateProfilingEntry(
  617. category, name, []() -> cm::nullopt_t { return cm::nullopt; });
  618. }
  619. template <typename ArgsFunc>
  620. cm::optional<cmMakefileProfilingData::RAII> CreateProfilingEntry(
  621. std::string const& category, std::string const& name, ArgsFunc&& argsFunc)
  622. {
  623. if (this->IsProfilingEnabled()) {
  624. return cm::make_optional<cmMakefileProfilingData::RAII>(
  625. this->GetProfilingOutput(), category, name, argsFunc());
  626. }
  627. return cm::nullopt;
  628. }
  629. #endif
  630. #ifdef CMake_ENABLE_DEBUGGER
  631. bool GetDebuggerOn() const { return this->DebuggerOn; }
  632. std::string GetDebuggerPipe() const { return this->DebuggerPipe; }
  633. std::string GetDebuggerDapLogFile() const
  634. {
  635. return this->DebuggerDapLogFile;
  636. }
  637. void SetDebuggerOn(bool b) { this->DebuggerOn = b; }
  638. bool StartDebuggerIfEnabled();
  639. void StopDebuggerIfNeeded(int exitCode);
  640. std::shared_ptr<cmDebugger::cmDebuggerAdapter> GetDebugAdapter()
  641. const noexcept
  642. {
  643. return this->DebugAdapter;
  644. }
  645. #endif
  646. protected:
  647. void RunCheckForUnusedVariables();
  648. int HandleDeleteCacheVariables(std::string const& var);
  649. using RegisteredGeneratorsVector =
  650. std::vector<std::unique_ptr<cmGlobalGeneratorFactory>>;
  651. RegisteredGeneratorsVector Generators;
  652. using RegisteredExtraGeneratorsVector =
  653. std::vector<cmExternalMakefileProjectGeneratorFactory*>;
  654. RegisteredExtraGeneratorsVector ExtraGenerators;
  655. void AddScriptingCommands() const;
  656. void AddProjectCommands() const;
  657. void AddDefaultGenerators();
  658. void AddDefaultExtraGenerators();
  659. std::map<std::string, DiagLevel> DiagLevels;
  660. std::string GeneratorInstance;
  661. std::string GeneratorPlatform;
  662. std::string GeneratorToolset;
  663. cm::optional<std::string> IntermediateDirStrategy;
  664. cm::optional<std::string> AutogenIntermediateDirStrategy;
  665. bool GeneratorInstanceSet = false;
  666. bool GeneratorPlatformSet = false;
  667. bool GeneratorToolsetSet = false;
  668. //! read in a cmake list file to initialize the cache
  669. void ReadListFile(std::vector<std::string> const& args,
  670. std::string const& path);
  671. bool FindPackage(std::vector<std::string> const& args);
  672. //! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file.
  673. /// If it is set, truncate it to 50kb
  674. void TruncateOutputLog(char const* fname);
  675. /**
  676. * Method called to check build system integrity at build time.
  677. * Returns 1 if CMake should rerun and 0 otherwise.
  678. */
  679. int CheckBuildSystem();
  680. bool SetDirectoriesFromFile(std::string const& arg);
  681. //! Make sure all commands are what they say they are and there is no
  682. /// macros.
  683. void CleanupCommandsAndMacros();
  684. void GenerateGraphViz(std::string const& fileName) const;
  685. private:
  686. std::vector<std::string> cmdArgs;
  687. std::string CMakeWorkingDirectory;
  688. ProgressCallbackType ProgressCallback;
  689. WorkingMode CurrentWorkingMode = NORMAL_MODE;
  690. CommandFailureAction CurrentCommandFailureAction =
  691. CommandFailureAction::FATAL_ERROR;
  692. bool DebugOutput = false;
  693. bool DebugFindOutput = false;
  694. // Elements of `cmakeLangTraceCmdStack` are "trace requests" pushed
  695. // by `cmake_language(TRACE ON [EXPAND])` and a boolean value is
  696. // a state of a given `EXPAND` option.
  697. std::stack<bool> cmakeLangTraceCmdStack;
  698. bool Trace = false;
  699. bool TraceExpand = false;
  700. TraceFormat TraceFormatVar = TraceFormat::Human;
  701. cmGeneratedFileStream TraceFile;
  702. cmake* TraceRedirect = nullptr;
  703. #ifndef CMAKE_BOOTSTRAP
  704. std::unique_ptr<cmConfigureLog> ConfigureLog;
  705. #endif
  706. bool WarnUninitialized = false;
  707. bool WarnUnusedCli = true;
  708. bool CheckSystemVars = false;
  709. bool IgnoreCompileWarningAsError = false;
  710. bool IgnoreLinkWarningAsError = false;
  711. std::map<std::string, bool> UsedCliVariables;
  712. std::string CMakeEditCommand;
  713. std::string CXXEnvironment;
  714. std::string CCEnvironment;
  715. std::string CheckBuildSystemArgument;
  716. std::string CheckStampFile;
  717. std::string CheckStampList;
  718. std::string VSSolutionFile;
  719. std::string EnvironmentGenerator;
  720. FileExtensions CLikeSourceFileExtensions;
  721. FileExtensions HeaderFileExtensions;
  722. FileExtensions CudaFileExtensions;
  723. FileExtensions ISPCFileExtensions;
  724. FileExtensions FortranFileExtensions;
  725. FileExtensions HipFileExtensions;
  726. bool ClearBuildSystem = false;
  727. bool DebugTryCompile = false;
  728. bool FreshCache = false;
  729. bool RegenerateDuringBuild = false;
  730. std::string CMakeListName;
  731. std::unique_ptr<cmFileTimeCache> FileTimeCache;
  732. std::string GraphVizFile;
  733. InstalledFilesMap InstalledFiles;
  734. #ifndef CMAKE_BOOTSTRAP
  735. std::map<std::string, cm::optional<cmCMakePresetsGraph::CacheVariable>>
  736. UnprocessedPresetVariables;
  737. std::map<std::string, cm::optional<std::string>>
  738. UnprocessedPresetEnvironment;
  739. #endif
  740. #if !defined(CMAKE_BOOTSTRAP)
  741. std::unique_ptr<cmVariableWatch> VariableWatch;
  742. std::unique_ptr<cmFileAPI> FileAPI;
  743. std::unique_ptr<cmInstrumentation> Instrumentation;
  744. #endif
  745. std::unique_ptr<cmState> State;
  746. cmStateSnapshot CurrentSnapshot;
  747. std::unique_ptr<cmMessenger> Messenger;
  748. #ifndef CMAKE_BOOTSTRAP
  749. bool SarifFileOutput = false;
  750. std::string SarifFilePath;
  751. #endif
  752. std::vector<std::string> TraceOnlyThisSources;
  753. std::set<std::string> DebugFindPkgs;
  754. std::set<std::string> DebugFindVars;
  755. Message::LogLevel MessageLogLevel = Message::LogLevel::LOG_STATUS;
  756. bool LogLevelWasSetViaCLI = false;
  757. bool LogContext = false;
  758. std::vector<std::string> CheckInProgressMessages;
  759. std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
  760. //! Print a list of valid generators to stderr.
  761. void PrintGeneratorList();
  762. std::unique_ptr<cmGlobalGenerator> EvaluateDefaultGlobalGenerator();
  763. void CreateDefaultGlobalGenerator();
  764. void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
  765. void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
  766. #if !defined(CMAKE_BOOTSTRAP)
  767. template <typename T>
  768. T const* FindPresetForWorkflow(
  769. cm::static_string_view type,
  770. std::map<std::string, cmCMakePresetsGraph::PresetPair<T>> const& presets,
  771. cmCMakePresetsGraph::WorkflowPreset::WorkflowStep const& step);
  772. #endif
  773. #if !defined(CMAKE_BOOTSTRAP)
  774. std::unique_ptr<cmMakefileProfilingData> ProfilingOutput;
  775. #endif
  776. #ifdef CMake_ENABLE_DEBUGGER
  777. std::shared_ptr<cmDebugger::cmDebuggerAdapter> DebugAdapter;
  778. bool DebuggerOn = false;
  779. std::string DebuggerPipe;
  780. std::string DebuggerDapLogFile;
  781. #endif
  782. cm::optional<int> ScriptModeExitCode;
  783. public:
  784. bool HasScriptModeExitCode() const { return ScriptModeExitCode.has_value(); }
  785. void SetScriptModeExitCode(int code) { ScriptModeExitCode = code; }
  786. int GetScriptModeExitCode() const { return ScriptModeExitCode.value_or(-1); }
  787. static cmDocumentationEntry CMAKE_STANDARD_OPTIONS_TABLE[19];
  788. };
  789. #define FOR_EACH_C90_FEATURE(F) F(c_function_prototypes)
  790. #define FOR_EACH_C99_FEATURE(F) \
  791. F(c_restrict) \
  792. F(c_variadic_macros)
  793. #define FOR_EACH_C11_FEATURE(F) F(c_static_assert)
  794. #define FOR_EACH_C_FEATURE(F) \
  795. F(c_std_90) \
  796. F(c_std_99) \
  797. F(c_std_11) \
  798. F(c_std_17) \
  799. F(c_std_23) \
  800. FOR_EACH_C90_FEATURE(F) \
  801. FOR_EACH_C99_FEATURE(F) \
  802. FOR_EACH_C11_FEATURE(F)
  803. #define FOR_EACH_CXX98_FEATURE(F) F(cxx_template_template_parameters)
  804. #define FOR_EACH_CXX11_FEATURE(F) \
  805. F(cxx_alias_templates) \
  806. F(cxx_alignas) \
  807. F(cxx_alignof) \
  808. F(cxx_attributes) \
  809. F(cxx_auto_type) \
  810. F(cxx_constexpr) \
  811. F(cxx_decltype) \
  812. F(cxx_decltype_incomplete_return_types) \
  813. F(cxx_default_function_template_args) \
  814. F(cxx_defaulted_functions) \
  815. F(cxx_defaulted_move_initializers) \
  816. F(cxx_delegating_constructors) \
  817. F(cxx_deleted_functions) \
  818. F(cxx_enum_forward_declarations) \
  819. F(cxx_explicit_conversions) \
  820. F(cxx_extended_friend_declarations) \
  821. F(cxx_extern_templates) \
  822. F(cxx_final) \
  823. F(cxx_func_identifier) \
  824. F(cxx_generalized_initializers) \
  825. F(cxx_inheriting_constructors) \
  826. F(cxx_inline_namespaces) \
  827. F(cxx_lambdas) \
  828. F(cxx_local_type_template_args) \
  829. F(cxx_long_long_type) \
  830. F(cxx_noexcept) \
  831. F(cxx_nonstatic_member_init) \
  832. F(cxx_nullptr) \
  833. F(cxx_override) \
  834. F(cxx_range_for) \
  835. F(cxx_raw_string_literals) \
  836. F(cxx_reference_qualified_functions) \
  837. F(cxx_right_angle_brackets) \
  838. F(cxx_rvalue_references) \
  839. F(cxx_sizeof_member) \
  840. F(cxx_static_assert) \
  841. F(cxx_strong_enums) \
  842. F(cxx_thread_local) \
  843. F(cxx_trailing_return_types) \
  844. F(cxx_unicode_literals) \
  845. F(cxx_uniform_initialization) \
  846. F(cxx_unrestricted_unions) \
  847. F(cxx_user_literals) \
  848. F(cxx_variadic_macros) \
  849. F(cxx_variadic_templates)
  850. #define FOR_EACH_CXX14_FEATURE(F) \
  851. F(cxx_aggregate_default_initializers) \
  852. F(cxx_attribute_deprecated) \
  853. F(cxx_binary_literals) \
  854. F(cxx_contextual_conversions) \
  855. F(cxx_decltype_auto) \
  856. F(cxx_digit_separators) \
  857. F(cxx_generic_lambdas) \
  858. F(cxx_lambda_init_captures) \
  859. F(cxx_relaxed_constexpr) \
  860. F(cxx_return_type_deduction) \
  861. F(cxx_variable_templates)
  862. #define FOR_EACH_CXX_FEATURE(F) \
  863. F(cxx_std_98) \
  864. F(cxx_std_11) \
  865. F(cxx_std_14) \
  866. F(cxx_std_17) \
  867. F(cxx_std_20) \
  868. F(cxx_std_23) \
  869. F(cxx_std_26) \
  870. FOR_EACH_CXX98_FEATURE(F) \
  871. FOR_EACH_CXX11_FEATURE(F) \
  872. FOR_EACH_CXX14_FEATURE(F)
  873. #define FOR_EACH_CUDA_FEATURE(F) \
  874. F(cuda_std_03) \
  875. F(cuda_std_11) \
  876. F(cuda_std_14) \
  877. F(cuda_std_17) \
  878. F(cuda_std_20) \
  879. F(cuda_std_23) \
  880. F(cuda_std_26)
  881. #define FOR_EACH_HIP_FEATURE(F) \
  882. F(hip_std_98) \
  883. F(hip_std_11) \
  884. F(hip_std_14) \
  885. F(hip_std_17) \
  886. F(hip_std_20) \
  887. F(hip_std_23) \
  888. F(hip_std_26)