Coverage Report

Created: 2026-10-28 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmGlobalGenerator.h
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#pragma once
4
5
#include "cmConfigure.h" // IWYU pragma: keep
6
7
#include <cstddef>
8
#include <functional>
9
#include <iosfwd>
10
#include <map>
11
#include <memory>
12
#include <set>
13
#include <string>
14
#include <unordered_map>
15
#include <unordered_set>
16
#include <utility>
17
#include <vector>
18
19
#include <cm/optional>
20
#include <cm/string_view>
21
#include <cmext/algorithm>
22
#include <cmext/string_view>
23
24
#include "cmBuildOptions.h"
25
#include "cmCustomCommandLines.h"
26
#include "cmDuration.h"
27
#include "cmExportFileGenerator.h"
28
#include "cmExportSet.h"
29
#include "cmInstallGenerator.h"
30
#include "cmLocalGenerator.h"
31
#include "cmSbomBuilder.h"
32
#include "cmStateSnapshot.h"
33
#include "cmStateTypes.h"
34
#include "cmStringAlgorithms.h"
35
#include "cmSystemTools.h"
36
#include "cmTarget.h"
37
#include "cmTargetDepend.h"
38
#include "cmTargetTypes.h"
39
#include "cmTestGenerator.h"
40
#include "cmValue.h"
41
#include "cmXcFramework.h"
42
43
#if !defined(CMAKE_BOOTSTRAP)
44
#  include <cm3p/json/value.h>
45
46
#  include "cmFileLockPool.h"
47
#endif
48
49
154k
#define CMAKE_DIRECTORY_ID_SEP "::@"
50
51
enum class cmDepfileFormat;
52
enum class codecvt_Encoding;
53
54
class cmBuildArgs;
55
class cmDirectoryId;
56
class cmExportBuildFileGenerator;
57
class cmExternalMakefileProjectGenerator;
58
class cmBuildSbomGenerator;
59
class cmInstallSbomGenerator;
60
class cmGeneratorTarget;
61
class cmRule;
62
class cmGeneratorRule;
63
class cmInstallRuntimeDependencySet;
64
class cmLinkLineComputer;
65
class cmMakefile;
66
class cmOutputConverter;
67
class cmQtAutoGenGlobalInitializer;
68
class cmSourceFile;
69
class cmState;
70
class cmStateDirectory;
71
class cmake;
72
73
namespace detail {
74
inline void AppendStrs(std::vector<std::string>&)
75
0
{
76
0
}
77
template <typename T, typename... Ts>
78
inline void AppendStrs(std::vector<std::string>& command, T&& s, Ts&&... ts)
79
0
{
80
0
  command.emplace_back(std::forward<T>(s));
81
0
  AppendStrs(command, std::forward<Ts>(ts)...);
82
0
}
Unexecuted instantiation: void detail::AppendStrs<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Unexecuted instantiation: void detail::AppendStrs<char const (&) [3]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [3])
Unexecuted instantiation: void detail::AppendStrs<char const (&) [3], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [3], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Unexecuted instantiation: void detail::AppendStrs<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: void detail::AppendStrs<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Unexecuted instantiation: void detail::AppendStrs<char const (&) [8], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [8], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Unexecuted instantiation: void detail::AppendStrs<char const (&) [21]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [21])
Unexecuted instantiation: void detail::AppendStrs<char const (&) [15]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [15])
Unexecuted instantiation: void detail::AppendStrs<char const (&) [9]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [9])
Unexecuted instantiation: void detail::AppendStrs<char const (&) [10]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [10])
Unexecuted instantiation: void detail::AppendStrs<char const (&) [5], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [5], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Unexecuted instantiation: void detail::AppendStrs<char const (&) [7]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [7])
Unexecuted instantiation: void detail::AppendStrs<char const (&) [56]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [56])
Unexecuted instantiation: void detail::AppendStrs<char const (&) [4]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [4])
Unexecuted instantiation: void detail::AppendStrs<char const (&) [29]>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, char const (&) [29])
83
84
struct GeneratedMakeCommand
85
{
86
  // Add each argument as a separate element to the vector
87
  template <typename... T>
88
  void Add(T&&... args)
89
0
  {
90
    // iterate the args and append each one
91
0
    AppendStrs(this->PrimaryCommand, std::forward<T>(args)...);
92
0
  }
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [3]>(char const (&) [3])
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [3], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(char const (&) [3], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [8], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(char const (&) [8], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [21]>(char const (&) [21])
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [15]>(char const (&) [15])
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [9]>(char const (&) [9])
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [10]>(char const (&) [10])
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [5], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(char const (&) [5], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [7]>(char const (&) [7])
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [56]>(char const (&) [56])
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [4]>(char const (&) [4])
Unexecuted instantiation: void detail::GeneratedMakeCommand::Add<char const (&) [29]>(char const (&) [29])
93
94
  // Add each value in the iterators as a separate element to the vector
95
  void Add(std::vector<std::string>::const_iterator start,
96
           std::vector<std::string>::const_iterator end)
97
0
  {
98
0
    cm::append(this->PrimaryCommand, start, end);
99
0
  }
100
101
0
  std::string Printable() const { return cmJoin(this->PrimaryCommand, " "); }
102
  std::string QuotedPrintable() const;
103
104
  std::vector<std::string> PrimaryCommand;
105
};
106
}
107
namespace Json {
108
class StreamWriter;
109
}
110
111
/** \class cmGlobalGenerator
112
 * \brief Responsible for overseeing the generation process for the entire tree
113
 *
114
 * Subclasses of this class generate makefiles for various
115
 * platforms.
116
 */
117
class cmGlobalGenerator
118
{
119
public:
120
  using LocalGeneratorVector = std::vector<std::unique_ptr<cmLocalGenerator>>;
121
  enum class BuildTryCompile
122
  {
123
    No,
124
    Yes,
125
  };
126
127
  //! Free any memory allocated with the GlobalGenerator
128
  cmGlobalGenerator(cmake* cm);
129
  virtual ~cmGlobalGenerator();
130
131
  virtual std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
132
    cmMakefile* mf);
133
134
  //! Get the name for this generator
135
661
  virtual std::string GetName() const { return "Generic"; }
136
137
  virtual std::vector<std::string> GetTestBuildDependencyPaths(
138
    std::string const& config,
139
    cmTestGenerator::BuildDependencies const& deps) const;
140
141
  struct InstallPrepTargets
142
  {
143
    struct TargetRequirements
144
    {
145
      bool Normal = false;
146
      bool InstallArtifact = false;
147
      std::set<std::string> GeneratedFiles;
148
    };
149
150
    using TargetMap = std::map<cmGeneratorTarget const*, TargetRequirements>;
151
152
    TargetMap All;
153
    std::map<std::string, TargetMap> Components;
154
155
    // Generated files that no target prepares, such as byproducts installed
156
    // by install(FILES).  Only generators that support depending on them
157
    // prepare these files.
158
    std::set<std::string> AllFiles;
159
    std::map<std::string, std::set<std::string>> ComponentFiles;
160
  };
161
162
  InstallPrepTargets GetInstallPrepTargets(std::string const& config);
163
164
  // Whether install preparation targets can depend on a generated file that
165
  // is not the unique output of a target.
166
0
  virtual bool SupportsInstallPrepFileDependencies() const { return false; }
167
168
  // Whether the name of an install component can be used in the name of its
169
  // install preparation target.
170
  virtual bool IsInstallPrepComponentRepresentable(
171
    std::string const& component) const;
172
173
  // Diagnose install rules that no install preparation target prepares.
174
  // Generators that write install preparation targets call this once.
175
  void CheckInstallPrepTargets();
176
177
  // Whether a generated file to be prepared for installation is the unique
178
  // output of a target.  Generators that cannot depend on a file with no such
179
  // owner build its installing target instead, and call this to diagnose it
180
  // once per file.
181
  bool CheckInstallPrepGeneratedFile(cmGeneratorTarget const* target,
182
                                     std::string const& file,
183
                                     std::set<std::string>& diagnosed);
184
185
  bool AreInstallPrepTargetsEnabled() const;
186
187
  /** Check whether the given name matches the current generator.  */
188
  virtual bool MatchesGeneratorName(std::string const& name) const
189
0
  {
190
0
    return this->GetName() == name;
191
0
  }
192
193
  /** Get encoding used by generator for makefile files */
194
  virtual codecvt_Encoding GetMakefileEncoding() const;
195
196
#if !defined(CMAKE_BOOTSTRAP)
197
  /** Get a JSON object describing the generator.  */
198
  virtual Json::Value GetJson() const;
199
#endif
200
201
  /** Tell the generator about the target system.  */
202
0
  virtual bool SetSystemName(std::string const&, cmMakefile*) { return true; }
203
204
  /** Set the generator-specific instance.  Returns true if supported.  */
205
  virtual bool SetGeneratorInstance(std::string const& i, cmMakefile* mf);
206
207
  /** Set the generator-specific platform name.  Returns true if platform
208
      is supported and false otherwise.  */
209
  virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
210
211
  /** Set the generator-specific toolset name.  Returns true if toolset
212
      is supported and false otherwise.  */
213
  virtual bool SetGeneratorToolset(std::string const& ts, bool build,
214
                                   cmMakefile* mf);
215
216
  /** Read any other cache entries needed for cmake --build. */
217
  virtual bool ReadCacheEntriesForBuild(cmState const& /*state*/)
218
0
  {
219
0
    return true;
220
0
  }
221
222
  /**
223
   * Create LocalGenerators and process the CMakeLists files. This does not
224
   * actually produce any makefiles, DSPs, etc.
225
   */
226
  virtual void Configure();
227
228
0
  virtual bool InspectConfigTypeVariables() { return true; }
229
230
  enum class CxxModuleSupportQuery
231
  {
232
    // Support is expected at the call site.
233
    Expected,
234
    // The call site is querying for support and handles problems by itself.
235
    Inspect,
236
  };
237
  virtual bool CheckCxxModuleSupport(CxxModuleSupportQuery /*query*/)
238
0
  {
239
0
    return false;
240
0
  }
241
242
0
  virtual bool SupportsCustomObjectNames() const { return true; }
243
244
0
  virtual bool SupportsBuildDatabase() const { return false; }
245
  bool AddBuildDatabaseTargets();
246
  void AddBuildDatabaseFile(std::string const& lang, std::string const& config,
247
                            std::string const& path);
248
249
0
  virtual bool IsGNUMakeJobServerAware() const { return false; }
250
251
  bool Compute();
252
0
  virtual void AddExtraIDETargets() {}
253
254
  enum TargetTypes
255
  {
256
    AllTargets,
257
    ImportedOnly
258
  };
259
260
  void CreateImportedGenerationObjects(
261
    cmMakefile* mf, std::vector<std::string> const& targets,
262
    std::vector<cmGeneratorTarget const*>& exports);
263
  void CreateGenerationObjects(TargetTypes targetTypes = AllTargets);
264
265
  /**
266
   * Generate the all required files for building this project/tree. This
267
   * basically creates a series of LocalGenerators for each directory and
268
   * requests that they Generate.
269
   */
270
  virtual void Generate();
271
272
  virtual std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
273
    cmOutputConverter* outputConverter,
274
    cmStateDirectory const& stateDir) const;
275
276
  std::unique_ptr<cmLinkLineComputer> CreateMSVC60LinkLineComputer(
277
    cmOutputConverter* outputConverter,
278
    cmStateDirectory const& stateDir) const;
279
280
  /**
281
   * Set/Get and Clear the enabled languages.
282
   */
283
  void SetLanguageEnabled(std::string const&, cmMakefile* mf);
284
  bool GetLanguageEnabled(std::string const&) const;
285
  void ClearEnabledLanguages();
286
  void GetEnabledLanguages(std::vector<std::string>& lang) const;
287
  /**
288
   * Try to determine system information such as shared library
289
   * extension, pthreads, byte order etc.
290
   */
291
  virtual void EnableLanguage(std::vector<std::string> const& languages,
292
                              cmMakefile*, bool optional);
293
294
  /**
295
   * Resolve the CMAKE_<lang>_COMPILER setting for the given language.
296
   * Intended to be called from EnableLanguage.
297
   */
298
  void ResolveLanguageCompiler(std::string const& lang, cmMakefile* mf,
299
                               bool optional) const;
300
301
  void SetupTryCompile(cmGlobalGenerator* gen, cmMakefile* mf);
302
  /**
303
   * Try running cmake and building a file. This is used for dynamically
304
   * loaded commands, not as part of the usual build process.
305
   */
306
  int TryCompile(int jobs, std::string const& bindir,
307
                 std::string const& projectName, std::string const& targetName,
308
                 bool fast, std::string& output, cmMakefile* mf);
309
310
  /**
311
   * Build a file given the following information. This is a more direct call
312
   * that is used by both CTest and TryCompile. If target name is NULL or
313
   * empty then all is assumed. clean indicates if a "make clean" should be
314
   * done first.
315
   */
316
  int Build(
317
    cmBuildArgs const& buildArgs, std::vector<std::string> const& targetNames,
318
    std::ostream& ostr, std::string const& makeProgram,
319
    std::string const& config, cmBuildOptions buildOptions, cmDuration timeout,
320
    cmSystemTools::OutputOption outputMode,
321
    std::vector<std::string> const& nativeOptions = std::vector<std::string>(),
322
    BuildTryCompile isInTryCompile = BuildTryCompile::No);
323
324
  /**
325
   * Open a generated IDE project given the following information.
326
   */
327
  virtual bool Open(std::string const& bindir, std::string const& projectName,
328
                    bool dryRun);
329
330
  struct GeneratedMakeCommand final : public detail::GeneratedMakeCommand
331
  {
332
  };
333
334
  virtual std::vector<GeneratedMakeCommand> GenerateBuildCommand(
335
    std::string const& makeProgram, std::string const& projectName,
336
    std::string const& projectDir, std::vector<std::string> const& targetNames,
337
    std::string const& config, int jobs, bool verbose,
338
    cmBuildOptions buildOptions = cmBuildOptions(),
339
    std::vector<std::string> const& makeOptions = std::vector<std::string>(),
340
    BuildTryCompile isInTryCompile = BuildTryCompile::No);
341
342
  virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const;
343
344
  /**
345
   * Generate a "cmake --build" call for a given target, config and parallel
346
   * level.
347
   */
348
  std::string GenerateCMakeBuildCommand(std::string const& target,
349
                                        std::string const& config,
350
                                        std::string const& parallel,
351
                                        std::string const& native,
352
                                        bool ignoreErrors);
353
354
  //! Get the CMake instance
355
25.1M
  cmake* GetCMakeInstance() const { return this->CMakeInstance; }
356
357
  void SetConfiguredFilesPath(cmGlobalGenerator* gen);
358
  std::vector<std::unique_ptr<cmMakefile>> const& GetMakefiles() const
359
0
  {
360
0
    return this->Makefiles;
361
0
  }
362
  LocalGeneratorVector const& GetLocalGenerators() const
363
11.8k
  {
364
11.8k
    return this->LocalGenerators;
365
11.8k
  }
366
367
  std::vector<cmGeneratorTarget*> GetLocalGeneratorTargetsInOrder(
368
    cmLocalGenerator* lg) const;
369
370
  // Find the single build-system target that produces the given path as a
371
  // primary custom-command output, or nullptr if there is none or more than
372
  // one.  Used to resolve file-level test build dependencies.
373
  cmGeneratorTarget* FindOutputOwningTarget(std::string const& output);
374
375
  // Whether the build generates the file, as the output or byproduct of a
376
  // custom command or custom target.
377
  bool IsGeneratedByBuild(std::string const& file);
378
379
  // Called by local generators when they record a new output or byproduct,
380
  // so that IsGeneratedByBuild rebuilds its index before its next lookup.
381
  void InvalidateGeneratedByBuildIndex()
382
5.92k
  {
383
5.92k
    this->GeneratedByBuildIndexComputed = false;
384
5.92k
  }
385
386
  // Find the single build-system target whose build produces the given path
387
  // as a linked artifact for the given configuration, or nullptr if there is
388
  // none or more than one.
389
  cmGeneratorTarget* FindArtifactOwningTarget(std::string const& artifact,
390
                                              std::string const& config);
391
392
  cmMakefile* GetCurrentMakefile() const
393
0
  {
394
0
    return this->CurrentConfigureMakefile;
395
0
  }
396
397
  void SetCurrentMakefile(cmMakefile* mf)
398
0
  {
399
0
    this->CurrentConfigureMakefile = mf;
400
0
  }
401
402
  void AddMakefile(std::unique_ptr<cmMakefile> mf);
403
404
  //! Set an generator for an "external makefile based project"
405
  void SetExternalMakefileProjectGenerator(
406
    std::unique_ptr<cmExternalMakefileProjectGenerator> extraGenerator);
407
408
  std::string GetExtraGeneratorName() const;
409
410
  void AddInstallComponent(std::string const& component);
411
412
  /** Mark the (absolute path to a) file as generated.  */
413
  void MarkAsGeneratedFile(std::string const& filepath);
414
  /** Determine if the absolute filepath belongs to a generated file.  */
415
  bool IsGeneratedFile(std::string const& filepath);
416
417
  std::set<std::string> const* GetInstallComponents() const
418
0
  {
419
0
    return &this->InstallComponents;
420
0
  }
421
422
0
  cmExportSetMap& GetExportSets() { return this->ExportSets; }
423
424
  cmValue GetGlobalSetting(std::string const& name) const;
425
  bool GlobalSettingIsOn(std::string const& name) const;
426
  std::string GetSafeGlobalSetting(std::string const& name) const;
427
428
  /** Add a file to the manifest of generated targets for a configuration.  */
429
  void AddToManifest(std::string const& f);
430
431
  void EnableInstallTarget();
432
433
  cmDuration TryCompileTimeout;
434
435
5.92k
  bool GetForceUnixPaths() const { return this->ForceUnixPaths; }
436
0
  bool GetToolSupportsColor() const { return this->ToolSupportsColor; }
437
438
  //! return the language for the given extension
439
  cm::string_view GetLanguageFromExtension(cm::string_view ext) const;
440
  //! is an extension to be ignored
441
  bool IgnoreFile(cm::string_view ext) const;
442
  //! What is the preference for linkers and this language (None or Preferred)
443
  int GetLinkerPreference(std::string const& lang) const;
444
  //! What is the object file extension for a given source file?
445
  std::string GetLanguageOutputExtension(cmSourceFile const&) const;
446
  //! What is the object file extension for a given language?
447
  std::string GetLanguageOutputExtension(std::string const& lang) const;
448
  //! What is the object file extension for a given --emit option in Rust?
449
  std::string GetRustEmitOutputExtension(std::string const& emitValue) const;
450
451
  //! What is the configurations directory variable called?
452
5.92k
  virtual char const* GetCMakeCFGIntDir() const { return "."; }
453
454
  //! expand CFGIntDir for a configuration
455
  virtual std::string ExpandCFGIntDir(std::string const& str,
456
                                      std::string const& config) const;
457
458
  /** Get whether the generator should use a script for link commands.  */
459
0
  bool GetUseLinkScript() const { return this->UseLinkScript; }
460
461
  /** Get whether the generator should produce special marks on rules
462
      producing symbolic (non-file) outputs.  */
463
0
  bool GetNeedSymbolicMark() const { return this->NeedSymbolicMark; }
464
465
  /*
466
   * Determine what program to use for building the project.
467
   */
468
  virtual bool FindMakeProgram(cmMakefile*);
469
470
  //! Find a target by name by searching the local generators.
471
  cmTarget* FindTarget(std::string const& name,
472
                       cm::TargetDomainSet domains = {
473
                         cm::TargetDomain::NATIVE,
474
                         cm::TargetDomain::ALIAS }) const;
475
476
  cmGeneratorTarget* FindGeneratorTarget(std::string const& name) const;
477
478
  void AddAlias(std::string const& name, std::string const& tgtName);
479
  bool IsAlias(std::string const& name) const;
480
481
  //! Find a rule by name.
482
  cmRule* FindRule(std::string const& name) const;
483
  cmGeneratorRule* FindGeneratorRule(std::string const& name) const;
484
485
  /** Determine if a name resolves to a framework on disk or a built target
486
      that is a framework. */
487
  bool NameResolvesToFramework(std::string const& libname) const;
488
  /** Split a framework path to the directory and name of the framework as well
489
   * as optional suffix.
490
   * Returns std::nullopt if the path does not match with framework format
491
   * when extendedFormat is true, required format is relaxed (i.e. extension
492
   * `.framework' is optional). Used when FRAMEWORK link feature is
493
   * specified */
494
  struct FrameworkDescriptor
495
  {
496
    FrameworkDescriptor(std::string directory, std::string name)
497
0
      : Directory(std::move(directory))
498
0
      , Name(std::move(name))
499
0
    {
500
0
    }
501
    FrameworkDescriptor(std::string directory, std::string version,
502
                        std::string name)
503
0
      : Directory(std::move(directory))
504
0
      , Version(std::move(version))
505
0
      , Name(std::move(name))
506
0
    {
507
0
    }
508
    FrameworkDescriptor(std::string directory, std::string version,
509
                        std::string name, std::string suffix)
510
0
      : Directory(std::move(directory))
511
0
      , Version(std::move(version))
512
0
      , Name(std::move(name))
513
0
      , Suffix(std::move(suffix))
514
0
    {
515
0
    }
516
    std::string GetLinkName() const
517
0
    {
518
0
      return this->Suffix.empty() ? this->Name
519
0
                                  : cmStrCat(this->Name, ',', this->Suffix);
520
0
    }
521
    std::string GetFullName() const
522
0
    {
523
0
      return cmStrCat(this->Name, ".framework/"_s, this->Name, this->Suffix);
524
0
    }
525
    std::string GetVersionedName() const
526
0
    {
527
0
      return this->Version.empty()
528
0
        ? this->GetFullName()
529
0
        : cmStrCat(this->Name, ".framework/Versions/"_s, this->Version, '/',
530
0
                   this->Name, this->Suffix);
531
0
    }
532
    std::string GetFrameworkPath() const
533
0
    {
534
0
      return this->Directory.empty()
535
0
        ? cmStrCat(this->Name, ".framework"_s)
536
0
        : cmStrCat(this->Directory, '/', this->Name, ".framework"_s);
537
0
    }
538
    std::string GetFullPath() const
539
0
    {
540
0
      return this->Directory.empty()
541
0
        ? this->GetFullName()
542
0
        : cmStrCat(this->Directory, '/', this->GetFullName());
543
0
    }
544
    std::string GetVersionedPath() const
545
0
    {
546
0
      return this->Directory.empty()
547
0
        ? this->GetVersionedName()
548
0
        : cmStrCat(this->Directory, '/', this->GetVersionedName());
549
0
    }
550
551
    std::string const Directory;
552
    std::string const Version;
553
    std::string const Name;
554
    std::string const Suffix;
555
  };
556
  enum class FrameworkFormat
557
  {
558
    Strict,
559
    Relaxed,
560
    Extended
561
  };
562
  cm::optional<FrameworkDescriptor> SplitFrameworkPath(
563
    std::string const& path,
564
    FrameworkFormat format = FrameworkFormat::Relaxed) const;
565
566
  cmMakefile* FindMakefile(std::string const& start_dir) const;
567
  cmLocalGenerator* FindLocalGenerator(cmDirectoryId const& id) const;
568
569
  /** Append the subdirectory for the given configuration.  If anything is
570
      appended the given prefix and suffix will be appended around it, which
571
      is useful for leading or trailing slashes.  */
572
  virtual void AppendDirectoryForConfig(std::string const& prefix,
573
                                        std::string const& config,
574
                                        std::string const& suffix,
575
                                        std::string& dir);
576
577
  /** Get the content of a directory.  Directory listings are cached
578
      and re-loaded from disk only when modified.  During the generation
579
      step the content will include the target files to be built even if
580
      they do not yet exist.  */
581
  std::set<std::string> const& GetDirectoryContent(std::string const& dir,
582
                                                   bool needDisk = true);
583
584
  /** Check whether a file exists for the purpose of resolving the
585
      location of a source file.  Files found to exist are remembered until
586
      the next configure, or until cmake::InvalidateFileSystemCaches,
587
      because the same source file is typically looked up many times.
588
      Missing files are always checked again so that files created later
589
      are still found.  */
590
  bool SourceFileExists(std::string const& path);
591
0
  void ClearSourceFileExistsCache() { this->ExistingSourceFiles.clear(); }
592
593
  void IndexTarget(cmTarget* t);
594
  void IndexGeneratorTarget(cmGeneratorTarget* gt);
595
596
  // Index the target using a name that is unique to that target
597
  // even if other targets have the same name.
598
  std::string IndexGeneratorTargetUniquely(cmGeneratorTarget const* gt);
599
600
  static bool IsReservedTarget(std::string const& name);
601
602
0
  virtual char const* GetAllTargetName() const { return "ALL_BUILD"; }
603
0
  virtual char const* GetInstallTargetName() const { return "INSTALL"; }
604
0
  virtual char const* GetInstallLocalTargetName() const { return nullptr; }
605
0
  virtual char const* GetInstallStripTargetName() const { return nullptr; }
606
0
  virtual char const* GetPreinstallTargetName() const { return nullptr; }
607
0
  virtual char const* GetTestTargetName() const { return "RUN_TESTS"; }
608
0
  virtual char const* GetPackageTargetName() const { return "PACKAGE"; }
609
0
  virtual char const* GetPackageSourceTargetName() const { return nullptr; }
610
0
  virtual char const* GetEditCacheTargetName() const { return nullptr; }
611
0
  virtual char const* GetRebuildCacheTargetName() const { return nullptr; }
612
0
  virtual char const* GetCleanTargetName() const { return nullptr; }
613
614
  void IndexRule(cmRule* rule);
615
  void IndexGeneratorRule(cmGeneratorRule* gt);
616
617
  // Lookup edit_cache target command preferred by this generator.
618
0
  virtual std::string GetEditCacheCommand() const { return ""; }
619
620
  // Default config to use for cmake --build
621
0
  virtual std::string GetDefaultBuildConfig() const { return "Debug"; }
622
623
  virtual cmValue GetDebuggerWorkingDirectory(cmGeneratorTarget* gt) const;
624
625
  // Class to track a set of dependencies.
626
  using TargetDependSet = cmTargetDependSet;
627
628
  // what targets does the specified target depend on directly
629
  // via a target_link_libraries or add_dependencies
630
  TargetDependSet const& GetTargetDirectDepends(
631
    cmGeneratorTarget const* target) const;
632
633
  // Return true if target 'l' occurs before 'r' in a global ordering
634
  // of targets that respects inter-target dependencies.
635
  bool TargetOrderIndexLess(cmGeneratorTarget const* l,
636
                            cmGeneratorTarget const* r) const;
637
638
  std::map<std::string, std::vector<cmLocalGenerator*>> const& GetProjectMap()
639
    const
640
0
  {
641
0
    return this->ProjectMap;
642
0
  }
643
644
  // track files replaced during a Generate
645
  void FileReplacedDuringGenerate(std::string const& filename);
646
  void GetFilesReplacedDuringGenerate(std::vector<std::string>& filenames);
647
648
  void AddRuleHash(std::vector<std::string> const& outputs,
649
                   std::string const& content);
650
651
  /** Return whether the given binary directory is unused.  */
652
  bool BinaryDirectoryIsNew(std::string const& dir)
653
0
  {
654
0
    return this->BinaryDirectories.insert(dir).second;
655
0
  }
656
657
  /** Return true if the generated build tree may contain multiple builds.
658
      i.e. "Can I build Debug and Release in the same tree?" */
659
138k
  virtual bool IsMultiConfig() const { return false; }
660
661
87.2k
  virtual bool IsXcode() const { return false; }
662
663
0
  virtual bool IsVisualStudio() const { return false; }
664
665
0
  virtual bool IsVisualStudioAtLeast10() const { return false; }
666
667
0
  virtual bool IsNinja() const { return false; }
668
669
0
  virtual bool IsFastbuild() const { return false; }
670
671
  /** Return true if we know the exact location of object files for the given
672
     cmTarget. If false, store the reason in the given string. This is
673
     meaningful only after EnableLanguage has been called.  */
674
  virtual bool HasKnownObjectFileLocation(cmTarget const&, std::string*) const
675
13
  {
676
13
    return true;
677
13
  }
678
679
  virtual bool UseFolderProperty() const;
680
681
0
  virtual bool IsIPOSupported() const { return false; }
682
683
  /** Return whether the generator can import external visual studio project
684
      using INCLUDE_EXTERNAL_MSPROJECT */
685
0
  virtual bool IsIncludeExternalMSProjectSupported() const { return false; }
686
687
  /** Return whether the generator should use EFFECTIVE_PLATFORM_NAME. This is
688
      relevant for mixed macOS and iOS builds. */
689
944
  virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; }
