Coverage Report

Created: 2026-07-14 07:09

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