Coverage Report

Created: 2026-04-29 07:01

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 "cmExportSet.h"
28
#include "cmLocalGenerator.h"
29
#include "cmStateSnapshot.h"
30
#include "cmStateTypes.h"
31
#include "cmStringAlgorithms.h"
32
#include "cmSystemTools.h"
33
#include "cmTarget.h"
34
#include "cmTargetDepend.h"
35
#include "cmValue.h"
36
#include "cmXcFramework.h"
37
38
#if !defined(CMAKE_BOOTSTRAP)
39
#  include <cm3p/json/value.h>
40
41
#  include "cmFileLockPool.h"
42
#endif
43
44
0
#define CMAKE_DIRECTORY_ID_SEP "::@"
45
46
enum class cmDepfileFormat;
47
enum class codecvt_Encoding;
48
49
class cmBuildArgs;
50
class cmDirectoryId;
51
class cmExportBuildFileGenerator;
52
class cmExternalMakefileProjectGenerator;
53
class cmGeneratorTarget;
54
class cmInstallRuntimeDependencySet;
55
class cmLinkLineComputer;
56
class cmMakefile;
57
class cmOutputConverter;
58
class cmQtAutoGenGlobalInitializer;
59
class cmSourceFile;
60
class cmState;
61
class cmStateDirectory;
62
class cmake;
63
64
namespace detail {
65
inline void AppendStrs(std::vector<std::string>&)
66
0
{
67
0
}
68
template <typename T, typename... Ts>
69
inline void AppendStrs(std::vector<std::string>& command, T&& s, Ts&&... ts)
70
0
{
71
0
  command.emplace_back(std::forward<T>(s));
72
0
  AppendStrs(command, std::forward<Ts>(ts)...);
73
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])
74
75
struct GeneratedMakeCommand
76
{
77
  // Add each argument as a separate element to the vector
78
  template <typename... T>
79
  void Add(T&&... args)
80
0
  {
81
    // iterate the args and append each one
82
0
    AppendStrs(this->PrimaryCommand, std::forward<T>(args)...);
83
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])
84
85
  // Add each value in the iterators as a separate element to the vector
86
  void Add(std::vector<std::string>::const_iterator start,
87
           std::vector<std::string>::const_iterator end)
88
0
  {
89
0
    cm::append(this->PrimaryCommand, start, end);
90
0
  }
91
92
0
  std::string Printable() const { return cmJoin(this->PrimaryCommand, " "); }
93
  std::string QuotedPrintable() const;
94
95
  std::vector<std::string> PrimaryCommand;
96
  bool RequiresOutputForward = false;
97
};
98
}
99
namespace Json {
100
class StreamWriter;
101
}
102
103
/** \class cmGlobalGenerator
104
 * \brief Responsible for overseeing the generation process for the entire tree
105
 *
106
 * Subclasses of this class generate makefiles for various
107
 * platforms.
108
 */
109
class cmGlobalGenerator
110
{
111
public:
112
  using LocalGeneratorVector = std::vector<std::unique_ptr<cmLocalGenerator>>;
113
  enum class BuildTryCompile
114
  {
115
    No,
116
    Yes,
117
  };
118
119
  //! Free any memory allocated with the GlobalGenerator
120
  cmGlobalGenerator(cmake* cm);
121
  virtual ~cmGlobalGenerator();
122
123
  virtual std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
124
    cmMakefile* mf);
125
126
  //! Get the name for this generator
127
0
  virtual std::string GetName() const { return "Generic"; }
128
129
  /** Check whether the given name matches the current generator.  */
130
  virtual bool MatchesGeneratorName(std::string const& name) const
131
0
  {
132
0
    return this->GetName() == name;
133
0
  }
134
135
  /** Get encoding used by generator for makefile files */
136
  virtual codecvt_Encoding GetMakefileEncoding() const;
137
138
#if !defined(CMAKE_BOOTSTRAP)
139
  /** Get a JSON object describing the generator.  */
140
  virtual Json::Value GetJson() const;
141
#endif
142
143
  /** Tell the generator about the target system.  */