690
691
  /** Return whether the "Resources" folder prefix should be stripped from
692
      MacFolder. */
693
  virtual bool ShouldStripResourcePath(cmMakefile*) const;
694
695
0
  virtual bool SupportsCustomCommandDepfile() const { return false; }
696
  virtual cm::optional<cmDepfileFormat> DepfileFormat() const
697
0
  {
698
0
    return cm::nullopt;
699
0
  }
700
701
0
  virtual bool SupportsLinkerDependencyFile() const { return false; }
702
703
  /** Generate an <output>.rule file path for a given command output.  */
704
  virtual std::string GenerateRuleFile(std::string const& output) const;
705
706
0
  virtual bool SupportsDefaultBuildType() const { return false; }
707
553
  virtual bool SupportsCrossConfigs() const { return false; }
708
0
  virtual bool SupportsDefaultConfigs() const { return false; }
709
710
  virtual std::string ConvertToOutputPath(std::string path) const
711
0
  {
712
0
    return path;
713
0
  }
714
  virtual std::string GetConfigDirectory(std::string const& config) const
715
0
  {
716
0
    if (!this->IsMultiConfig() || config.empty()) {
717
0
      return {};
718
0
    }
719
0
    return cmStrCat('/', config);
720
0
  }
721
722
  static std::string EscapeJSON(std::string const& s);
