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