144
0
  virtual bool SetSystemName(std::string const&, cmMakefile*) { return true; }
145
146
  /** Set the generator-specific instance.  Returns true if supported.  */
147
  virtual bool SetGeneratorInstance(std::string const& i, cmMakefile* mf);
148
149
  /** Set the generator-specific platform name.  Returns true if platform
150
      is supported and false otherwise.  */
151
  virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
152
153
  /** Set the generator-specific toolset name.  Returns true if toolset
154
      is supported and false otherwise.  */
155
  virtual bool SetGeneratorToolset(std::string const& ts, bool build,
156
                                   cmMakefile* mf);
157
158
  /** Read any other cache entries needed for cmake --build. */
159
  virtual bool ReadCacheEntriesForBuild(cmState const& /*state*/)
160
0
  {
161
0
    return true;
162
0
  }
163
164
  /**
165
   * Create LocalGenerators and process the CMakeLists files. This does not
166
   * actually produce any makefiles, DSPs, etc.
167
   */
168
  virtual void Configure();
169
170
0
  virtual bool InspectConfigTypeVariables() { return true; }
171
172
  enum class CxxModuleSupportQuery
173
  {
174
    // Support is expected at the call site.
175
    Expected,
176
    // The call site is querying for support and handles problems by itself.
177
    Inspect,
178
  };
179
  virtual bool CheckCxxModuleSupport(CxxModuleSupportQuery /*query*/)
180
0
  {
181
0
    return false;
182
0
  }
183
184
0
  virtual bool SupportsCustomObjectNames() const { return true; }
185
186
0
  virtual bool SupportsBuildDatabase() const { return false; }
187
  bool AddBuildDatabaseTargets();
188
  void AddBuildDatabaseFile(std::string const& lang, std::string const& config,
189
                            std::string const& path);
190
191
0
  virtual bool IsGNUMakeJobServerAware() const { return false; }
192
193
  bool Compute();
194
0
  virtual void AddExtraIDETargets() {}
195
196
  enum TargetTypes
197
  {
198
    AllTargets,
199
    ImportedOnly
200
  };
201
202
  void CreateImportedGenerationObjects(
203
    cmMakefile* mf, std::vector<std::string> const& targets,
204
    std::vector<cmGeneratorTarget const*>& exports);
205
  void CreateGenerationObjects(TargetTypes targetTypes = AllTargets);
206
207
  /**
208
   * Generate the all required files for building this project/tree. This
209
   * basically creates a series of LocalGenerators for each directory and
210
   * requests that they Generate.
211
   */
212
  virtual void Generate();
213
214
  virtual std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
215
    cmOutputConverter* outputConverter,
216
    cmStateDirectory const& stateDir) const;
217
218
  std::unique_ptr<cmLinkLineComputer> CreateMSVC60LinkLineComputer(
219
    cmOutputConverter* outputConverter,
220
    cmStateDirectory const& stateDir) const;
221
222
  /**
223
   * Set/Get and Clear the enabled languages.
224
   */
225
  void SetLanguageEnabled(std::string const&, cmMakefile* mf);
226
  bool GetLanguageEnabled(std::string const&) const;
227
  void ClearEnabledLanguages();
228
  void GetEnabledLanguages(std::vector<std::string>& lang) const;
229
  /**
230
   * Try to determine system information such as shared library
231
   * extension, pthreads, byte order etc.
232
   */
233
  virtual void EnableLanguage(std::vector<std::string> const& languages,
234
                              cmMakefile*, bool optional);
235
236
  /**
237
   * Resolve the CMAKE_<lang>_COMPILER setting for the given language.
238
   * Intended to be called from EnableLanguage.
239
   */
240
  void ResolveLanguageCompiler(std::string const& lang, cmMakefile* mf,
241
                               bool optional) const;
242
243
  /**
244
   * Try to determine system information, get it from another generator
245
   */
246
  void EnableLanguagesFromGenerator(cmGlobalGenerator* gen, cmMakefile* mf);
247
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
  void AddBuildExportSet(cmExportBuildFileGenerator* gen);