723
724
  void ProcessEvaluationFiles();
725
726
  std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets()
727
0
  {
728
0
    return this->BuildExportSets;
729
0
  }
730
  /** Scan all build-tree exports in the project and report which of them
731
   *  reference `target`.  Used both by cmExportBuildFileGenerator (to resolve
732
   *  out-of-export link references) and by cmSbomBuilder (to record which
733
   *  export sets a target appears in for SBOM dependency tracking).  */
734
  cmExportFileGenerator::ExportInfo FindBuildExportInfo(
735
    cmGeneratorTarget const* target) const;
736
737
  /** Same as FindBuildExportInfo, but searches install-tree export sets
738
   *  (those registered via install(EXPORT ...)). */
739
  cmExportFileGenerator::ExportInfo FindInstallExportInfo(
740
    cmGeneratorTarget const* target) const;
741
742
  /** Scan all build-tree SBOMs and report which of them cover `target`. */
743
  cmSbomBuilder::SbomInfo FindBuildSbomInfo(
744
    cmGeneratorTarget const* target) const;
745
746
  /** Same as FindBuildSbomInfo, but searches install-tree SBOMs. */
747
  cmSbomBuilder::SbomInfo FindInstallSbomInfo(
748
    cmGeneratorTarget const* target) const;
749
  void AddBuildExportSet(cmExportBuildFileGenerator* gen);
