Coverage Report

Created: 2026-06-15 07:03

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