Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmMakefile.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 <deque>
9
#include <functional>
10
#include <map>
11
#include <memory>
12
#include <set>
13
#include <stack>
14
#include <string>
15
#include <unordered_map>
16
#include <utility>
17
#include <vector>
18
19
#include <cm/optional>
20
#include <cm/string_view>
21
22
#include "cmsys/RegularExpression.hxx"
23
24
#include "cm_sys_stat.h"
25
26
#include "cmAlgorithms.h"
27
#include "cmCustomCommand.h"
28
#include "cmFindPackageStack.h"
29
#include "cmFunctionBlocker.h"
30
#include "cmListFileCache.h"
31
#include "cmMessageType.h" // IWYU pragma: keep
32
#include "cmNewLineStyle.h"
33
#include "cmPolicies.h"
34
#include "cmSourceFileLocationKind.h"
35
#include "cmStateSnapshot.h"
36
#include "cmStateTypes.h"
37
#include "cmValue.h"
38
39
// IWYU does not see that 'std::unordered_map<std::string, cmTarget>'
40
// will not compile without the complete type.
41
#include "cmTarget.h" // IWYU pragma: keep
42
43
#if !defined(CMAKE_BOOTSTRAP)
44
#  include "cmSourceGroup.h"
45
#endif
46
47
enum class cmCustomCommandType;
48
enum class cmObjectLibraryCommands;
49
50
class cmCompiledGeneratorExpression;
51
class cmCustomCommandLines;
52
class cmExecutionStatus;
53
class cmExpandedCommandArgument;
54
class cmExportBuildFileGenerator;
55
class cmGeneratorExpressionEvaluationFile;
56
class cmGlobalGenerator;
57
class cmInstallGenerator;
58
class cmLocalGenerator;
59
class cmMessenger;
60
class cmSourceFile;
61
class cmState;
62
class cmTest;
63
class cmTestGenerator;
64
class cmVariableWatch;
65
class cmake;
66
67
/** A type-safe wrapper for a string representing a directory id.  */
68
class cmDirectoryId
69
{
70
public:
71
  cmDirectoryId(std::string s);
72
  std::string String;
73
};
74
75
/** \class cmMakefile
76
 * \brief Process the input CMakeLists.txt file.
77
 *
78
 * Process and store into memory the input CMakeLists.txt file.
79
 * Each CMakeLists.txt file is parsed and the commands found there
80
 * are added into the build process.
81
 */
82
class cmMakefile
83
{
84
public:
85
  /* Mark a variable as used */
86
  void MarkVariableAsUsed(std::string const& var);
87
  /* return true if a variable has been initialized */
88
  bool VariableInitialized(std::string const&) const;
89
90
  /**
91
   * Construct an empty makefile.
92
   */
93
  cmMakefile(cmGlobalGenerator* globalGenerator,
94
             cmStateSnapshot const& snapshot);
95
96
  /**
97
   * Destructor.
98
   */
99
  ~cmMakefile();
100
101
  cmMakefile(cmMakefile const&) = delete;
102
  cmMakefile& operator=(cmMakefile const&) = delete;
103
104
  cmDirectoryId GetDirectoryId() const;
105
106
  bool ReadListFile(std::string const& filename);
107
108
  bool ReadListFileAsString(std::string const& content,
109
                            std::string const& virtualFileName);
110
111
  bool ReadDependentFile(std::string const& filename,
112
                         bool noPolicyScope = true);
113
114
  /**
115
   * Add a function blocker to this makefile
116
   */
117
  void AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb);
118
119
  /// @return whether we are processing the top CMakeLists.txt file.
120
  bool IsRootMakefile() const;
121
122
  /**
123
   * Remove the function blocker whose scope ends with the given command.
124
   * This returns ownership of the function blocker object.
125
   */
126
  std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker();
127
128
  /**
129
   * Try running cmake and building a file. This is used for dynamically
130
   * loaded commands, not as part of the usual build process.
131
   */
132
  int TryCompile(std::string const& srcdir, std::string const& bindir,
133
                 std::string const& projectName, std::string const& targetName,
134
                 bool fast, int jobs,
135
                 std::vector<std::string> const* cmakeArgs,
136
                 std::string& output);
137
138
  bool GetIsSourceFileTryCompile() const;
139
140
  /**
141
   * Help enforce global target name uniqueness.
142
   */
143
  bool EnforceUniqueName(std::string const& name, std::string& msg,
144
                         bool isCustom = false) const;
145
146
  enum class GeneratorActionWhen
147
  {
148
    // Run after all CMake code has been parsed.
149
    AfterConfigure,
150
    // Run after generator targets have been constructed.
151
    AfterGeneratorTargets,
152
  };
153
154
  class GeneratorAction
155
  {
156
    using ActionT =
157
      std::function<void(cmLocalGenerator&, cmListFileBacktrace const&)>;
158
    using CCActionT =
159
      std::function<void(cmLocalGenerator&, cmListFileBacktrace const&,
160
                         std::unique_ptr<cmCustomCommand> cc)>;
161
162
  public:
163
    GeneratorAction(
164
      ActionT&& action,
165
      GeneratorActionWhen when = GeneratorActionWhen::AfterConfigure)
166
0
      : When(when)
167
0
      , Action(std::move(action))
168
0
    {
169
0
    }
170
171
    GeneratorAction(
172
      std::unique_ptr<cmCustomCommand> tcc, CCActionT&& action,
173
      GeneratorActionWhen when = GeneratorActionWhen::AfterConfigure)
174
0
      : When(when)
175
0
      , CCAction(std::move(action))
176
0
      , cc(std::move(tcc))
177
0
    {
178
0
    }
179
180
    void operator()(cmLocalGenerator& lg, cmListFileBacktrace const& lfbt,
181
                    GeneratorActionWhen when);
182
183
  private:
184
    GeneratorActionWhen When;
185
186
    ActionT Action;
187
188
    // FIXME: Use std::variant
189
    CCActionT CCAction;
190
    std::unique_ptr<cmCustomCommand> cc;
191
  };
192
193
  /**
194
   * Register an action that is executed during Generate
195
   */
196
  void AddGeneratorAction(GeneratorAction&& action);