750
  void AddBuildExportExportSet(cmExportBuildFileGenerator* gen);
751
  void AddBuildSbomGenerator(cmBuildSbomGenerator* gen);
752
  std::vector<cmBuildSbomGenerator*> const& GetBuildSbomGenerators() const
753
0
  {
754
0
    return this->BuildSbomGenerators;
755
0
  }
756
757
  // Project-wide registry of install(SBOM) generators.
758
  void AddInstallSbomGenerator(cmInstallSbomGenerator const* gen);
759
  std::vector<cmInstallSbomGenerator const*> const& GetInstallSbomGenerators()
760
    const
761
0
  {
762
0
    return this->InstallSbomGenerators;
763
0
  }
764
765
  bool IsExportedTargetsFile(std::string const& filename) const;
766
767
  /** True if any registered cmBuildSbomGenerator already targets this
768
   *  output file path.  Used to diagnose duplicate `export(SBOM ...)`
769
   *  calls that would otherwise silently clobber each other's output. */
770
  bool IsBuildSbomFile(std::string const& filepath) const;
771
772
  /** True if any registered cmInstallSbomGenerator already targets this
773
   *  install file path (DESTINATION + filename).  Used to diagnose
774
   *  duplicate `install(SBOM ...)` calls that would otherwise silently
775
   *  clobber each other at install time. */