639
  void AddBuildExportExportSet(cmExportBuildFileGenerator* gen);
640
  bool IsExportedTargetsFile(std::string const& filename) const;
641
  cmExportBuildFileGenerator* GetExportedTargetsFile(
642
    std::string const& filename) const;
643
  void AddCMP0068WarnTarget(std::string const& target);
644
645
  virtual bool SupportsShortObjectNames() const;
646
  bool UseShortObjectNames(
647
    cmStateEnums::IntermediateDirKind kind =
648
      cmStateEnums::IntermediateDirKind::ObjectFiles) const;
649
  virtual std::string GetShortBinaryOutputDir() const;
650
  std::string ComputeTargetShortName(std::string const& bindir,
651
                                     std::string const& targetName) const;
652
  struct TargetDirectoryRegistration
653
  {
654
0
    TargetDirectoryRegistration() = default;
655
    TargetDirectoryRegistration(cmGeneratorTarget const* t, bool w)
656
0
      : CollidesWith(t)
657
0
      , Warned(w)
658
0
    {
659
0
    }
660
661
    cmGeneratorTarget const* CollidesWith = nullptr;
662
    bool Warned = false;
663
  };
664
  TargetDirectoryRegistration& RegisterTargetDirectory(
665
    cmGeneratorTarget const* tgt, std::string const& targetDir) const;
666
667
  virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
668
669
  bool GenerateCPackPropertiesFile();
670
671
  void SetFilenameTargetDepends(
672
    cmSourceFile* sf, std::set<cmGeneratorTarget const*> const& tgts);
673
  std::set<cmGeneratorTarget const*> const& GetFilenameTargetDepends(
674
    cmSourceFile* sf) const;
675
676
#if !defined(CMAKE_BOOTSTRAP)
677
0
  cmFileLockPool& GetFileLockPool() { return this->FileLockPool; }
678
#endif
679
680
  std::string MakeSilentFlag;
681
682
  size_t RecursionDepth = 0;
683
684
  virtual void GetQtAutoGenConfigs(std::vector<std::string>& configs) const
685
0
  {
686
0
    configs.emplace_back("$<CONFIG>");
687
0
  }
688
689
  std::string const& GetRealPath(std::string const& dir);
690
691
  std::string NewDeferId();
692
693
  cmInstallRuntimeDependencySet* CreateAnonymousRuntimeDependencySet();
694
695
  cmInstallRuntimeDependencySet* GetNamedRuntimeDependencySet(
696
    std::string const& name);
697
698
  enum class StripCommandStyle
699
  {
700
    Default,
701
    Apple,
702
  };
703
  StripCommandStyle GetStripCommandStyle(std::string const& strip);
704
705
  std::string GetEncodedLiteral(std::string const& lit);
706
0
  virtual std::string& EncodeLiteral(std::string& lit) { return lit; }
707
708
  bool CheckCMP0171() const;
709
710
  void AddInstallScript(std::string const& file);
711
  void AddTestFile(std::string const& file);
712
  void AddCMakeFilesToRebuild(std::vector<std::string>& files) const;
713
714
  virtual std::set<std::string> const& GetDefaultConfigs() const
715
0
  {
716
0
    static std::set<std::string> configs;
717
0
    return configs;
718
0
  }
719
720
  bool ShouldWarnCMP0210(std::string const& lang);
721
722
  bool ShouldWarnExperimental(cm::string_view featureName,
723
                              cm::string_view featureUuid);
724
725
  cm::optional<cmXcFrameworkPlist> GetXcFrameworkPListContent(
726
    std::string const& path) const;
727
  void SetXcFrameworkPListContent(std::string const& path,
728
                                  cmXcFrameworkPlist const& content);
729
730
protected:
731
  /** Get all targets produced under the given root, plus the transitive
732
      closure of targets on which they depend, possibly from other dirs.  */
733
  TargetDependSet GetTargetsForProject(
734
    cmLocalGenerator const* root,
735
    std::vector<cmLocalGenerator*> const& generators) const;