197
198
  /// Helper to insert the constructor GeneratorAction(args...)
199
  template <class... Args>
200
  void AddGeneratorAction(Args&&... args)
201
0
  {
202
0
    AddGeneratorAction(GeneratorAction(std::move(args)...));
203
0
  }
Unexecuted instantiation: cmFLTKWrapUICommand.cxx:void cmMakefile::AddGeneratorAction<cmFLTKWrapUICommand(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> > > > const&, cmExecutionStatus&)::$_0>(cmFLTKWrapUICommand(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> > > > const&, cmExecutionStatus&)::$_0&&)
Unexecuted instantiation: cmInstallFilesCommand.cxx:void cmMakefile::AddGeneratorAction<cmInstallFilesCommand(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> > > > const&, cmExecutionStatus&)::$_0>(cmInstallFilesCommand(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> > > > const&, cmExecutionStatus&)::$_0&&)
Unexecuted instantiation: cmInstallProgramsCommand.cxx:void cmMakefile::AddGeneratorAction<cmInstallProgramsCommand(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> > > > const&, cmExecutionStatus&)::$_0>(cmInstallProgramsCommand(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> > > > const&, cmExecutionStatus&)::$_0&&)
Unexecuted instantiation: cmVariableWatchCommand.cxx:void cmMakefile::AddGeneratorAction<(anonymous namespace)::FinalAction>((anonymous namespace)::FinalAction&&)
Unexecuted instantiation: void cmMakefile::AddGeneratorAction<std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >, ModuleCompilationDatabaseCommandAction&, cmMakefile::GeneratorActionWhen>(std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >&&, ModuleCompilationDatabaseCommandAction&, cmMakefile::GeneratorActionWhen&&)
Unexecuted instantiation: void cmMakefile::AddGeneratorAction<std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >, ModuleCompilationDatabaseTargetAction&>(std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >&&, ModuleCompilationDatabaseTargetAction&)
Unexecuted instantiation: cmMakefile.cxx:void cmMakefile::AddGeneratorAction<std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >, cmMakefile::AddCustomCommandToTarget(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cmCustomCommandType, std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >)::$_0>(std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >&&, cmMakefile::AddCustomCommandToTarget(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cmCustomCommandType, std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >)::$_0&&)
Unexecuted instantiation: cmMakefile.cxx:void cmMakefile::AddGeneratorAction<std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >, cmMakefile::AddCustomCommandToOutput(std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >, std::__1::function<void (cmSourceFile*)> const&, bool)::$_0>(std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >&&, cmMakefile::AddCustomCommandToOutput(std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >, std::__1::function<void (cmSourceFile*)> const&, bool)::$_0&&)
Unexecuted instantiation: cmMakefile.cxx:void cmMakefile::AddGeneratorAction<cmMakefile::AppendCustomCommandToOutput(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> > > > const&, cmImplicitDependsList const&, cmCustomCommandLines const&)::$_0>(cmMakefile::AppendCustomCommandToOutput(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> > > > const&, cmImplicitDependsList const&, cmCustomCommandLines const&)::$_0&&)
Unexecuted instantiation: cmMakefile.cxx:void cmMakefile::AddGeneratorAction<std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >, cmMakefile::AddUtilityCommand(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >)::$_0>(std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >&&, cmMakefile::AddUtilityCommand(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, std::__1::unique_ptr<cmCustomCommand, std::__1::default_delete<cmCustomCommand> >)::$_0&&)
204
205
  /**
206
   * Perform generate actions, Library dependency analysis etc before output of
207
   * the makefile.
208
   */
209
  void Generate(cmLocalGenerator& lg);
210
  void GenerateAfterGeneratorTargets(cmLocalGenerator& lg);
211
212
  /**
213
   * Get the target for PRE_BUILD, PRE_LINK, or POST_BUILD commands.
214
   */
215
  cmTarget* GetCustomCommandTarget(std::string const& target,
216
                                   cmObjectLibraryCommands objLibCommands,
217
                                   cmListFileBacktrace const& lfbt) const;
218
219
  /**
220
   * Dispatch adding a custom PRE_BUILD, PRE_LINK, or POST_BUILD command to a
221
   * target.
222
   */
223
  cmTarget* AddCustomCommandToTarget(std::string const& target,
224
                                     cmCustomCommandType type,
225
                                     std::unique_ptr<cmCustomCommand> cc);
226
227
  /**
228
   * Called for each file with custom command.
229
   */
230
  using CommandSourceCallback = std::function<void(cmSourceFile*)>;
231
232
  /**
233
   * Dispatch adding a custom command to a source file.
234
   */
235
  void AddCustomCommandToOutput(
236
    std::unique_ptr<cmCustomCommand> cc,
237
    CommandSourceCallback const& callback = nullptr, bool replace = false);
238
  void AppendCustomCommandToOutput(
239
    std::string const& output, std::vector<std::string> const& depends,
240
    cmImplicitDependsList const& implicit_depends,
241
    cmCustomCommandLines const& commandLines);
242
243
  /**
244
   * Add a define flag to the build.
245
   */
246
  void AddDefineFlag(std::string const& definition);
247
  void RemoveDefineFlag(std::string const& definition);
248
  void AddCompileDefinition(std::string const& definition);
249
  void AddCompileOption(std::string const& option);
250
  void AddLinkOption(std::string const& option);
251
  void AddLinkDirectory(std::string const& directory, bool before = false);
252
253
  /** Create a new imported target with the name and type given.  */
254
  cmTarget* AddImportedTarget(std::string const& name,
255
                              cmStateEnums::TargetType type, bool global);
256
257
  cmTarget* AddForeignTarget(std::string const& origin,
258
                             std::string const& name);
259
260
  std::pair<cmTarget&, bool> CreateNewTarget(
261
    std::string const& name, cmStateEnums::TargetType type,
262
    cmTarget::PerConfig perConfig = cmTarget::PerConfig::Yes,
263
    cmTarget::Visibility vis = cmTarget::Visibility::Normal);
264
265
  cmTarget* AddNewTarget(cmStateEnums::TargetType type,
266
                         std::string const& name);
