Coverage Report

Created: 2026-07-14 07:09

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