776
  bool IsInstallSbomFile(std::string const& filepath) const;
777
778
  cmExportBuildFileGenerator* GetExportedTargetsFile(
779
    std::string const& filename) const;
780
  void AddCMP0068WarnTarget(std::string const& target);
781
  void AddCMP0224WarnTest(std::string const& test);
782
783
  virtual bool SupportsShortObjectNames() const;
784
  bool UseShortObjectNames(
785
    cmStateEnums::IntermediateDirKind kind =
786
      cmStateEnums::IntermediateDirKind::ObjectFiles) const;
787
  virtual std::string GetShortBinaryOutputDir() const;
788
  std::string ComputeTargetShortName(std::string const& bindir,
789
                                     std::string const& targetName) const;
790
  struct TargetDirectoryRegistration
791
  {
792
0
    TargetDirectoryRegistration() = default;
793
    TargetDirectoryRegistration(cmGeneratorTarget const* t, bool w)
794
0
      : CollidesWith(t)
795
0
      , Warned(w)
796
0
    {
797
0
    }
798
799
    cmGeneratorTarget const* CollidesWith = nullptr;
800
    bool Warned = false;
801
  };
802
  TargetDirectoryRegistration& RegisterTargetDirectory(
803
    cmGeneratorTarget const* tgt, std::string const& targetDir) const;