267
  cmTarget* AddSynthesizedTarget(cmStateEnums::TargetType type,
268
                                 std::string const& name);
269
270
  /** Create a target instance for the utility.  */
271
  cmTarget* AddNewUtilityTarget(std::string const& utilityName,
272
                                bool excludeFromAll);
273
274
  /**
275
   * Add an executable to the build.
276
   */
277
  cmTarget* AddExecutable(std::string const& exename,
278
                          std::vector<std::string> const& srcs,
279
                          bool excludeFromAll = false);
280
281
  /**
282
   * Dispatch adding a utility to the build.  A utility target is a command
283
   * that is run every time the target is built.
284
   */
285
  cmTarget* AddUtilityCommand(std::string const& utilityName,
286
                              bool excludeFromAll,
287
                              std::unique_ptr<cmCustomCommand> cc);
288
289
  /**
290
   * Add a subdirectory to the build.
291
   */
292
  void AddSubDirectory(std::string const& fullSrcDir,
293
                       std::string const& fullBinDir, bool excludeFromAll,
294
                       bool immediate, bool system);
295
296
  void Configure();
297
298
  /**
299
   * Configure a subdirectory
300
   */
301
  void ConfigureSubDirectory(cmMakefile* mf);
302
303
  /**
304
   * Add an include directory to the build.
305
   */
306
  void AddIncludeDirectories(std::vector<std::string> const& incs,
307
                             bool before = false);
308
309
  /**
310
   * Add a variable definition to the build. This variable
311
   * can be used in CMake to refer to lists, directories, etc.
312
   */
313
  void AddDefinition(std::string const& name, cm::string_view value);
314
  void AddDefinition(std::string const& name, cmValue value)
315
0
  {
316
0
    this->AddDefinition(name, *value);
317
0
  }
318
  /**
319
   * Add bool variable definition to the build.
320
   */
321
  void AddDefinitionBool(std::string const& name, bool);
322
  //! Add a definition to this makefile and the global cmake cache.
323
  void AddCacheDefinition(std::string const& name, cmValue value, cmValue doc,
324
                          cmStateEnums::CacheEntryType type,
325
                          bool force = false);
326
  void AddCacheDefinition(std::string const& name, cmValue value,
327
                          std::string const& doc,
328
                          cmStateEnums::CacheEntryType type,
329
                          bool force = false)
330
0
  {
331
0
    this->AddCacheDefinition(name, value, cmValue{ doc }, type, force);
332
0
  }
333
  void AddCacheDefinition(std::string const& name, std::string const& value,
334
                          std::string const& doc,
335
                          cmStateEnums::CacheEntryType type,
336
                          bool force = false)
337
0
  {
338
0
    this->AddCacheDefinition(name, cmValue{ value }, cmValue{ doc }, type,
339
0
                             force);
340
0
  }
341
342
  /**
343
   * Remove a variable definition from the build.  This is not valid
344
   * for cache entries, and will only affect the current makefile.
345
   */
346
  void RemoveDefinition(std::string const& name);
347
  //! Remove a definition from the cache.
348
  void RemoveCacheDefinition(std::string const& name) const;
349
350
  /**
351
   * Specify the name of the project for this build.
352
   */
353
  void SetProjectName(std::string const& name);
354
355
  void InitCMAKE_CONFIGURATION_TYPES(std::string const& genDefault);
356
357
  /* Get the default configuration */
358
  std::string GetDefaultConfiguration() const;
359
360
  enum GeneratorConfigQuery
361
  {
362
    IncludeEmptyConfig, // Include "" aka noconfig
363
    ExcludeEmptyConfig, // Exclude "" aka noconfig
364
    OnlyMultiConfig,
365
  };
366
367
  /** Get the configurations for dependency checking.  */
368
  std::vector<std::string> GetGeneratorConfigs(
369
    GeneratorConfigQuery mode) const;
370
371
  /**
372
   * Set the name of the library.
373
   */
374
  cmTarget* AddLibrary(std::string const& libname,
375
                       cmStateEnums::TargetType type,
376
                       std::vector<std::string> const& srcs,
377
                       bool excludeFromAll = false);
378
  void AddAlias(std::string const& libname, std::string const& tgt,
379
                bool globallyVisible = true);
380
381
  //@{
382
  /**
383
   * Set, Push, Pop policy values for CMake.
384
   */
385
  bool SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
386
  bool SetPolicy(char const* id, cmPolicies::PolicyStatus status);
387
  cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id,
388
                                           bool parent_scope = false) const;
389
  bool SetPolicyVersion(std::string const& version_min,
390
                        std::string const& version_max);
391
  void RecordPolicies(cmPolicies::PolicyMap& pm) const;
392
  //@}
393
394
  /** Update CMAKE_PARENT_LIST_FILE based on CMP0198 policy status.  */
395
  void UpdateParentListFileVariable();
396
397
  /** Helper class to push and pop policies automatically.  */
398
  class PolicyPushPop
399
  {
400
  public:
401
    PolicyPushPop(cmMakefile* m);
402
    ~PolicyPushPop();
403
404
    PolicyPushPop(PolicyPushPop const&) = delete;
405
    PolicyPushPop& operator=(PolicyPushPop const&) = delete;
406
407
  private:
408
    cmMakefile* Makefile;
409
  };
410
  friend class PolicyPushPop;
411
412
  /** Helper class to push and pop variables scopes automatically. */
413
  class VariablePushPop
414
  {
415
  public:
416
    VariablePushPop(cmMakefile* m);
417
    ~VariablePushPop();
418
419
    VariablePushPop(VariablePushPop const&) = delete;
420
    VariablePushPop& operator=(VariablePushPop const&) = delete;
421
422
  private:
423
    cmMakefile* Makefile;
424
  };
425
426
  std::string const& GetHomeDirectory() const;
427
  std::string const& GetHomeOutputDirectory() const;
428
429
  /**
430
   * Set CMAKE_SCRIPT_MODE_FILE variable when running a -P script.
431
   */
432
  void SetScriptModeFile(std::string const& scriptfile);
433
434
  /**
435
   * Set CMAKE_ARGC, CMAKE_ARGV0 ... variables.
436
   */
437
  void SetArgcArgv(std::vector<std::string> const& args);
