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