804
805
  virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
806
807
  bool GenerateCPackPropertiesFile();
808
809
  void SetFilenameTargetDepends(
810
    cmSourceFile* sf, std::set<cmGeneratorTarget const*> const& tgts);
811
  std::set<cmGeneratorTarget const*> const& GetFilenameTargetDepends(
812
    cmSourceFile* sf) const;
813
814
#if !defined(CMAKE_BOOTSTRAP)
815
23.7k
  cmFileLockPool& GetFileLockPool() { return this->FileLockPool; }
816
#endif
817
818
  std::string MakeSilentFlag;
819
820
  size_t RecursionDepth = 0;
821
822
  virtual void GetQtAutoGenConfigs(std::vector<std::string>& configs) const
823
0
  {
824
0
    configs.emplace_back("$<CONFIG>");
825
0
  }
826
827
  std::string const& GetRealPath(std::string const& dir);
828
829
  std::string NewDeferId();
830
831
  cmInstallRuntimeDependencySet* CreateAnonymousRuntimeDependencySet();
832
833
  cmInstallRuntimeDependencySet* GetNamedRuntimeDependencySet(
834
    std::string const& name);
835
836
  enum class StripCommandStyle
837
  {
838
    Default,
839
    Apple,
840
  };
841
  StripCommandStyle GetStripCommandStyle(std::string const& strip);
842
843
  std::string GetEncodedLiteral(std::string const& lit);
844
0
  virtual std::string& EncodeLiteral(std::string& lit) { return lit; }
845
846
  bool CheckCMP0171() const;
847
848
  void AddInstallScript(std::string const& file);
849
  void AddTestFile(std::string const& file);
850
  void AddCMakeFilesToRebuild(std::vector<std::string>& files) const;
851
852
  virtual std::set<std::string> const& GetDefaultConfigs() const
853
0
  {
854
0
    static std::set<std::string> configs;
855
0
    return configs;
856
0
  }
857
858
  bool ShouldWarnCMP0210(std::string const& lang);
859
860
  bool ShouldWarnExperimental(cm::string_view featureName,
861
                              cm::string_view featureUuid);
862
863
  cm::optional<cmXcFrameworkPlist> GetXcFrameworkPListContent(
864
    std::string const& path) const;
865
  void SetXcFrameworkPListContent(std::string const& path,
866
                                  cmXcFrameworkPlist const& content);
867
868
protected:
869
  virtual std::string GetTestBuildDependencyPath(
870
    cmGeneratorTarget const* target, std::string const& config) const;
871
872
  /** Get all targets produced under the given root, plus the transitive
873
      closure of targets on which they depend, possibly from other dirs.  */
874
  TargetDependSet GetTargetsForProject(
875
    cmLocalGenerator const* root,
876
    std::vector<cmLocalGenerator*> const& generators) const;
877
878
  bool IsRootOnlyTarget(cmGeneratorTarget* target) const;
879
  void AddTargetDepends(cmGeneratorTarget const* target,
880
                        TargetDependSet& projectTargets) const;
881
  void SetLanguageEnabledFlag(std::string const& l, cmMakefile* mf);
882
  void SetLanguageEnabledMaps(std::string const& l, cmMakefile* mf);
883
  void FillExtensionToLanguageMap(std::string const& l, cmMakefile* mf);
884
  virtual bool CheckLanguages(std::vector<std::string> const& languages,
885
                              cmMakefile* mf) const;
886
  virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
887
                                   cmValue envVar) const;
888
889
  virtual bool ComputeTargetDepends();
890
891
#if !defined(CMAKE_BOOTSTRAP)
892
  void WriteJsonContent(std::string const& fname,
893
                        Json::Value const& value) const;
894
  void WriteInstallJson() const;
895
#endif
896
897
  virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
898
899
  bool ApplyCXXStdTarget();
900
  void WriteCxxImportErrorModules();
901
  bool DiscoverSyntheticTargets();
902
903
  bool AddHeaderSetVerification();
904
905
  void CreateFileGenerateOutputs();
906
  bool AddAutomaticSources();
907
908
  std::string SelectMakeProgram(std::string const& makeProgram,
909
                                std::string const& makeDefault = "") const;
910
911
  // Fill the ProjectMap, this must be called after LocalGenerators
912
  // has been populated.
913
  void FillProjectMap();
914
  void CheckTargetProperties();
915
  bool IsExcluded(cmStateSnapshot const& root,
916
                  cmStateSnapshot const& snp) const;
917
  bool IsExcluded(cmLocalGenerator const* root,
918
                  cmLocalGenerator const* gen) const;
919
  bool IsExcluded(cmLocalGenerator const* root,
920
                  cmGeneratorTarget const* target) const;