438
439
  std::string const& GetCurrentSourceDirectory() const;
440
  std::string const& GetCurrentBinaryDirectory() const;
441
442
  //@}
443
444
  /**
445
   * Set a regular expression that include files must match
446
   * in order to be considered as part of the depend information.
447
   */
448
  void SetIncludeRegularExpression(std::string const& regex)
449
0
  {
450
0
    this->SetProperty("INCLUDE_REGULAR_EXPRESSION", regex);
451
0
  }
452
  std::string const& GetIncludeRegularExpression() const
453
0
  {
454
0
    return this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
455
0
  }
456
457
  /**
458
   * Set a regular expression that include files that are not found
459
   * must match in order to be considered a problem.
460
   */
461
  void SetComplainRegularExpression(std::string const& regex)
462
0
  {
463
0
    this->ComplainFileRegularExpression = regex;
464
0
  }
465
  std::string const& GetComplainRegularExpression() const
466
0
  {
467
0
    return this->ComplainFileRegularExpression;
468
0
  }
469
470
  // -- List of targets
471
  using cmTargetMap = std::unordered_map<std::string, cmTarget>;
472
  /** Get the target map */
473
0
  cmTargetMap& GetTargets() { return this->Targets; }
474
  /** Get the target map - const version */
475
0
  cmTargetMap const& GetTargets() const { return this->Targets; }
476
477
  std::vector<std::unique_ptr<cmTarget>> const& GetOwnedImportedTargets() const
478
0
  {
479
0
    return this->ImportedTargetsOwned;
480
0
  }
481
  std::vector<cmTarget*> GetImportedTargets() const;
482
483
  cmTarget* FindImportedTarget(std::string const& name) const;
484
485
  cmTarget* FindLocalNonAliasTarget(std::string const& name) const;
486
487
  /** Find a target to use in place of the given name.  The target
488
      returned may be imported or built within the project.  */
489
  cmTarget* FindTargetToUse(std::string const& name,
490
                            cmStateEnums::TargetDomainSet domains = {
491
                              cmStateEnums::TargetDomain::NATIVE,
492
                              cmStateEnums::TargetDomain::ALIAS }) const;
493
  bool IsAlias(std::string const& name) const;
494
495
  std::map<std::string, std::string> GetAliasTargets() const
496
0
  {
497
0
    return this->AliasTargets;
498
0
  }
499
500
  /**
501
   * Mark include directories as system directories.
502
   */
503
  void AddSystemIncludeDirectories(std::set<std::string> const& incs);
504
505
  /** Get a cmSourceFile pointer for a given source name, if the name is
506
   *  not found, then a null pointer is returned.
507
   */
508
  cmSourceFile* GetSource(
509
    std::string const& sourceName,
510
    cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous) const;
511
512
  /** Create the source file and return it. generated
513
   * indicates if it is a generated file, this is used in determining
514
   * how to create the source file instance e.g. name
515
   */