736
737
  bool IsRootOnlyTarget(cmGeneratorTarget* target) const;
738
  void AddTargetDepends(cmGeneratorTarget const* target,
739
                        TargetDependSet& projectTargets) const;
740
  void SetLanguageEnabledFlag(std::string const& l, cmMakefile* mf);
741
  void SetLanguageEnabledMaps(std::string const& l, cmMakefile* mf);
742
  void FillExtensionToLanguageMap(std::string const& l, cmMakefile* mf);
743
  virtual bool CheckLanguages(std::vector<std::string> const& languages,
744
                              cmMakefile* mf) const;
745
  virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
746
                                   cmValue envVar) const;
747
748
  virtual bool ComputeTargetDepends();
749
750
#if !defined(CMAKE_BOOTSTRAP)
751
  void WriteJsonContent(std::string const& fname,
752
                        Json::Value const& value) const;
753
  void WriteInstallJson() const;
754
#endif
755
756
  virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
757
758
  bool ApplyCXXStdTargets();
759
  bool DiscoverSyntheticTargets();
760
761
  bool AddHeaderSetVerification();
762
763
  void CreateFileGenerateOutputs();
764
  bool AddAutomaticSources();
765
766
  std::string SelectMakeProgram(std::string const& makeProgram,
767
                                std::string const& makeDefault = "") const;
768
769
  // Fill the ProjectMap, this must be called after LocalGenerators
770
  // has been populated.
771
  void FillProjectMap();
772
  void CheckTargetProperties();
773
  bool IsExcluded(cmStateSnapshot const& root,
774
                  cmStateSnapshot const& snp) const;
775
  bool IsExcluded(cmLocalGenerator const* root,
776
                  cmLocalGenerator const* gen) const;
777
  bool IsExcluded(cmLocalGenerator const* root,
778
                  cmGeneratorTarget const* target) const;
779
0
  virtual void InitializeProgressMarks() {}
780
781
  struct GlobalTargetInfo
782
  {
783
    std::string Name;
784
    std::string Message;
785
    cmCustomCommandLines CommandLines;
786
    std::vector<std::string> Depends;
787
    std::string WorkingDir;
788
    bool UsesTerminal = false;
789
    cmTarget::PerConfig PerConfig = cmTarget::PerConfig::Yes;
790
    bool StdPipesUTF8 = false;
791
    std::string Role;
792
  };
793
794
  void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets);
795
796
  void AddGlobalTarget_Package(std::vector<GlobalTargetInfo>& targets);
797
  void AddGlobalTarget_PackageSource(std::vector<GlobalTargetInfo>& targets);
798
  void AddGlobalTarget_Test(std::vector<GlobalTargetInfo>& targets);
799
  void AddGlobalTarget_EditCache(std::vector<GlobalTargetInfo>& targets) const;
800
  void AddGlobalTarget_RebuildCache(
801
    std::vector<GlobalTargetInfo>& targets) const;
802
  void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets);
803
  void CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf);
804
805
  void ReserveGlobalTargetCodegen();
806
807
  std::string FindMakeProgramFile;
808
  std::string ConfiguredFilesPath;
809
  cmake* CMakeInstance;
810
  std::vector<std::unique_ptr<cmMakefile>> Makefiles;
811
  LocalGeneratorVector LocalGenerators;
812
813
#ifndef CMAKE_BOOTSTRAP
814
  std::unique_ptr<cmQtAutoGenGlobalInitializer> QtAutoGen;
815
#endif
816
817
  cmMakefile* CurrentConfigureMakefile;
818
  // map from project name to vector of local generators in that project
819
  std::map<std::string, std::vector<cmLocalGenerator*>> ProjectMap;
820
821
  // Set of named installation components requested by the project.
822
  std::set<std::string> InstallComponents;
823
  // Sets of named target exports
824
  cmExportSetMap ExportSets;
825
  std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets;
826
  std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets;
827
828
  std::map<std::string, std::string> AliasTargets;
829
830
  cmTarget* FindTargetImpl(std::string const& name,
831
                           cmStateEnums::TargetDomainSet domains) const;
