1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #pragma once
4
5 #include "cmConfigure.h" // IWYU pragma: keep
6
7 #include <cstddef>
8 #include <iosfwd>
9 #include <map>
10 #include <memory>
11 #include <set>
12 #include <string>
13 #include <unordered_map>
14 #include <unordered_set>
15 #include <utility>
16 #include <vector>
17
18 #include <cm/optional>
19 #include <cmext/algorithm>
20
21 #include "cm_codecvt.hxx"
22
23 #include "cmCustomCommandLines.h"
24 #include "cmDuration.h"
25 #include "cmExportSet.h"
26 #include "cmStateSnapshot.h"
27 #include "cmStringAlgorithms.h"
28 #include "cmSystemTools.h"
29 #include "cmTarget.h"
30 #include "cmTargetDepend.h"
31 #include "cmTransformDepfile.h"
32 #include "cmValue.h"
33
34 #if !defined(CMAKE_BOOTSTRAP)
35 # include <cm3p/json/value.h>
36
37 # include "cmFileLockPool.h"
38 #endif
39
40 #define CMAKE_DIRECTORY_ID_SEP "::@"
41
42 class cmDirectoryId;
43 class cmExportBuildFileGenerator;
44 class cmExternalMakefileProjectGenerator;
45 class cmGeneratorTarget;
46 class cmInstallRuntimeDependencySet;
47 class cmLinkLineComputer;
48 class cmLocalGenerator;
49 class cmMakefile;
50 class cmOutputConverter;
51 class cmSourceFile;
52 class cmState;
53 class cmStateDirectory;
54 class cmake;
55
56 namespace detail {
AppendStrs(std::vector<std::string> &)57 inline void AppendStrs(std::vector<std::string>&)
58 {
59 }
60 template <typename T, typename... Ts>
AppendStrs(std::vector<std::string> & command,T && s,Ts &&...ts)61 inline void AppendStrs(std::vector<std::string>& command, T&& s, Ts&&... ts)
62 {
63 command.emplace_back(std::forward<T>(s));
64 AppendStrs(command, std::forward<Ts>(ts)...);
65 }
66
67 struct GeneratedMakeCommand
68 {
69 // Add each argument as a separate element to the vector
70 template <typename... T>
AddGeneratedMakeCommand71 void Add(T&&... args)
72 {
73 // iterate the args and append each one
74 AppendStrs(this->PrimaryCommand, std::forward<T>(args)...);
75 }
76
77 // Add each value in the iterators as a separate element to the vector
AddGeneratedMakeCommand78 void Add(std::vector<std::string>::const_iterator start,
79 std::vector<std::string>::const_iterator end)
80 {
81 cm::append(this->PrimaryCommand, start, end);
82 }
83
PrintableGeneratedMakeCommand84 std::string Printable() const { return cmJoin(this->PrimaryCommand, " "); }
85
86 std::vector<std::string> PrimaryCommand;
87 bool RequiresOutputForward = false;
88 };
89 }
90
91 /** \class cmGlobalGenerator
92 * \brief Responsible for overseeing the generation process for the entire tree
93 *
94 * Subclasses of this class generate makefiles for various
95 * platforms.
96 */
97 class cmGlobalGenerator
98 {
99 public:
100 using LocalGeneratorVector = std::vector<std::unique_ptr<cmLocalGenerator>>;
101
102 //! Free any memory allocated with the GlobalGenerator
103 cmGlobalGenerator(cmake* cm);
104 virtual ~cmGlobalGenerator();
105
106 virtual std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
107 cmMakefile* mf);
108
109 //! Get the name for this generator
GetName()110 virtual std::string GetName() const { return "Generic"; }
111
112 /** Check whether the given name matches the current generator. */
MatchesGeneratorName(const std::string & name)113 virtual bool MatchesGeneratorName(const std::string& name) const
114 {
115 return this->GetName() == name;
116 }
117
118 /** Get encoding used by generator for makefile files */
GetMakefileEncoding()119 virtual codecvt::Encoding GetMakefileEncoding() const
120 {
121 return codecvt::None;
122 }
123
124 #if !defined(CMAKE_BOOTSTRAP)
125 /** Get a JSON object describing the generator. */
126 virtual Json::Value GetJson() const;
127 #endif
128
129 /** Tell the generator about the target system. */
SetSystemName(std::string const &,cmMakefile *)130 virtual bool SetSystemName(std::string const&, cmMakefile*) { return true; }
131
132 /** Set the generator-specific instance. Returns true if supported. */
133 virtual bool SetGeneratorInstance(std::string const& i, cmMakefile* mf);
134
135 /** Set the generator-specific platform name. Returns true if platform
136 is supported and false otherwise. */
137 virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
138
139 /** Set the generator-specific toolset name. Returns true if toolset
140 is supported and false otherwise. */
141 virtual bool SetGeneratorToolset(std::string const& ts, bool build,
142 cmMakefile* mf);
143
144 /** Read any other cache entries needed for cmake --build. */
ReadCacheEntriesForBuild(const cmState &)145 virtual bool ReadCacheEntriesForBuild(const cmState& /*state*/)
146 {
147 return true;
148 }
149
150 /**
151 * Create LocalGenerators and process the CMakeLists files. This does not
152 * actually produce any makefiles, DSPs, etc.
153 */
154 virtual void Configure();
155
InspectConfigTypeVariables()156 virtual bool InspectConfigTypeVariables() { return true; }
157
158 bool Compute();
AddExtraIDETargets()159 virtual void AddExtraIDETargets() {}
160
161 enum TargetTypes
162 {
163 AllTargets,
164 ImportedOnly
165 };
166
167 void CreateImportedGenerationObjects(
168 cmMakefile* mf, std::vector<std::string> const& targets,
169 std::vector<cmGeneratorTarget const*>& exports);
170 void CreateGenerationObjects(TargetTypes targetTypes = AllTargets);
171
172 /**
173 * Generate the all required files for building this project/tree. This
174 * basically creates a series of LocalGenerators for each directory and
175 * requests that they Generate.
176 */
177 virtual void Generate();
178
179 virtual std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
180 cmOutputConverter* outputConverter,
181 cmStateDirectory const& stateDir) const;
182
183 std::unique_ptr<cmLinkLineComputer> CreateMSVC60LinkLineComputer(
184 cmOutputConverter* outputConverter,
185 cmStateDirectory const& stateDir) const;
186
187 /**
188 * Set/Get and Clear the enabled languages.
189 */
190 void SetLanguageEnabled(const std::string&, cmMakefile* mf);
191 bool GetLanguageEnabled(const std::string&) const;
192 void ClearEnabledLanguages();
193 void GetEnabledLanguages(std::vector<std::string>& lang) const;
194 /**
195 * Try to determine system information such as shared library
196 * extension, pthreads, byte order etc.
197 */
198 virtual void EnableLanguage(std::vector<std::string> const& languages,
199 cmMakefile*, bool optional);
200
201 /**
202 * Resolve the CMAKE_<lang>_COMPILER setting for the given language.
203 * Intended to be called from EnableLanguage.
204 */
205 void ResolveLanguageCompiler(const std::string& lang, cmMakefile* mf,
206 bool optional) const;
207
208 /**
209 * Try to determine system information, get it from another generator
210 */
211 void EnableLanguagesFromGenerator(cmGlobalGenerator* gen, cmMakefile* mf);
212
213 /**
214 * Try running cmake and building a file. This is used for dynamically
215 * loaded commands, not as part of the usual build process.
216 */
217 int TryCompile(int jobs, const std::string& srcdir,
218 const std::string& bindir, const std::string& projectName,
219 const std::string& targetName, bool fast, std::string& output,
220 cmMakefile* mf);
221
222 /**
223 * Build a file given the following information. This is a more direct call
224 * that is used by both CTest and TryCompile. If target name is NULL or
225 * empty then all is assumed. clean indicates if a "make clean" should be
226 * done first.
227 */
228 int Build(
229 int jobs, const std::string& srcdir, const std::string& bindir,
230 const std::string& projectName,
231 std::vector<std::string> const& targetNames, std::string& output,
232 const std::string& makeProgram, const std::string& config, bool clean,
233 bool fast, bool verbose, cmDuration timeout,
234 cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_NONE,
235 std::vector<std::string> const& nativeOptions =
236 std::vector<std::string>());
237
238 /**
239 * Open a generated IDE project given the following information.
240 */
241 virtual bool Open(const std::string& bindir, const std::string& projectName,
242 bool dryRun);
243
244 struct GeneratedMakeCommand final : public detail::GeneratedMakeCommand
245 {
246 };
247
248 virtual std::vector<GeneratedMakeCommand> GenerateBuildCommand(
249 const std::string& makeProgram, const std::string& projectName,
250 const std::string& projectDir, std::vector<std::string> const& targetNames,
251 const std::string& config, bool fast, int jobs, bool verbose,
252 std::vector<std::string> const& makeOptions = std::vector<std::string>());
253
254 virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const;
255
256 /**
257 * Generate a "cmake --build" call for a given target, config and parallel
258 * level.
259 */
260 std::string GenerateCMakeBuildCommand(const std::string& target,
261 const std::string& config,
262 const std::string& parallel,
263 const std::string& native,
264 bool ignoreErrors);
265
266 //! Get the CMake instance
GetCMakeInstance()267 cmake* GetCMakeInstance() const { return this->CMakeInstance; }
268
269 void SetConfiguredFilesPath(cmGlobalGenerator* gen);
GetMakefiles()270 const std::vector<std::unique_ptr<cmMakefile>>& GetMakefiles() const
271 {
272 return this->Makefiles;
273 }
GetLocalGenerators()274 const LocalGeneratorVector& GetLocalGenerators() const
275 {
276 return this->LocalGenerators;
277 }
278
279 std::vector<cmGeneratorTarget*> GetLocalGeneratorTargetsInOrder(
280 cmLocalGenerator* lg) const;
281
GetCurrentMakefile()282 cmMakefile* GetCurrentMakefile() const
283 {
284 return this->CurrentConfigureMakefile;
285 }
286
SetCurrentMakefile(cmMakefile * mf)287 void SetCurrentMakefile(cmMakefile* mf)
288 {
289 this->CurrentConfigureMakefile = mf;
290 }
291
292 void AddMakefile(std::unique_ptr<cmMakefile> mf);
293
294 //! Set an generator for an "external makefile based project"
295 void SetExternalMakefileProjectGenerator(
296 std::unique_ptr<cmExternalMakefileProjectGenerator> extraGenerator);
297
298 std::string GetExtraGeneratorName() const;
299
300 void AddInstallComponent(const std::string& component);
301
302 /** Mark the (absolute path to a) file as generated. */
303 void MarkAsGeneratedFile(const std::string& filepath);
304 /** Determine if the absolute filepath belongs to a generated file. */
305 bool IsGeneratedFile(const std::string& filepath);
306
GetInstallComponents()307 const std::set<std::string>* GetInstallComponents() const
308 {
309 return &this->InstallComponents;
310 }
311
GetExportSets()312 cmExportSetMap& GetExportSets() { return this->ExportSets; }
313
314 cmValue GetGlobalSetting(std::string const& name) const;
315 bool GlobalSettingIsOn(std::string const& name) const;
316 std::string GetSafeGlobalSetting(std::string const& name) const;
317
318 /** Add a file to the manifest of generated targets for a configuration. */
319 void AddToManifest(std::string const& f);
320
321 void EnableInstallTarget();
322
323 cmDuration TryCompileTimeout;
324
GetForceUnixPaths()325 bool GetForceUnixPaths() const { return this->ForceUnixPaths; }
GetToolSupportsColor()326 bool GetToolSupportsColor() const { return this->ToolSupportsColor; }
327
328 //! return the language for the given extension
329 std::string GetLanguageFromExtension(const char* ext) const;
330 //! is an extension to be ignored
331 bool IgnoreFile(const char* ext) const;
332 //! What is the preference for linkers and this language (None or Preferred)
333 int GetLinkerPreference(const std::string& lang) const;
334 //! What is the object file extension for a given source file?
335 std::string GetLanguageOutputExtension(cmSourceFile const&) const;
336
337 //! What is the configurations directory variable called?
GetCMakeCFGIntDir()338 virtual const char* GetCMakeCFGIntDir() const { return "."; }
339
340 //! expand CFGIntDir for a configuration
341 virtual std::string ExpandCFGIntDir(const std::string& str,
342 const std::string& config) const;
343
344 /** Get whether the generator should use a script for link commands. */
GetUseLinkScript()345 bool GetUseLinkScript() const { return this->UseLinkScript; }
346
347 /** Get whether the generator should produce special marks on rules
348 producing symbolic (non-file) outputs. */
GetNeedSymbolicMark()349 bool GetNeedSymbolicMark() const { return this->NeedSymbolicMark; }
350
351 /*
352 * Determine what program to use for building the project.
353 */
354 virtual bool FindMakeProgram(cmMakefile*);
355
356 //! Find a target by name by searching the local generators.
357 cmTarget* FindTarget(const std::string& name,
358 bool excludeAliases = false) const;
359
360 cmGeneratorTarget* FindGeneratorTarget(const std::string& name) const;
361
362 void AddAlias(const std::string& name, const std::string& tgtName);
363 bool IsAlias(const std::string& name) const;
364
365 /** Determine if a name resolves to a framework on disk or a built target
366 that is a framework. */
367 bool NameResolvesToFramework(const std::string& libname) const;
368
369 cmMakefile* FindMakefile(const std::string& start_dir) const;
370 cmLocalGenerator* FindLocalGenerator(cmDirectoryId const& id) const;
371
372 /** Append the subdirectory for the given configuration. If anything is
373 appended the given prefix and suffix will be appended around it, which
374 is useful for leading or trailing slashes. */
375 virtual void AppendDirectoryForConfig(const std::string& prefix,
376 const std::string& config,
377 const std::string& suffix,
378 std::string& dir);
379
380 /** Get the content of a directory. Directory listings are cached
381 and re-loaded from disk only when modified. During the generation
382 step the content will include the target files to be built even if
383 they do not yet exist. */
384 std::set<std::string> const& GetDirectoryContent(std::string const& dir,
385 bool needDisk = true);
386
387 void IndexTarget(cmTarget* t);
388 void IndexGeneratorTarget(cmGeneratorTarget* gt);
389
390 // Index the target using a name that is unique to that target
391 // even if other targets have the same name.
392 std::string IndexGeneratorTargetUniquely(cmGeneratorTarget const* gt);
393
394 static bool IsReservedTarget(std::string const& name);
395
GetAllTargetName()396 virtual const char* GetAllTargetName() const { return "ALL_BUILD"; }
GetInstallTargetName()397 virtual const char* GetInstallTargetName() const { return "INSTALL"; }
GetInstallLocalTargetName()398 virtual const char* GetInstallLocalTargetName() const { return nullptr; }
GetInstallStripTargetName()399 virtual const char* GetInstallStripTargetName() const { return nullptr; }
GetPreinstallTargetName()400 virtual const char* GetPreinstallTargetName() const { return nullptr; }
GetTestTargetName()401 virtual const char* GetTestTargetName() const { return "RUN_TESTS"; }
GetPackageTargetName()402 virtual const char* GetPackageTargetName() const { return "PACKAGE"; }
GetPackageSourceTargetName()403 virtual const char* GetPackageSourceTargetName() const { return nullptr; }
GetEditCacheTargetName()404 virtual const char* GetEditCacheTargetName() const { return nullptr; }
GetRebuildCacheTargetName()405 virtual const char* GetRebuildCacheTargetName() const { return nullptr; }
GetCleanTargetName()406 virtual const char* GetCleanTargetName() const { return nullptr; }
407
408 // Lookup edit_cache target command preferred by this generator.
GetEditCacheCommand()409 virtual std::string GetEditCacheCommand() const { return ""; }
410
411 // Default config to use for cmake --build
GetDefaultBuildConfig()412 virtual std::string GetDefaultBuildConfig() const { return "Debug"; }
413
414 // Class to track a set of dependencies.
415 using TargetDependSet = cmTargetDependSet;
416
417 // what targets does the specified target depend on directly
418 // via a target_link_libraries or add_dependencies
419 TargetDependSet const& GetTargetDirectDepends(
420 const cmGeneratorTarget* target);
421
GetProjectMap()422 const std::map<std::string, std::vector<cmLocalGenerator*>>& GetProjectMap()
423 const
424 {
425 return this->ProjectMap;
426 }
427
428 // track files replaced during a Generate
429 void FileReplacedDuringGenerate(const std::string& filename);
430 void GetFilesReplacedDuringGenerate(std::vector<std::string>& filenames);
431
432 void AddRuleHash(const std::vector<std::string>& outputs,
433 std::string const& content);
434
435 /** Return whether the given binary directory is unused. */
BinaryDirectoryIsNew(const std::string & dir)436 bool BinaryDirectoryIsNew(const std::string& dir)
437 {
438 return this->BinaryDirectories.insert(dir).second;
439 }
440
441 /** Return true if the generated build tree may contain multiple builds.
442 i.e. "Can I build Debug and Release in the same tree?" */
IsMultiConfig()443 virtual bool IsMultiConfig() const { return false; }
444
IsXcode()445 virtual bool IsXcode() const { return false; }
446
IsVisualStudio()447 virtual bool IsVisualStudio() const { return false; }
448
IsVisualStudioAtLeast10()449 virtual bool IsVisualStudioAtLeast10() const { return false; }
450
IsNinja()451 virtual bool IsNinja() const { return false; }
452
453 /** Return true if we know the exact location of object files.
454 If false, store the reason in the given string.
455 This is meaningful only after EnableLanguage has been called. */
HasKnownObjectFileLocation(std::string *)456 virtual bool HasKnownObjectFileLocation(std::string*) const { return true; }
457
458 virtual bool UseFolderProperty() const;
459
IsIPOSupported()460 virtual bool IsIPOSupported() const { return false; }
461
462 /** Return whether the generator can import external visual studio project
463 using INCLUDE_EXTERNAL_MSPROJECT */
IsIncludeExternalMSProjectSupported()464 virtual bool IsIncludeExternalMSProjectSupported() const { return false; }
465
466 /** Return whether the generator should use EFFECTIVE_PLATFORM_NAME. This is
467 relevant for mixed macOS and iOS builds. */
UseEffectivePlatformName(cmMakefile *)468 virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; }
469
470 /** Return whether the "Resources" folder prefix should be stripped from
471 MacFolder. */
472 virtual bool ShouldStripResourcePath(cmMakefile*) const;
473
SupportsCustomCommandDepfile()474 virtual bool SupportsCustomCommandDepfile() const { return false; }
DepfileFormat()475 virtual cm::optional<cmDepfileFormat> DepfileFormat() const
476 {
477 return cm::nullopt;
478 }
479
480 std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
481
482 /** Generate an <output>.rule file path for a given command output. */
483 virtual std::string GenerateRuleFile(std::string const& output) const;
484
SupportsDefaultBuildType()485 virtual bool SupportsDefaultBuildType() const { return false; }
SupportsCrossConfigs()486 virtual bool SupportsCrossConfigs() const { return false; }
SupportsDefaultConfigs()487 virtual bool SupportsDefaultConfigs() const { return false; }
488
489 static std::string EscapeJSON(const std::string& s);
490
491 void ProcessEvaluationFiles();
492
GetBuildExportSets()493 std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets()
494 {
495 return this->BuildExportSets;
496 }
497 void AddBuildExportSet(cmExportBuildFileGenerator* gen);
498 void AddBuildExportExportSet(cmExportBuildFileGenerator* gen);
499 bool IsExportedTargetsFile(const std::string& filename) const;
500 bool GenerateImportFile(const std::string& file);
501 cmExportBuildFileGenerator* GetExportedTargetsFile(
502 const std::string& filename) const;
503 void AddCMP0042WarnTarget(const std::string& target);
504 void AddCMP0068WarnTarget(const std::string& target);
505
506 virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
507
508 bool GenerateCPackPropertiesFile();
509
510 void SetFilenameTargetDepends(
511 cmSourceFile* sf, std::set<cmGeneratorTarget const*> const& tgts);
512 const std::set<const cmGeneratorTarget*>& GetFilenameTargetDepends(
513 cmSourceFile* sf) const;
514
515 #if !defined(CMAKE_BOOTSTRAP)
GetFileLockPool()516 cmFileLockPool& GetFileLockPool() { return this->FileLockPool; }
517 #endif
518
GetConfigureDoneCMP0026()519 bool GetConfigureDoneCMP0026() const
520 {
521 return this->ConfigureDoneCMP0026AndCMP0024;
522 }
523
524 std::string MakeSilentFlag;
525
526 int RecursionDepth;
527
GetQtAutoGenConfigs(std::vector<std::string> & configs)528 virtual void GetQtAutoGenConfigs(std::vector<std::string>& configs) const
529 {
530 configs.emplace_back("$<CONFIG>");
531 }
532
533 std::string const& GetRealPath(std::string const& dir);
534
535 std::string NewDeferId();
536
537 cmInstallRuntimeDependencySet* CreateAnonymousRuntimeDependencySet();
538
539 cmInstallRuntimeDependencySet* GetNamedRuntimeDependencySet(
540 const std::string& name);
541
542 protected:
543 // for a project collect all its targets by following depend
544 // information, and also collect all the targets
545 void GetTargetSets(TargetDependSet& projectTargets,
546 TargetDependSet& originalTargets, cmLocalGenerator* root,
547 std::vector<cmLocalGenerator*>& generators);
548 bool IsRootOnlyTarget(cmGeneratorTarget* target) const;
549 void AddTargetDepends(const cmGeneratorTarget* target,
550 TargetDependSet& projectTargets);
551 void SetLanguageEnabledFlag(const std::string& l, cmMakefile* mf);
552 void SetLanguageEnabledMaps(const std::string& l, cmMakefile* mf);
553 void FillExtensionToLanguageMap(const std::string& l, cmMakefile* mf);
554 virtual bool CheckLanguages(std::vector<std::string> const& languages,
555 cmMakefile* mf) const;
556 virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
557 cmValue envVar) const;
558
559 virtual bool ComputeTargetDepends();
560
561 virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
562
563 /// @brief Qt AUTOMOC/UIC/RCC target generation
564 /// @return true on success
565 bool QtAutoGen();
566
567 bool AddAutomaticSources();
568
569 std::string SelectMakeProgram(const std::string& makeProgram,
570 const std::string& makeDefault = "") const;
571
572 // Fill the ProjectMap, this must be called after LocalGenerators
573 // has been populated.
574 void FillProjectMap();
575 void CheckTargetProperties();
576 bool IsExcluded(cmStateSnapshot const& root,
577 cmStateSnapshot const& snp) const;
578 bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
579 bool IsExcluded(cmLocalGenerator* root,
580 const cmGeneratorTarget* target) const;
InitializeProgressMarks()581 virtual void InitializeProgressMarks() {}
582
583 struct GlobalTargetInfo
584 {
585 std::string Name;
586 std::string Message;
587 cmCustomCommandLines CommandLines;
588 std::vector<std::string> Depends;
589 std::string WorkingDir;
590 bool UsesTerminal = false;
591 cmTarget::PerConfig PerConfig = cmTarget::PerConfig::Yes;
592 bool StdPipesUTF8 = false;
593 };
594
595 void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets);
596
597 void AddGlobalTarget_Package(std::vector<GlobalTargetInfo>& targets);
598 void AddGlobalTarget_PackageSource(std::vector<GlobalTargetInfo>& targets);
599 void AddGlobalTarget_Test(std::vector<GlobalTargetInfo>& targets);
600 void AddGlobalTarget_EditCache(std::vector<GlobalTargetInfo>& targets) const;
601 void AddGlobalTarget_RebuildCache(
602 std::vector<GlobalTargetInfo>& targets) const;
603 void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets);
604 void CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf);
605
606 std::string FindMakeProgramFile;
607 std::string ConfiguredFilesPath;
608 cmake* CMakeInstance;
609 std::vector<std::unique_ptr<cmMakefile>> Makefiles;
610 LocalGeneratorVector LocalGenerators;
611 cmMakefile* CurrentConfigureMakefile;
612 // map from project name to vector of local generators in that project
613 std::map<std::string, std::vector<cmLocalGenerator*>> ProjectMap;
614
615 // Set of named installation components requested by the project.
616 std::set<std::string> InstallComponents;
617 // Sets of named target exports
618 cmExportSetMap ExportSets;
619 std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets;
620 std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets;
621
622 std::map<std::string, std::string> AliasTargets;
623
624 cmTarget* FindTargetImpl(std::string const& name) const;
625
626 cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
627
628 std::string GetPredefinedTargetsFolder() const;
629
630 private:
631 using TargetMap = std::unordered_map<std::string, cmTarget*>;
632 using GeneratorTargetMap =
633 std::unordered_map<std::string, cmGeneratorTarget*>;
634 using MakefileMap = std::unordered_map<std::string, cmMakefile*>;
635 using LocalGeneratorMap = std::unordered_map<std::string, cmLocalGenerator*>;
636 // Map efficiently from target name to cmTarget instance.
637 // Do not use this structure for looping over all targets.
638 // It contains both normal and globally visible imported targets.
639 TargetMap TargetSearchIndex;
640 GeneratorTargetMap GeneratorTargetSearchIndex;
641
642 // Map efficiently from source directory path to cmMakefile instance.
643 // Do not use this structure for looping over all directories.
644 // It may not contain all of them (see note in IndexMakefile method).
645 MakefileMap MakefileSearchIndex;
646
647 // Map efficiently from source directory path to cmLocalGenerator instance.
648 // Do not use this structure for looping over all directories.
649 // Its order is not deterministic.
650 LocalGeneratorMap LocalGeneratorSearchIndex;
651
652 void ComputeTargetOrder();
653 void ComputeTargetOrder(cmGeneratorTarget const* gt, size_t& index);
654 std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex;
655
656 cmMakefile* TryCompileOuterMakefile;
657 // If you add a new map here, make sure it is copied
658 // in EnableLanguagesFromGenerator
659 std::map<std::string, bool> IgnoreExtensions;
660 std::set<std::string> LanguagesReady; // Ready for try_compile
661 std::set<std::string> LanguagesInProgress;
662 std::map<std::string, std::string> OutputExtensions;
663 std::map<std::string, std::string> LanguageToOutputExtension;
664 std::map<std::string, std::string> ExtensionToLanguage;
665 std::map<std::string, int> LanguageToLinkerPreference;
666 std::map<std::string, std::string> LanguageToOriginalSharedLibFlags;
667
668 // Deferral id generation.
669 size_t NextDeferId = 0;
670
671 // Record hashes for rules and outputs.
672 struct RuleHash
673 {
674 char Data[32];
675 };
676 std::map<std::string, RuleHash> RuleHashes;
677 void CheckRuleHashes();
678 void CheckRuleHashes(std::string const& pfile, std::string const& home);
679 void WriteRuleHashes(std::string const& pfile);
680
681 void WriteSummary();
682 void WriteSummary(cmGeneratorTarget* target);
683 void FinalizeTargetCompileInfo();
684
685 virtual void ForceLinkerLanguages();
686
687 bool CheckTargetsForMissingSources() const;
688 bool CheckTargetsForType() const;
689 bool CheckTargetsForPchCompilePdb() const;
690
691 void CreateLocalGenerators();
692
693 void CheckCompilerIdCompatibility(cmMakefile* mf,
694 std::string const& lang) const;
695
696 void ComputeBuildFileGenerators();
697
698 std::unique_ptr<cmExternalMakefileProjectGenerator> ExtraGenerator;
699
700 // track files replaced during a Generate
701 std::vector<std::string> FilesReplacedDuringGenerate;
702
703 // Store computed inter-target dependencies.
704 using TargetDependMap = std::map<cmGeneratorTarget const*, TargetDependSet>;
705 TargetDependMap TargetDependencies;
706
707 friend class cmake;
708 void CreateGeneratorTargets(
709 TargetTypes targetTypes, cmMakefile* mf, cmLocalGenerator* lg,
710 std::map<cmTarget*, cmGeneratorTarget*> const& importedMap);
711 void CreateGeneratorTargets(TargetTypes targetTypes);
712
713 void ClearGeneratorMembers();
714
715 bool CheckCMP0037(std::string const& targetName,
716 std::string const& reason) const;
717
718 void IndexMakefile(cmMakefile* mf);
719 void IndexLocalGenerator(cmLocalGenerator* lg);
720
GetBuildIgnoreErrorsFlag()721 virtual const char* GetBuildIgnoreErrorsFlag() const { return nullptr; }
722
723 bool UnsupportedVariableIsDefined(const std::string& name,
724 bool supported) const;
725
726 // Cache directory content and target files to be built.
727 struct DirectoryContent
728 {
729 long LastDiskTime = -1;
730 std::set<std::string> All;
731 std::set<std::string> Generated;
732 };
733 std::map<std::string, DirectoryContent> DirectoryContentMap;
734
735 // Set of binary directories on disk.
736 std::set<std::string> BinaryDirectories;
737
738 // track targets to issue CMP0042 warning for.
739 std::set<std::string> CMP0042WarnTargets;
740 // track targets to issue CMP0068 warning for.
741 std::set<std::string> CMP0068WarnTargets;
742
743 mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>>
744 FilenameTargetDepends;
745
746 std::map<std::string, std::string> RealPaths;
747
748 std::unordered_set<std::string> GeneratedFiles;
749
750 std::vector<std::unique_ptr<cmInstallRuntimeDependencySet>>
751 RuntimeDependencySets;
752 std::map<std::string, cmInstallRuntimeDependencySet*>
753 RuntimeDependencySetsByName;
754
755 #if !defined(CMAKE_BOOTSTRAP)
756 // Pool of file locks
757 cmFileLockPool FileLockPool;
758 #endif
759
760 protected:
761 float FirstTimeProgress;
762 bool NeedSymbolicMark;
763 bool UseLinkScript;
764 bool ForceUnixPaths;
765 bool ToolSupportsColor;
766 bool InstallTargetEnabled;
767 bool ConfigureDoneCMP0026AndCMP0024;
768 };
769