516
  cmSourceFile* CreateSource(
517
    std::string const& sourceName, bool generated = false,
518
    cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
519
520
  /** Get a cmSourceFile pointer for a given source name, if the name is
521
   *  not found, then create the source file and return it. generated
522
   * indicates if it is a generated file, this is used in determining
523
   * how to create the source file instance e.g. name
524
   */
525
  cmSourceFile* GetOrCreateSource(
526
    std::string const& sourceName, bool generated = false,
527
    cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
528
529
  /** Get a cmSourceFile pointer for a given source name and always mark the
530
   * file as generated, if the name is not found, then create the source file
531
   * and return it.
532
   */
533
  cmSourceFile* GetOrCreateGeneratedSource(std::string const& sourceName);
534
535
  void AddTargetObject(std::string const& tgtName, std::string const& objFile);
536
537
  /**
538
   * Given a variable name, return its value (as a string).
539
   * If the variable is not found in this makefile instance, the
540
   * cache is then queried.
541
   */
542
  cmValue GetDefinition(std::string const&) const;
543
  std::string const& GetSafeDefinition(std::string const&) const;
544
  std::string const& GetRequiredDefinition(std::string const& name) const;
545
  bool IsDefinitionSet(std::string const&) const;
546
  bool IsNormalDefinitionSet(std::string const&) const;
547
  /**
548
   * Get the list of all variables in the current space. If argument
549
   * cacheonly is specified and is greater than 0, then only cache
550
   * variables will be listed.
551
   */
552
  std::vector<std::string> GetDefinitions() const;
553
554
  /**
555
   * Test a boolean variable to see if it is true or false.
556
   * If the variable is not found in this makefile instance, the
557
   * cache is then queried.
558
   * Returns false if no entry defined.
559
   */
560
  bool IsOn(std::string const& name) const;
561
  bool IsSet(std::string const& name) const;
562
563
  /** Return whether the target platform is 32-bit. */
564
  bool PlatformIs32Bit() const;
565
566
  /** Return whether the target platform is 64-bit.  */
567
  bool PlatformIs64Bit() const;
568
  /** Return whether the target platform is x32.  */
569
  bool PlatformIsx32() const;
570
571
  /** Apple SDK Type */
572
  enum class AppleSDK
573
  {
574
    MacOS,
575
    IPhoneOS,
576
    IPhoneSimulator,
577
    AppleTVOS,
578
    AppleTVSimulator,
579
    WatchOS,
580
    WatchSimulator,
581
    XROS,
582
    XRSimulator,
583
  };
584
585
  /** What SDK type points CMAKE_OSX_SYSROOT to? */
586
  AppleSDK GetAppleSDKType() const;
587
588
  /** Return whether the target platform is Apple iOS.  */
589
  bool PlatformIsAppleEmbedded() const;
590
591
  /** Return whether the target platform is an Apple simulator.  */
592
  bool PlatformIsAppleSimulator() const;
593
594
  /** Return whether the target platform is an Apple catalyst.  */
595
  bool PlatformIsAppleCatalyst() const;
596
597
  /** Return whether the target platform supports generation of text base stubs
598
     (.tbd file) describing exports (Apple specific). */
599
  bool PlatformSupportsAppleTextStubs() const;
600
601
  /** Retrieve soname flag for the specified language if supported */
602
  char const* GetSONameFlag(std::string const& language) const;
603
604
  /**
605
   * Get a list of preprocessor define flags.
606
   */
607
0
  std::string GetDefineFlags() const { return this->DefineFlags; }
608
609
  /**
610
   * Make sure CMake can write this file
611
   */
612
  bool CanIWriteThisFile(std::string const& fileName) const;
613
614
#if !defined(CMAKE_BOOTSTRAP)
615
616
  /**
617
   * Resolve source group genex.
618
   */
619
  void ResolveSourceGroupGenex(cmLocalGenerator* lg);
620
621
  /**
622
   * Get the vector source groups.
623
   */
624
  SourceGroupVector const& GetSourceGroups() const
625
0
  {
626
0
    return this->SourceGroups;
627
0
  }
628
629
  /**
630
   * Get the source group
631
   */
632
  cmSourceGroup* GetSourceGroup(std::vector<std::string> const& name) const;
633
634
  /**
635
   * Add a root source group for consideration when adding a new source.
636
   */
637
  void AddSourceGroup(std::string const& name, char const* regex = nullptr);
638
639
  /**
640
   * Add a source group for consideration when adding a new source.
641
   * name is tokenized.
642
   */
643
  void AddSourceGroup(std::vector<std::string> const& name,
644
                      char const* regex = nullptr);
645
646
  /**
647
   * Get and existing or create a new source group.
648
   */
649
  cmSourceGroup* GetOrCreateSourceGroup(
650
    std::vector<std::string> const& folders);
651
652
  /**
653
   * Get and existing or create a new source group.
654
   * The name will be tokenized.
655
   */
656
  cmSourceGroup* GetOrCreateSourceGroup(std::string const& name);
657
#endif
658
659
  /**
660
   * Get the vector of list files on which this makefile depends
661
   */
662
  std::vector<std::string> const& GetListFiles() const
663
0
  {
664
0
    return this->ListFiles;
665
0
  }
666
  //! When the file changes cmake will be re-run from the build system.
667
  void AddCMakeDependFile(std::string const& file)
668
0
  {
669
0
    this->ListFiles.push_back(file);
670
0
  }
671
  void AddCMakeDependFilesFromUser();
672
673
  std::string FormatListFileStack() const;
674
675
  /**
676
   * Get the current context backtrace.
677
   */
678
  cmListFileBacktrace GetBacktrace() const;
679
680
  /**
681
   * Get the current stack of find_package calls.
682
   */
683
  cmFindPackageStack GetFindPackageStack() const;
684
685
  /**
686
   * Get the vector of  files created by this makefile
687
   */
688
  std::vector<std::string> const& GetOutputFiles() const
689
0
  {
690
0
    return this->OutputFiles;
691
0
  }
692
  void AddCMakeOutputFile(std::string const& file)
693
0
  {
694
0
    this->OutputFiles.push_back(file);
695
0
  }
696
697
  /**
698
   * Expand all defined variables in the string.
699
   * Defined variables come from the this->Definitions map.
700
   * They are expanded with ${var} where var is the
701
   * entry in the this->Definitions map.  Also \@var\@ is
702
   * expanded to match autoconf style expansions.
703
   */
704
  std::string const& ExpandVariablesInString(std::string& source) const;
705
  std::string const& ExpandVariablesInString(
706
    std::string& source, bool escapeQuotes, bool noEscapes,
707
    bool atOnly = false, char const* filename = nullptr, long line = -1,
708
    bool removeEmpty = false, bool replaceAt = false) const;
709
710
  /**
711
   * Remove any remaining variables in the string. Anything with ${var} or
712
   * \@var\@ will be removed.
713
   */
714
  void RemoveVariablesInString(std::string& source, bool atOnly = false) const;
715
716
  /**
717
   * Replace variables and #cmakedefine lines in the given string.
718
   * See cmConfigureFileCommand for details.
719
   */
720
  void ConfigureString(std::string const& input, std::string& output,
721
                       bool atOnly, bool escapeQuotes) const;
722
723
  /**
724
   * Copy file but change lines according to ConfigureString
725
   */
726
  int ConfigureFile(std::string const& infile, std::string const& outfile,
727
                    bool copyonly, bool atOnly, bool escapeQuotes,
728
                    mode_t permissions = 0, cmNewLineStyle = cmNewLineStyle());
729
730
  enum class CommandMissingFromStack
731
  {
732
    No,
733
    Yes,
734
  };
735
736
  /**
737
   * Print a command's invocation
738
   */
739
  void PrintCommandTrace(
740
    cmListFileFunction const& lff, cmListFileBacktrace const& bt,
741
    CommandMissingFromStack missing = CommandMissingFromStack::No) const;
742
743
  /**
744
   * Set a callback that is invoked whenever ExecuteCommand is called.
745
   */
746
  void OnExecuteCommand(std::function<void()> callback);
747
748
  /**
749
   * Execute a single CMake command.  Returns true if the command
750
   * succeeded or false if it failed.
751
   */
752
  bool ExecuteCommand(cmListFileFunction const& lff, cmExecutionStatus& status,
753
                      cm::optional<std::string> deferId = {});
754
755
  //! Enable support for named language, if nil then all languages are
756
  /// enabled.
757
  void EnableLanguage(std::vector<std::string> const& languages,
758
                      bool optional);
759
760
  cmState* GetState() const;
761
762
/**
763
 * Get the variable watch. This is used to determine when certain variables
764
 * are accessed.
765
 */
766
#ifndef CMAKE_BOOTSTRAP
767
  cmVariableWatch* GetVariableWatch() const;
768
#endif
769
770
  //! Display progress or status message.
771
  void DisplayStatus(std::string const&, float) const;
772
773
  /**
774
   * Expand the given list file arguments into the full set after
775
   * variable replacement and list expansion.
776
   */
777
  bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
778
                       std::vector<std::string>& outArgs) const;
779
  bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
780
                       std::vector<cmExpandedCommandArgument>& outArgs) const;
781
782
  /**
783
   * Get the instance
784
   */
785
  cmake* GetCMakeInstance() const;
786
  cmMessenger* GetMessenger() const;