921
0
  virtual void InitializeProgressMarks() {}
922
923
  struct GlobalTargetInfo
924
  {
925
    std::string Name;
926
    std::string Message;
927
    cmCustomCommandLines CommandLines;
928
    std::vector<std::string> Depends;
929
    std::string WorkingDir;
930
    bool UsesTerminal = false;
931
    cmTarget::PerConfig PerConfig = cmTarget::PerConfig::Yes;
932
    bool StdPipesUTF8 = false;
933
    std::string Role;
934
  };
935
936
  void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets);
937
938
  void AddGlobalTarget_Package(std::vector<GlobalTargetInfo>& targets);
939
  void AddGlobalTarget_PackageSource(std::vector<GlobalTargetInfo>& targets);
940
  void AddGlobalTarget_Test(std::vector<GlobalTargetInfo>& targets);
941
  void AddGlobalTarget_EditCache(std::vector<GlobalTargetInfo>& targets) const;
942
  void AddGlobalTarget_RebuildCache(
943
    std::vector<GlobalTargetInfo>& targets) const;
944
  void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets);
945
  void CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf);
946
947
  void ReserveGlobalTargetCodegen();
948
949
  // Execute user's callbacks and produce custom commands for file sets
950
  // attached to a custom rule
951
  void ConfigureRules();
952
953
  std::string FindMakeProgramFile;
954
  std::string ConfiguredFilesPath;
955
  cmake* CMakeInstance;
956
  std::vector<std::unique_ptr<cmMakefile>> Makefiles;
957
  LocalGeneratorVector LocalGenerators;
958
959
#ifndef CMAKE_BOOTSTRAP
960
  std::unique_ptr<cmQtAutoGenGlobalInitializer> QtAutoGen;
961
#endif
962
963
  cmMakefile* CurrentConfigureMakefile;
964
  // map from project name to vector of local generators in that project
965
  std::map<std::string, std::vector<cmLocalGenerator*>> ProjectMap;
966
967
  // Set of named installation components requested by the project.
968
  std::set<std::string> InstallComponents;
969
  // Sets of named target exports
970
  cmExportSetMap ExportSets;
971
  std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets;
972
  std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets;
973
  std::vector<cmBuildSbomGenerator*> BuildSbomGenerators;
974
  std::vector<cmInstallSbomGenerator const*> InstallSbomGenerators;
975
976
  std::map<std::string, std::string> AliasTargets;
977
978
  cmTarget* FindTargetImpl(std::string const& name,
979
                           cm::TargetDomainSet domains) const;
980
981
  cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
982
983
  std::string GetPredefinedTargetsFolder() const;
984
985
private:
986
  using TargetMap = std::unordered_map<std::string, cmTarget*>;
987
  using GeneratorTargetMap =
988
    std::unordered_map<std::string, cmGeneratorTarget*>;
989
  using RuleMap = std::unordered_map<std::string, cmRule*>;
990
  using GeneratorRuleMap = std::unordered_map<std::string, cmGeneratorRule*>;
991
  using MakefileMap = std::unordered_map<std::string, cmMakefile*>;
992
  using LocalGeneratorMap = std::unordered_map<std::string, cmLocalGenerator*>;
993
  using TargetDirectoryRegistrationMap =
994
    std::map<cmGeneratorTarget const*, TargetDirectoryRegistration>;
995
  using TargetDirectoryMap =
996
    std::unordered_map<std::string, std::set<cmGeneratorTarget const*>>;
997
  // Map efficiently from target name to cmTarget instance.
998
  // Do not use this structure for looping over all targets.
999
  // It contains both normal and globally visible imported targets.
1000
  TargetMap TargetSearchIndex;
1001
  GeneratorTargetMap GeneratorTargetSearchIndex;
1002
1003
  // Map from target to a directory registration.
1004
  mutable TargetDirectoryRegistrationMap TargetDirectoryRegistrations;
1005
  // Map from target directories to targets using it.
1006
  mutable TargetDirectoryMap TargetDirectories;
1007
1008
  // Map efficiently from rule name to cmRule instance.
1009
  // Do not use this structure for looping over all rules.
1010
  // It may not contain all of them.
1011
  RuleMap RuleSearchIndex;
1012
  GeneratorRuleMap GeneratorRuleSearchIndex;
1013
1014
  // Map efficiently from source directory path to cmMakefile instance.
1015
  // Do not use this structure for looping over all directories.
1016
  // It may not contain all of them (see note in IndexMakefile method).
1017
  MakefileMap MakefileSearchIndex;
1018
1019
  // Map efficiently from source directory path to cmLocalGenerator instance.
1020
  // Do not use this structure for looping over all directories.
1021
  // Its order is not deterministic.
1022
  LocalGeneratorMap LocalGeneratorSearchIndex;
1023
1024
  void ComputeTargetOrder();
1025
  void ComputeTargetOrder(cmGeneratorTarget const* gt, size_t& index);
1026
  std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex;
1027
1028
  cmMakefile* TryCompileOuterMakefile;
1029
  std::map<std::string, bool> IgnoreExtensions;
1030
  std::set<std::string> LanguagesReadyForTryCompile;
1031
  std::set<std::string> LanguagesInProgress;
1032
  std::map<std::string, std::string> OutputExtensions;
1033
  std::map<std::string, std::string> LanguageToOutputExtension;
1034
  std::map<std::string, std::string> RustEmitToOutputExtension;
1035
#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
1036
  std::map<std::string, std::string, std::less<void>> ExtensionToLanguage;
1037
#else
1038
  std::map<std::string, std::string> ExtensionToLanguage;
1039
#endif
1040
  std::map<std::string, int> LanguageToLinkerPreference;
1041
1042
#if !defined(CMAKE_BOOTSTRAP)
1043
  std::unique_ptr<Json::StreamWriter> JsonWriter;
1044
#endif
1045
1046
#ifdef __APPLE__
1047
  std::map<std::string, StripCommandStyle> StripCommandStyleMap;
1048
#endif
1049
1050
  // Deferral id generation.
1051
  size_t NextDeferId = 0;
1052
1053
  // Record hashes for rules and outputs.
1054
  struct RuleHash
1055
  {
1056
    char Data[32];
1057
  };
1058
  std::map<std::string, RuleHash> RuleHashes;
1059
  void CheckRuleHashes();
1060
  void CheckRuleHashes(std::string const& pfile, std::string const& home);
1061
  void WriteRuleHashes(std::string const& pfile);
1062
1063
  void WriteSummary();
1064
  void WriteSummary(cmGeneratorTarget* target);