832
833
  cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
834
835
  std::string GetPredefinedTargetsFolder() const;
836
837
private:
838
  using TargetMap = std::unordered_map<std::string, cmTarget*>;
839
  using GeneratorTargetMap =
840
    std::unordered_map<std::string, cmGeneratorTarget*>;
841
  using MakefileMap = std::unordered_map<std::string, cmMakefile*>;
842
  using LocalGeneratorMap = std::unordered_map<std::string, cmLocalGenerator*>;
843
  using TargetDirectoryRegistrationMap =
844
    std::map<cmGeneratorTarget const*, TargetDirectoryRegistration>;
845
  using TargetDirectoryMap =
846
    std::unordered_map<std::string, std::set<cmGeneratorTarget const*>>;
847
  // Map efficiently from target name to cmTarget instance.
848
  // Do not use this structure for looping over all targets.
849
  // It contains both normal and globally visible imported targets.
850
  TargetMap TargetSearchIndex;
851
  GeneratorTargetMap GeneratorTargetSearchIndex;
852
853
  // Map from target to a directory registration.
854
  mutable TargetDirectoryRegistrationMap TargetDirectoryRegistrations;
855
  // Map from target directories to targets using it.
856
  mutable TargetDirectoryMap TargetDirectories;
857
858
  // Map efficiently from source directory path to cmMakefile instance.
859
  // Do not use this structure for looping over all directories.
860
  // It may not contain all of them (see note in IndexMakefile method).
861
  MakefileMap MakefileSearchIndex;
862
863
  // Map efficiently from source directory path to cmLocalGenerator instance.
864
  // Do not use this structure for looping over all directories.
865
  // Its order is not deterministic.
866
  LocalGeneratorMap LocalGeneratorSearchIndex;
867
868
  void ComputeTargetOrder();
869
  void ComputeTargetOrder(cmGeneratorTarget const* gt, size_t& index);
870
  std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex;
871
872
  cmMakefile* TryCompileOuterMakefile;
873
  // If you add a new map here, make sure it is copied
874
  // in EnableLanguagesFromGenerator
875
  std::map<std::string, bool> IgnoreExtensions;
876
  std::set<std::string> LanguagesReady; // Ready for try_compile
877
  std::set<std::string> LanguagesInProgress;
878
  std::map<std::string, std::string> OutputExtensions;
879
  std::map<std::string, std::string> LanguageToOutputExtension;
880
  std::map<std::string, std::string> RustEmitToOutputExtension;
881
#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
882
  std::map<std::string, std::string, std::less<void>> ExtensionToLanguage;
883
#else
884
  std::map<std::string, std::string> ExtensionToLanguage;
885
#endif
886
  std::map<std::string, int> LanguageToLinkerPreference;
887
888
#if !defined(CMAKE_BOOTSTRAP)
889
  std::unique_ptr<Json::StreamWriter> JsonWriter;
890
#endif
891
892
#ifdef __APPLE__
893
  std::map<std::string, StripCommandStyle> StripCommandStyleMap;
894
#endif
895
896
  // Deferral id generation.
897
  size_t NextDeferId = 0;
898
899
  // Record hashes for rules and outputs.
900
  struct RuleHash
901
  {
902
    char Data[32];
903
  };
904
  std::map<std::string, RuleHash> RuleHashes;
905
  void CheckRuleHashes();
906
  void CheckRuleHashes(std::string const& pfile, std::string const& home);
907
  void WriteRuleHashes(std::string const& pfile);
908
909
  void WriteSummary();
910
  void WriteSummary(cmGeneratorTarget* target);
911
  void FinalizeTargetConfiguration();
912
913
  virtual void ForceLinkerLanguages();
914
915
  void CheckTargetLinkLibraries() const;
916
  bool CheckTargetsForMissingSources() const;
917
  bool CheckTargetsForType() const;
918
  void MarkTargetsForPchReuse() const;
919
920
  void CreateLocalGenerators();
921
922
  void CheckCompilerIdCompatibility(cmMakefile* mf,
923
                                    std::string const& lang) const;