787
  cmGlobalGenerator* GetGlobalGenerator() const;
788
789
  /**
790
   * Get all the source files this makefile knows about
791
   */
792
  std::vector<std::unique_ptr<cmSourceFile>> const& GetSourceFiles() const
793
0
  {
794
0
    return this->SourceFiles;
795
0
  }
796
797
  std::vector<cmTarget*> const& GetOrderedTargets() const
798
0
  {
799
0
    return this->OrderedTargets;
800
0
  }
801
802
  //! Add a new cmTest to the list of tests for this makefile.
803
  cmTest* CreateTest(std::string const& testName);
804
805
  /** Get a cmTest pointer for a given test name, if the name is
806
   *  not found, then a null pointer is returned.
807
   */
808
  cmTest* GetTest(std::string const& testName) const;
809
810
  /**
811
   * Get all tests that run under the given configuration.
812
   */
813
  void GetTests(std::string const& config, std::vector<cmTest*>& tests) const;
814
815
  /**
816
   * Return a location of a file in cmake or custom modules directory
817
   */
818
  std::string GetModulesFile(cm::string_view name) const
819
0
  {
820
0
    bool system;
821
0
    std::string debugBuffer;
822
0
    return this->GetModulesFile(name, system, false, debugBuffer);
823
0
  }
824
825
  /**
826
   * Return a location of a file in cmake or custom modules directory
827
   */
828
  std::string GetModulesFile(cm::string_view name, bool& system) const
829
0
  {
830
0
    std::string debugBuffer;
831
0
    return this->GetModulesFile(name, system, false, debugBuffer);
832
0
  }
833
834
  std::string GetModulesFile(cm::string_view name, bool& system, bool debug,
835
                             std::string& debugBuffer) const;
836
837
  //! Set/Get a property of this directory
838
  void SetProperty(std::string const& prop, cmValue value);
839
  void SetProperty(std::string const& prop, std::nullptr_t)
840
0
  {
841
0
    this->SetProperty(prop, cmValue{ nullptr });
842
0
  }
843
  void SetProperty(std::string const& prop, std::string const& value)
844
0
  {
845
0
    this->SetProperty(prop, cmValue(value));
846
0
  }
847
  void AppendProperty(std::string const& prop, std::string const& value,
848
                      bool asString = false);
849
  cmValue GetProperty(std::string const& prop) const;
850
  cmValue GetProperty(std::string const& prop, bool chain) const;
851
  bool GetPropertyAsBool(std::string const& prop) const;
852
  std::vector<std::string> GetPropertyKeys() const;
853
854
  //! Initialize a makefile from its parent
855
  void InitializeFromParent(cmMakefile* parent);
856
857
  bool ExplicitlyGeneratesSbom() const;
858
  void SetExplicitlyGeneratesSbom(bool status = true);
859
860
  void AddInstallGenerator(std::unique_ptr<cmInstallGenerator> g);
861
862
  std::vector<std::unique_ptr<cmInstallGenerator>>& GetInstallGenerators()
863
0
  {
864
0
    return this->InstallGenerators;
865
0
  }
866
  std::vector<std::unique_ptr<cmInstallGenerator>> const&
867
  GetInstallGenerators() const
868
0
  {
869
0
    return this->InstallGenerators;
870
0
  }
871
872
  void AddTestGenerator(std::unique_ptr<cmTestGenerator> g);
873
874
  std::vector<std::unique_ptr<cmTestGenerator>> const& GetTestGenerators()
875
    const
876
0
  {
877
0
    return this->TestGenerators;
878
0
  }
879
880
  class FunctionPushPop
881
  {
882
  public:
883
    FunctionPushPop(cmMakefile* mf, std::string const& fileName,
884
                    cmPolicies::PolicyMap const& pm);
885
    ~FunctionPushPop();
886
887
    FunctionPushPop(FunctionPushPop const&) = delete;
888
    FunctionPushPop& operator=(FunctionPushPop const&) = delete;
889
890
0
    void Quiet() { this->ReportError = false; }
891
892
  private:
893
    cmMakefile* Makefile;
894
    bool ReportError = true;
895
  };
896
897
  class MacroPushPop
898
  {
899
  public:
900
    MacroPushPop(cmMakefile* mf, std::string const& fileName,
901
                 cmPolicies::PolicyMap const& pm);
902
    ~MacroPushPop();
903
904
    MacroPushPop(MacroPushPop const&) = delete;
905
    MacroPushPop& operator=(MacroPushPop const&) = delete;
906
907
0
    void Quiet() { this->ReportError = false; }
908
909
  private:
910
    cmMakefile* Makefile;
911
    bool ReportError = true;
912
  };
913
914
  void PushFunctionScope(std::string const& fileName,
915
                         cmPolicies::PolicyMap const& pm);
916
  void PopFunctionScope(bool reportError);
917
  void PushMacroScope(std::string const& fileName,
918
                      cmPolicies::PolicyMap const& pm);
919
  void PopMacroScope(bool reportError);
920
  void PushScope();
921
  void PopScope();
922
  void RaiseScope(std::string const& var, char const* value);
923
  void RaiseScope(std::string const& var, cmValue value)
924
0
  {
925
0
    this->RaiseScope(var, value.GetCStr());
926
0
  }
927
  void RaiseScope(std::vector<std::string> const& variables);
928
929
  // push and pop loop scopes
930
  void PushLoopBlockBarrier();
931
  void PopLoopBlockBarrier();
932
933
  bool IsImportedTargetGlobalScope() const;
934
935
  enum class ImportedTargetScope
936
  {
937
    Local,
938
    Global,
939
  };
940
941
  /** Helper class to manage whether imported packages
942
   * should be globally scoped based off the find package command
943
   */
944
  class SetGlobalTargetImportScope
945
  {
946
  public:
947
    SetGlobalTargetImportScope(cmMakefile* mk, ImportedTargetScope const scope)
948
0
      : Makefile(mk)
949
0
    {
950
0
      if (scope == ImportedTargetScope::Global &&
951
0
          !this->Makefile->IsImportedTargetGlobalScope()) {
952
0
        this->Makefile->CurrentImportedTargetScope = scope;
953
0
        this->Set = true;
954
0
      } else {
955
0
        this->Set = false;
956
0
      }
957
0
    }
958
    ~SetGlobalTargetImportScope()
959
0
    {
960
0
      if (this->Set) {
961
0
        this->Makefile->CurrentImportedTargetScope =
962
0
          ImportedTargetScope::Local;
963
0
      }
964
0
    }
965
966
  private:
967
    cmMakefile* Makefile;
968
    bool Set;
969
  };