1065
  void FinalizeTargetConfiguration();
1066
1067
  virtual void ForceLinkerLanguages();
1068
1069
  void CheckTargetLinkLibraries() const;
1070
  bool CheckTargetsForMissingSources() const;
1071
  bool CheckTargetsForType() const;
1072
  void MarkTargetsForPchReuse() const;
1073
1074
  void CreateLocalGenerators();
1075
1076
  void CheckCompilerIdCompatibility(cmMakefile* mf,
1077
                                    std::string const& lang) const;
1078
1079
  void ComputeBuildFileGenerators();
1080
1081
  std::unique_ptr<cmExternalMakefileProjectGenerator> ExtraGenerator;
1082
1083
  // track files replaced during a Generate
1084
  std::vector<std::string> FilesReplacedDuringGenerate;
1085
1086
  // Store computed inter-target dependencies.
1087
  using TargetDependMap = std::map<cmGeneratorTarget const*, TargetDependSet>;
1088
  TargetDependMap TargetDependencies;
1089
1090
  // Map from a custom-command primary output (collapsed full path) to the
1091
  // build-system target(s) that produce it.  Built lazily on first use and
1092
  // cleared with the other generator members.
1093
  std::map<std::string, std::vector<cmGeneratorTarget*>> OutputOwnerIndex;
1094
  bool OutputOwnerIndexComputed = false;
1095
  void ComputeOutputOwnerIndex();
1096
1097
  // Map from a configuration to a map from a linked artifact (collapsed full
1098
  // path) to the build-system target(s) that produce it.  Built lazily for
1099
  // each configuration and cleared with the other generator members.
1100
  std::map<std::string, std::map<std::string, std::vector<cmGeneratorTarget*>>>
1101
    ArtifactOwnerIndex;
1102
1103
  // Every output and byproduct path recorded by any local generator, keyed
1104
  // as for cmLocalGenerator::GetSourcesWithOutput.  Built lazily on first use
1105
  // and invalidated whenever a local generator records a new path.
1106
  std::unordered_set<std::string> GeneratedByBuildIndex;
1107
  bool GeneratedByBuildIndexComputed = false;
1108
1109
  // The build dependencies of each install rule for each configuration,
1110
  // computed once and shared by CheckInstallPrepTargets and
1111
  // GetInstallPrepTargets.
1112
  std::map<std::pair<cmInstallGenerator const*, std::string>,
1113
           std::vector<cmInstallGenerator::BuildDependency>>
1114
    InstallPrepDependencies;
1115
  std::vector<cmInstallGenerator::BuildDependency> const&
1116
  GetInstallPrepDependencies(cmInstallGenerator const* installer,
1117
                             std::string const& config);
1118
1119
  friend class cmake;
1120
  void CreateGeneratorTargets(
1121
    TargetTypes targetTypes, cmMakefile* mf, cmLocalGenerator* lg,
1122
    std::map<cmTarget*, cmGeneratorTarget*> const& importedMap);
1123
  void CreateGeneratorTargets(TargetTypes targetTypes);
1124
1125
  void ClearGeneratorMembers();
1126
1127
  bool CheckReservedTargetName(std::string const& targetName,
1128
                               std::string const& reason) const;
1129
  bool CheckReservedTargetNamePrefix(std::string const& targetPrefix,
1130
                                     std::string const& reason) const;
1131
1132
  void IndexMakefile(cmMakefile* mf);
1133
  void IndexLocalGenerator(cmLocalGenerator* lg);
1134
1135
0
  virtual char const* GetBuildIgnoreErrorsFlag() const { return nullptr; }
1136
1137
  bool UnsupportedVariableIsDefined(std::string const& name,
1138
                                    bool supported) const;
1139
1140
  // Cache directory content and target files to be built.
1141
  struct DirectoryContent
1142
  {
1143
    long LastDiskTime = -1;
1144
    std::set<std::string> All;
1145
    std::set<std::string> Generated;
1146
  };
1147
  std::map<std::string, DirectoryContent> DirectoryContentMap;
1148
1149
  // Files known to exist, see SourceFileExists.
1150
  std::unordered_set<std::string> ExistingSourceFiles;
1151
1152
  // Cache parsed PList files
1153
  std::map<std::string, cmXcFrameworkPlist> XcFrameworkPListContentMap;
1154
1155
  // Set of binary directories on disk.
1156
  std::set<std::string> BinaryDirectories;
1157
1158
  // track targets to issue CMP0068 warning for.
1159
  std::set<std::string> CMP0068WarnTargets;
1160
1161
  // track tests to issue CMP0224 warning for.
1162
  std::set<std::string> CMP0224WarnTests;
1163
1164
  std::unordered_set<std::string> WarnedCMP0210Languages;
1165
1166
  std::unordered_set<std::string> WarnedExperimental;
1167
1168
  mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>>
1169
    FilenameTargetDepends;
1170
1171
  std::map<std::string, std::string> RealPaths;
1172
1173
  std::unordered_set<std::string> GeneratedFiles;
1174
1175
  std::vector<std::unique_ptr<cmInstallRuntimeDependencySet>>
1176
    RuntimeDependencySets;
1177
  std::map<std::string, cmInstallRuntimeDependencySet*>
1178
    RuntimeDependencySetsByName;
1179
1180
  std::vector<std::string> InstallScripts;
1181
  std::vector<std::string> TestFiles;
1182
1183
#if !defined(CMAKE_BOOTSTRAP)
1184
  // Pool of file locks
1185
  cmFileLockPool FileLockPool;
1186
#endif
1187
1188
  using PerLanguageModuleDatabases =
1189
    std::map<std::string, std::vector<std::string>>;
1190
  using PerConfigModuleDatabases =
1191
    std::map<std::string, PerLanguageModuleDatabases>;
1192
  PerConfigModuleDatabases PerConfigModuleDbs;
1193
  PerLanguageModuleDatabases PerLanguageModuleDbs;
1194
1195
  enum class IntermediateDirStrategy
1196
  {
1197
    Full,
1198
    Short,
1199
  };
1200
  IntermediateDirStrategy IntDirStrategy = IntermediateDirStrategy::Full;
1201
  IntermediateDirStrategy QtAutogenIntDirStrategy =
1202
    IntermediateDirStrategy::Full;
1203
1204
protected:
1205
  float FirstTimeProgress;
1206
  bool NeedSymbolicMark;
1207
  bool UseLinkScript;
1208
  bool ForceUnixPaths;
1209
  bool ToolSupportsColor;
1210
  bool InstallTargetEnabled;
1211
  bool AllowGlobalTargetCodegen;
1212
};