924
925
  void ComputeBuildFileGenerators();
926
927
  std::unique_ptr<cmExternalMakefileProjectGenerator> ExtraGenerator;
928
929
  // track files replaced during a Generate
930
  std::vector<std::string> FilesReplacedDuringGenerate;
931
932
  // Store computed inter-target dependencies.
933
  using TargetDependMap = std::map<cmGeneratorTarget const*, TargetDependSet>;
934
  TargetDependMap TargetDependencies;
935
936
  friend class cmake;
937
  void CreateGeneratorTargets(
938
    TargetTypes targetTypes, cmMakefile* mf, cmLocalGenerator* lg,
939
    std::map<cmTarget*, cmGeneratorTarget*> const& importedMap);
940
  void CreateGeneratorTargets(TargetTypes targetTypes);
941
942
  void ClearGeneratorMembers();
943
944
  bool CheckReservedTargetName(std::string const& targetName,
945
                               std::string const& reason) const;
946
  bool CheckReservedTargetNamePrefix(std::string const& targetPrefix,
947
                                     std::string const& reason) const;
948
949
  void IndexMakefile(cmMakefile* mf);
950
  void IndexLocalGenerator(cmLocalGenerator* lg);
951
952
0
  virtual char const* GetBuildIgnoreErrorsFlag() const { return nullptr; }
953
954
  bool UnsupportedVariableIsDefined(std::string const& name,
955
                                    bool supported) const;
956
957
  // Cache directory content and target files to be built.
958
  struct DirectoryContent
959
  {
960
    long LastDiskTime = -1;
961
    std::set<std::string> All;
962
    std::set<std::string> Generated;
963
  };
964
  std::map<std::string, DirectoryContent> DirectoryContentMap;
965
966
  // Cache parsed PList files
967
  std::map<std::string, cmXcFrameworkPlist> XcFrameworkPListContentMap;
968
969
  // Set of binary directories on disk.
970
  std::set<std::string> BinaryDirectories;
971
972
  // track targets to issue CMP0068 warning for.
973
  std::set<std::string> CMP0068WarnTargets;
974
975
  std::unordered_set<std::string> WarnedCMP0210Languages;
976
977
  std::unordered_set<std::string> WarnedExperimental;
978
979
  mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>>
980
    FilenameTargetDepends;
981
982
  std::map<std::string, std::string> RealPaths;
983
984
  std::unordered_set<std::string> GeneratedFiles;
985
986
  std::vector<std::unique_ptr<cmInstallRuntimeDependencySet>>
987
    RuntimeDependencySets;
988
  std::map<std::string, cmInstallRuntimeDependencySet*>
989
    RuntimeDependencySetsByName;
990
991
  std::vector<std::string> InstallScripts;
992
  std::vector<std::string> TestFiles;
993
994
#if !defined(CMAKE_BOOTSTRAP)
995
  // Pool of file locks
996
  cmFileLockPool FileLockPool;
997
#endif
998
999
  using PerLanguageModuleDatabases =
1000
    std::map<std::string, std::vector<std::string>>;
1001
  using PerConfigModuleDatabases =
1002
    std::map<std::string, PerLanguageModuleDatabases>;
1003
  PerConfigModuleDatabases PerConfigModuleDbs;
1004
  PerLanguageModuleDatabases PerLanguageModuleDbs;
1005
1006
  enum class IntermediateDirStrategy
1007
  {
1008
    Full,
1009
    Short,
1010
  };
1011
  IntermediateDirStrategy IntDirStrategy = IntermediateDirStrategy::Full;
1012
  IntermediateDirStrategy QtAutogenIntDirStrategy =
1013
    IntermediateDirStrategy::Full;
1014
1015
protected:
1016
  float FirstTimeProgress;
1017
  bool NeedSymbolicMark;
1018
  bool UseLinkScript;
1019
  bool ForceUnixPaths;
1020
  bool ToolSupportsColor;
1021
  bool InstallTargetEnabled;
1022
  bool AllowGlobalTargetCodegen;
1023
};