970
971
  /** Helper class to push and pop scopes automatically.  */
972
  class ScopePushPop
973
  {
974
  public:
975
    ScopePushPop(cmMakefile* m)
976
0
      : Makefile(m)
977
0
    {
978
0
      this->Makefile->PushScope();
979
0
    }
980
981
0
    ~ScopePushPop() { this->Makefile->PopScope(); }
982
983
    ScopePushPop(ScopePushPop const&) = delete;
984
    ScopePushPop& operator=(ScopePushPop const&) = delete;
985
986
  private:
987
    cmMakefile* Makefile;
988
  };
989
990
  void IssueMessage(MessageType t, std::string const& text) const;
991
  Message::LogLevel GetCurrentLogLevel() const;
992
993
  /** Set whether or not to report a CMP0000 violation.  */
994
0
  void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
995
996
  void IssueInvalidTargetNameError(std::string const& targetName) const;
997
998
  cmBTStringRange GetIncludeDirectoriesEntries() const;
999
  cmBTStringRange GetCompileOptionsEntries() const;
1000
  cmBTStringRange GetCompileDefinitionsEntries() const;
1001
  cmBTStringRange GetLinkOptionsEntries() const;
1002
  cmBTStringRange GetLinkDirectoriesEntries() const;
1003
1004
  std::set<std::string> const& GetSystemIncludeDirectories() const
1005
0
  {
1006
0
    return this->SystemIncludeDirectories;
1007
0
  }
1008
1009
  bool PolicyOptionalWarningEnabled(std::string const& var) const;
1010
1011
  void PushLoopBlock();
1012
  void PopLoopBlock();
1013
  bool IsLoopBlock() const;
1014
1015
  void ClearMatches();
1016
  void StoreMatches(cmsys::RegularExpression& re);
1017
1018
  cmStateSnapshot GetStateSnapshot() const;
1019
1020
  void EnforceDirectoryLevelRules() const;
1021
1022
  void AddEvaluationFile(
1023
    std::string const& inputFile, std::string const& targetName,
1024
    std::unique_ptr<cmCompiledGeneratorExpression> outputName,
1025
    std::unique_ptr<cmCompiledGeneratorExpression> condition,
1026
    std::string const& newLineCharacter, mode_t permissions,
1027
    bool inputIsContent);
1028
  std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>> const&
1029
  GetEvaluationFiles() const;
1030
1031
  std::vector<std::unique_ptr<cmExportBuildFileGenerator>> const&
1032
  GetExportBuildFileGenerators() const;
1033
  void AddExportBuildFileGenerator(
1034
    std::unique_ptr<cmExportBuildFileGenerator> gen);
1035
1036
  // Maintain a stack of package roots to allow nested PACKAGE_ROOT_PATH
1037
  // searches
1038
  std::deque<std::vector<std::string>> FindPackageRootPathStack;
1039
1040
  friend class cmFindPackageStackRAII;
1041
1042
  class DebugFindPkgRAII
1043
  {
1044
    cmMakefile* Makefile;
1045
    bool OldValue;
1046
1047
  public:
1048
    DebugFindPkgRAII(cmMakefile* mf, std::string const& pkg);
1049
    ~DebugFindPkgRAII();
1050
1051
    DebugFindPkgRAII(DebugFindPkgRAII const&) = delete;
1052
    DebugFindPkgRAII& operator=(DebugFindPkgRAII const&) = delete;
1053
  };
1054
1055
  class CallRAII
1056
  {
1057
  public:
1058
    CallRAII(cmMakefile* mf, std::string const& file,
1059
             cmExecutionStatus& status);
1060
    ~CallRAII();
1061
1062
    CallRAII(CallRAII const&) = delete;
1063
    CallRAII& operator=(CallRAII const&) = delete;
1064
1065
  protected:
1066
    CallRAII(cmMakefile* mf, cmListFileContext const& lfc,
1067
             cmExecutionStatus& status);
1068
1069
    cmMakefile* Detach();
1070
1071
    cmMakefile* Makefile;
1072
  };
1073
1074
  bool GetDebugFindPkgMode() const;
1075
1076
  void MaybeWarnCMP0074(std::string const& rootVar, cmValue rootDef,
1077
                        cm::optional<std::string> const& rootEnv);
1078
  void MaybeWarnCMP0144(std::string const& rootVAR, cmValue rootDEF,
1079
                        cm::optional<std::string> const& rootENV);
1080
  void MaybeWarnUninitialized(std::string const& variable,
1081
                              char const* sourceFilename) const;
1082
  bool IsProjectFile(char const* filename) const;
1083
1084
  size_t GetRecursionDepthLimit() const;
1085
1086
  size_t GetRecursionDepth() const;
1087
  void SetRecursionDepth(size_t recursionDepth);
1088
1089
  std::string NewDeferId() const;
1090
  bool DeferCall(std::string id, std::string fileName, cmListFileFunction lff);
1091
  bool DeferCancelCall(std::string const& id);
1092
  cm::optional<std::string> DeferGetCallIds() const;
1093
  cm::optional<std::string> DeferGetCall(std::string const& id) const;
1094
1095
protected:
1096
  // add link libraries and directories to the target
1097
  void AddGlobalLinkInformation(cmTarget& target);
1098
1099
  // libraries, classes, and executables
1100
  mutable cmTargetMap Targets;
1101
  std::map<std::string, std::string> AliasTargets;
1102
1103
  std::vector<cmTarget*> OrderedTargets;
1104
1105
  std::vector<std::unique_ptr<cmSourceFile>> SourceFiles;
1106
1107
  // Because cmSourceFile names are compared in a fuzzy way (see
1108
  // cmSourceFileLocation::Match()) we can't have a straight mapping from
