Coverage Report

Created: 2026-06-15 07:03

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