1109
  // filename to cmSourceFile.  To make lookups more efficient we store the
1110
  // Name portion of the cmSourceFileLocation and then compare on the list of
1111
  // cmSourceFiles that might match that name.  Note that on platforms which
1112
  // have a case-insensitive filesystem we store the key in all lowercase.
1113
  using SourceFileMap =
1114
    std::unordered_map<std::string, std::vector<cmSourceFile*>>;
1115
  SourceFileMap SourceFileSearchIndex;
1116
1117
  // For "Known" paths we can store a direct filename to cmSourceFile map
1118
  std::unordered_map<std::string, cmSourceFile*> KnownFileSearchIndex;
1119
1120
  // Tests
1121
  std::map<std::string, std::unique_ptr<cmTest>> Tests;
1122
1123
  // The set of include directories that are marked as system include
1124
  // directories.
1125
  std::set<std::string> SystemIncludeDirectories;
1126
1127
  std::vector<std::string> ListFiles;
1128
  std::vector<std::string> OutputFiles;
1129
1130
  std::vector<std::unique_ptr<cmInstallGenerator>> InstallGenerators;
1131
  std::vector<std::unique_ptr<cmTestGenerator>> TestGenerators;
1132
1133
  std::string ComplainFileRegularExpression;
1134
  std::string DefineFlags;
1135
1136
#if !defined(CMAKE_BOOTSTRAP)
1137
  SourceGroupVector SourceGroups;
1138
  size_t ObjectLibrariesSourceGroupIndex;
1139
#endif
1140
1141
  cmGlobalGenerator* GlobalGenerator;
1142
  bool IsFunctionBlocked(cmListFileFunction const& lff,
1143
                         cmExecutionStatus& status);
1144
1145
private:
1146
  cmStateSnapshot StateSnapshot;
1147
  cmListFileBacktrace Backtrace;
1148
  size_t RecursionDepth = 0;
1149
1150
  struct DeferCommand
1151
  {
1152
    // Id is empty for an already-executed or canceled operation.
1153
    std::string Id;
1154
    std::string FilePath;
1155
    cmListFileFunction Command;
1156
  };
1157
  struct DeferCommands
1158
  {
1159
    std::vector<DeferCommand> Commands;
1160
  };
1161
  std::unique_ptr<DeferCommands> Defer;
1162
  bool DeferRunning = false;
1163
1164
  void DoGenerate(cmLocalGenerator& lg);
1165
1166
  void RunListFile(cmListFile const& listFile,
1167
                   std::string const& filenametoread,
1168
                   DeferCommands* defer = nullptr);
1169
1170
  bool ParseDefineFlag(std::string const& definition, bool remove);
1171
1172
  bool EnforceUniqueDir(std::string const& srcPath,
1173
                        std::string const& binPath) const;
1174
1175
  std::function<void()> ExecuteCommandCallback;
1176
  using FunctionBlockerPtr = std::unique_ptr<cmFunctionBlocker>;
1177
  using FunctionBlockersType =
1178
    std::stack<FunctionBlockerPtr, std::vector<FunctionBlockerPtr>>;
1179
  FunctionBlockersType FunctionBlockers;
1180
  std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
1181
  void PushFunctionBlockerBarrier();
1182
  void PopFunctionBlockerBarrier(bool reportError = true);
1183
1184
  std::stack<int> LoopBlockCounter;
1185
1186
  mutable cmsys::RegularExpression cmDefineRegex;
1187
  mutable cmsys::RegularExpression cmDefine01Regex;
1188
  mutable cmsys::RegularExpression cmNamedCurly;
1189
1190
  std::vector<cmMakefile*> UnConfiguredDirectories;
1191
  std::vector<std::unique_ptr<cmExportBuildFileGenerator>>
1192
    ExportBuildFileGenerators;
1193
1194
  std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>
1195
    EvaluationFiles;
1196
1197
  class CallScope;
1198
  friend class CallScope;
1199
1200
  std::vector<cmExecutionStatus*> ExecutionStatusStack;
1201
  friend class cmParseFileScope;
1202
1203
  std::vector<std::unique_ptr<cmTarget>> ImportedTargetsOwned;
1204
  using TargetMap = std::unordered_map<std::string, cmTarget*>;
1205
  TargetMap ImportedTargets;
1206
1207
  // Internal policy stack management.
1208
  void PushPolicy(bool weak = false,
1209
                  cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
1210
  void PopPolicy();
1211
  void PopSnapshot(bool reportError = true);
1212
  friend bool cmCMakePolicyCommand(std::vector<std::string> const& args,
1213
                                   cmExecutionStatus& status);
1214
  class IncludeScope;
1215
  friend class IncludeScope;
1216
1217
  class ListFileScope;
1218
  friend class ListFileScope;
1219
1220
  class DeferScope;
1221
  friend class DeferScope;
1222
1223
  class DeferCallScope;
1224
  friend class DeferCallScope;
1225
1226
  class BuildsystemFileScope;
1227
  friend class BuildsystemFileScope;
1228
1229
  MessageType ExpandVariablesInStringImpl(std::string& errorstr,
1230
                                          std::string& source,
1231
                                          bool escapeQuotes, bool noEscapes,
1232
                                          bool atOnly, char const* filename,
1233
                                          long line, bool replaceAt) const;
1234
1235
  bool ValidateCustomCommand(cmCustomCommandLines const& commandLines) const;
1236
1237
  void CreateGeneratedOutputs(std::vector<std::string> const& outputs);
1238
1239
  std::vector<BT<GeneratorAction>> GeneratorActions;
1240
  bool GeneratorActionsInvoked = false;
1241
1242
  cmFindPackageStack FindPackageStack;
1243
  unsigned int FindPackageStackNextIndex = 0;
1244
1245
  bool ExplicitSbomGenerator = false;
1246
  bool DebugFindPkg = false;
1247
1248
  bool CheckSystemVars;
1249
  bool CheckCMP0000;
1250
  std::set<std::string> WarnedCMP0074;
1251
  std::set<std::string> WarnedCMP0144;
1252
  bool IsSourceFileTryCompile;
1253
  ImportedTargetScope CurrentImportedTargetScope = ImportedTargetScope::Local;
1254
};