Coverage Report

Created: 2026-09-14 06:43

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: cmCMakeLanguageCommand.cxx:void cmMakefile::AddGeneratorAction<(anonymous namespace)::PrintTargetPropertiesDeferred(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >, std::__1::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> > > >, bool, std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::optional<cmsys::RegularExpression>, std::__1::optional<cmsys::RegularExpression>, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmExecutionStatus&)::$_0, cmMakefile::GeneratorActionWhen>((anonymous namespace)::PrintTargetPropertiesDeferred(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >, std::__1::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> > > >, bool, std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::optional<cmsys::RegularExpression>, std::__1::optional<cmsys::RegularExpression>, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cmExecutionStatus&)::$_0&&, cmMakefile::GeneratorActionWhen&&)
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
  cmStateSnapshot::WarnCMP0220 RaiseToRoot(std::string const& var,
976
                                           char const* varDef);
977
978
  // push and pop loop scopes
979
  void PushLoopBlockBarrier();
980
  void PopLoopBlockBarrier();
981
982
  bool IsImportedTargetGlobalScope() const;
983
984
  /** Helper class to manage whether imported packages
985
   * should be globally scoped based off the find package command
986
   */
987
  class SetGlobalTargetImportScope
988
  {
989
  public:
990
    SetGlobalTargetImportScope(cmMakefile* mk,
991
                               cm::ImportedTargetScope const scope)
992
0
      : Makefile(mk)
993
0
    {
994
0
      if (scope == cm::ImportedTargetScope::Global &&
995
0
          !this->Makefile->IsImportedTargetGlobalScope()) {
996
0
        this->Makefile->CurrentImportedTargetScope = scope;
997
0
        this->Set = true;
998
0
      } else {
999
0
        this->Set = false;
1000
0
      }
1001
0
    }
1002
    ~SetGlobalTargetImportScope()
1003
0
    {
1004
0
      if (this->Set) {
1005
0
        this->Makefile->CurrentImportedTargetScope =
1006
0
          cm::ImportedTargetScope::Local;
1007
0
      }
1008
0
    }
1009
1010
  private:
1011
    cmMakefile* Makefile;
1012
    bool Set;
1013
  };
1014
1015
  /** Helper class to push and pop scopes automatically.  */
1016
  class ScopePushPop
1017
  {
1018
  public:
1019
    ScopePushPop(cmMakefile* m)
1020
0
      : Makefile(m)
1021
0
    {
1022
0
      this->Makefile->PushScope();
1023
0
    }
1024
1025
0
    ~ScopePushPop() { this->Makefile->PopScope(); }
1026
1027
    ScopePushPop(ScopePushPop const&) = delete;
1028
    ScopePushPop& operator=(ScopePushPop const&) = delete;
1029
1030
  private:
1031
    cmMakefile* Makefile;
1032
  };
1033
1034
  void IssueMessage(MessageType t, std::string const& text) const
1035
0
  {
1036
0
    this->IssueMessage(t, text, this->Backtrace);
1037
0
  }
1038
  void IssueMessage(MessageType t, std::string const& text,
1039
                    cmListFileBacktrace const& bt) const;
1040
1041
  void IssueDiagnostic(cmDiagnosticCategory category,
1042
                       std::string const& text) const
1043
0
  {
1044
0
    this->IssueDiagnostic(category, text,
1045
0
                          cmDiagnosticContext{ this->Backtrace });
1046
0
  }
1047
  void IssueDiagnostic(cmDiagnosticCategory category, std::string const& text,
1048
                       cmListFileBacktrace backtrace) const
1049
0
  {
1050
0
    this->IssueDiagnostic(category, text,
1051
0
                          cmDiagnosticContext{ std::move(backtrace) });
1052
0
  }
1053
  void IssueDiagnostic(cmDiagnosticCategory category, std::string const& text,
1054
                       cmDiagnosticContext const& context) const;
1055
  void IssuePolicyWarning(cmPolicies::PolicyID policy, cm::string_view preface,
1056
                          cm::string_view postface,
1057
                          cmListFileBacktrace const& bt) const;
1058
  void IssuePolicyWarning(cmPolicies::PolicyID policy,
1059
                          cm::string_view preface = {},
1060
                          cm::string_view postface = {}) const
1061
0
  {
1062
0
    this->IssuePolicyWarning(policy, preface, postface, this->Backtrace);
1063
0
  }
1064
  Message::LogLevel GetCurrentLogLevel() const;
1065
1066
  /** Set whether or not to report a CMP0000 violation.  */
1067
0
  void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
1068
1069
  void IssueInvalidTargetNameError(std::string const& targetName) const;
1070
1071
  cmBTStringRange GetIncludeDirectoriesEntries() const;
1072
  cmBTStringRange GetCompileOptionsEntries() const;
1073
  cmBTStringRange GetCompileDefinitionsEntries() const;
1074
  cmBTStringRange GetLinkOptionsEntries() const;
1075
  cmBTStringRange GetLinkDirectoriesEntries() const;
1076
1077
  std::set<std::string> const& GetSystemIncludeDirectories() const
1078
0
  {
1079
0
    return this->SystemIncludeDirectories;
1080
0
  }
1081
1082
  bool PolicyOptionalWarningEnabled(std::string const& var) const;
1083
1084
  void PushLoopBlock();
1085
  void PopLoopBlock();
1086
  bool IsLoopBlock() const;
1087
1088
  void ClearMatches();
1089
  void StoreMatches(cmsys::RegularExpression& re);
1090
1091
  cmStateSnapshot GetStateSnapshot() const;
1092
1093
  void EnforceDirectoryLevelRules() const;
1094
1095
  void AddEvaluationFile(
1096
    std::string const& inputFile, std::string const& targetName,
1097
    std::unique_ptr<cmCompiledGeneratorExpression> outputName,
1098
    std::unique_ptr<cmCompiledGeneratorExpression> condition,
1099
    std::string const& newLineCharacter, mode_t permissions,
1100
    bool inputIsContent);
1101
  std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>> const&
1102
  GetEvaluationFiles() const;
1103
1104
  std::vector<std::unique_ptr<cmExportBuildFileGenerator>> const&
1105
  GetExportBuildFileGenerators() const;
1106
  void AddExportBuildFileGenerator(
1107
    std::unique_ptr<cmExportBuildFileGenerator> gen);
1108
1109
#ifndef CMAKE_BOOTSTRAP
1110
  std::vector<std::unique_ptr<cmBuildSbomGenerator>> const&
1111
  GetBuildSbomGenerators() const;
1112
  void AddBuildSbomGenerator(std::unique_ptr<cmBuildSbomGenerator> gen);
1113
#endif
1114
1115
  // Maintain a stack of package roots to allow nested PACKAGE_ROOT_PATH
1116
  // searches
1117
  std::deque<std::vector<std::string>> FindPackageRootPathStack;
1118
1119
  /**
1120
   * RAII type to manage the find_package call stack.
1121
   */
1122
  class FindPackageStackRAII
1123
  {
1124
    cmMakefile* Makefile;
1125
1126
  public:
1127
    FindPackageStackRAII(cmMakefile* mf, std::string const& pkg,
1128
                         std::shared_ptr<cmPackageInformation const> pkgInfo);
1129
    ~FindPackageStackRAII();
1130
1131
    FindPackageStackRAII(FindPackageStackRAII const&) = delete;
1132
    FindPackageStackRAII& operator=(FindPackageStackRAII const&) = delete;
1133
  };
1134
1135
  class DebugFindPkgRAII
1136
  {
1137
    cmMakefile* Makefile;
1138
    bool OldValue;
1139
1140
  public:
1141
    DebugFindPkgRAII(cmMakefile* mf, std::string const& pkg);
1142
    ~DebugFindPkgRAII();
1143
1144
    DebugFindPkgRAII(DebugFindPkgRAII const&) = delete;
1145
    DebugFindPkgRAII& operator=(DebugFindPkgRAII const&) = delete;
1146
  };
1147
1148
  class CallRAII
1149
  {
1150
  public:
1151
    CallRAII(cmMakefile* mf, std::string const& file,
1152
             cmExecutionStatus& status);
1153
    ~CallRAII();
1154
1155
    CallRAII(CallRAII const&) = delete;
1156
    CallRAII& operator=(CallRAII const&) = delete;
1157
1158
  protected:
1159
    CallRAII(cmMakefile* mf, cmListFileContext const& lfc,
1160
             cmExecutionStatus& status);
1161
1162
    cmMakefile* Detach();
1163
1164
    cmMakefile* Makefile;
1165
  };
1166
1167
  bool GetDebugFindPkgMode() const;
1168
1169
  void MaybeWarnCMP0074(std::string const& rootVar, cmValue rootDef,
1170
                        cm::optional<std::string> const& rootEnv);
1171
  void MaybeWarnCMP0144(std::string const& rootVAR, cmValue rootDEF,
1172
                        cm::optional<std::string> const& rootENV);
1173
  void MaybeWarnUninitialized(std::string const& variable,
1174
                              char const* sourceFilename) const;
1175
  bool IsProjectFile(char const* filename) const;
1176
1177
  size_t GetRecursionDepthLimit() const;
1178
1179
  size_t GetRecursionDepth() const;
1180
  void SetRecursionDepth(size_t recursionDepth);
1181
1182
  std::string NewDeferId() const;
1183
  bool DeferCall(std::string id, std::string fileName, cmListFileFunction lff);
1184
  bool DeferCancelCall(std::string const& id);
1185
  cm::optional<std::string> DeferGetCallIds() const;
1186
  cm::optional<std::string> DeferGetCall(std::string const& id) const;
1187
1188
  //! Check CMP0219 policy status for the given callee and arguments.
1189
  //! Returns the effective policy status: OLD, NEW, or WARN (only on
1190
  //! first occurrence of calleeName with backslashes present).  The
1191
  //! caller is responsible for issuing any warning when WARN is returned.
1192
  cmPolicies::PolicyStatus CheckCMP0219(std::string const& calleeName,
1193
                                        std::vector<std::string> const& args);
1194
  cmPolicies::PolicyStatus CheckCMP0219(
1195
    std::string const& calleeName,
1196
    std::vector<cmListFileArgument> const& args);
1197
  void IssueCMP0219Warning(std::string const& calleeName,
1198
                           std::vector<std::string> const& args) const;
1199
  void IssueCMP0219Warning(std::string const& calleeName,
1200
                           std::vector<cmListFileArgument> const& args) const;
1201
1202
protected:
1203
  // add link libraries and directories to the target
1204
  void AddGlobalLinkInformation(cmTarget& target);
1205
1206
  // libraries, classes, and executables
1207
  mutable cmTargetMap Targets;
1208
  std::map<std::string, std::string> AliasTargets;
1209
1210
  std::vector<cmTarget*> OrderedTargets;
1211
1212
  std::vector<std::unique_ptr<cmSourceFile>> SourceFiles;
1213
1214
  // Because cmSourceFile names are compared in a fuzzy way (see
1215
  // cmSourceFileLocation::Match()) we can't have a straight mapping from
1216
  // filename to cmSourceFile.  To make lookups more efficient we store the
1217
  // Name portion of the cmSourceFileLocation and then compare on the list of
1218
  // cmSourceFiles that might match that name.  Note that on platforms which
1219
  // have a case-insensitive filesystem we store the key in all lowercase.
1220
  using SourceFileMap =
1221
    std::unordered_map<std::string, std::vector<cmSourceFile*>>;
1222
  SourceFileMap SourceFileSearchIndex;
1223
1224
  // For "Known" paths we can store a direct filename to cmSourceFile map
1225
  std::unordered_map<std::string, cmSourceFile*> KnownFileSearchIndex;
1226
1227
  // Tests
1228
  std::map<std::string, std::unique_ptr<cmTest>> Tests;
1229
1230
  // The set of include directories that are marked as system include
1231
  // directories.
1232
  std::set<std::string> SystemIncludeDirectories;
1233
1234
  std::vector<std::string> ListFiles;
1235
  std::vector<std::string> OutputFiles;
1236
1237
  std::vector<std::unique_ptr<cmInstallGenerator>> InstallGenerators;
1238
  std::vector<std::unique_ptr<cmTestGenerator>> TestGenerators;
1239
1240
  std::string ComplainFileRegularExpression;
1241
  std::string DefineFlags;
1242
1243
#if !defined(CMAKE_BOOTSTRAP)
1244
  SourceGroupVector SourceGroups;
1245
  size_t ObjectLibrariesSourceGroupIndex;
1246
#endif
1247
1248
  cmGlobalGenerator* GlobalGenerator;
1249
  bool IsFunctionBlocked(cmListFileFunction const& lff,
1250
                         cmExecutionStatus& status);
1251
1252
private:
1253
  cmStateSnapshot StateSnapshot;
1254
  cmListFileBacktrace Backtrace;
1255
  size_t RecursionDepth = 0;
1256
1257
  struct DeferCommand
1258
  {
1259
    // Id is empty for an already-executed or canceled operation.
1260
    std::string Id;
1261
    std::string FilePath;
1262
    cmListFileFunction Command;
1263
  };
1264
  struct DeferCommands
1265
  {
1266
    std::vector<DeferCommand> Commands;
1267
  };
1268
  std::unique_ptr<DeferCommands> Defer;
1269
  bool DeferRunning = false;
1270
1271
  void DoGenerate(cmLocalGenerator& lg);
1272
1273
  void RunListFile(cmListFile const& listFile,
1274
                   std::string const& filenametoread,
1275
                   DeferCommands* defer = nullptr);
1276
1277
  bool ParseDefineFlag(std::string const& definition, bool remove);
1278
1279
  bool EnforceUniqueDir(std::string const& srcPath,
1280
                        std::string const& binPath) const;
1281
1282
  std::function<void()> ExecuteCommandCallback;
1283
  using FunctionBlockerPtr = std::unique_ptr<cmFunctionBlocker>;
1284
  using FunctionBlockersType =
1285
    std::stack<FunctionBlockerPtr, std::vector<FunctionBlockerPtr>>;
1286
  FunctionBlockersType FunctionBlockers;
1287
  std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
1288
  void PushFunctionBlockerBarrier();
1289
  void PopFunctionBlockerBarrier(bool reportError = true);
1290
1291
  std::stack<int> LoopBlockCounter;
1292
1293
  mutable cmsys::RegularExpression cmDefineRegex;
1294
  mutable cmsys::RegularExpression cmDefine01Regex;
1295
  mutable cmsys::RegularExpression cmNamedCurly;
1296
1297
  std::vector<cmMakefile*> UnConfiguredDirectories;
1298
  std::vector<std::unique_ptr<cmExportBuildFileGenerator>>
1299
    ExportBuildFileGenerators;
1300
1301
#ifndef CMAKE_BOOTSTRAP
1302
  std::vector<std::unique_ptr<cmBuildSbomGenerator>> BuildSbomGenerators;
1303
#endif
1304
1305
  std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>
1306
    EvaluationFiles;
1307
1308
  class CallScope;
1309
  friend class CallScope;
1310
1311
  std::vector<cmExecutionStatus*> ExecutionStatusStack;
1312
  friend class cmParseFileScope;
1313
1314
  std::vector<std::unique_ptr<cmTarget>> ImportedTargetsOwned;
1315
  using TargetMap = std::unordered_map<std::string, cmTarget*>;
1316
  TargetMap ImportedTargets;
1317
1318
  // Internal policy stack management.
1319
  void PushPolicy(bool weak = false, cmPolicies::PolicyMap const& pm = {});
1320
  void PopPolicy();
1321
  friend bool cmCMakePolicyCommand(std::vector<std::string> const& args,
1322
                                   cmExecutionStatus& status);
1323
1324
  // Internal diagnostic stack management.
1325
  void PushDiagnostic(bool weak = false, cmDiagnostics::DiagnosticMap dm = {});
1326
  void PopDiagnostic();
1327
  friend bool cmCMakeDiagnosticCommand(std::vector<std::string> const& args,
1328
                                       cmExecutionStatus& status);
1329
1330
  void PopSnapshot(bool reportError = true);
1331
1332
  class IncludeScope;
1333
  friend class IncludeScope;
1334
1335
  class ListFileScope;
1336
  friend class ListFileScope;
1337
1338
  class DeferScope;
1339
  friend class DeferScope;
1340
1341
  class DeferCallScope;
1342
  friend class DeferCallScope;
1343
1344
  class BuildsystemFileScope;
1345
  friend class BuildsystemFileScope;
1346
1347
  MessageType ExpandVariablesInStringImpl(std::string& errorstr,
1348
                                          std::string& source,
1349
                                          bool escapeQuotes, bool noEscapes,
1350
                                          bool atOnly, char const* filename,
1351
                                          long line, bool replaceAt) const;
1352
1353
  bool ValidateCustomCommand(cmCustomCommandLines const& commandLines) const;
1354
1355
  void CreateGeneratedOutputs(std::vector<std::string> const& outputs);
1356
1357
  std::vector<BT<GeneratorAction>> GeneratorActions;
1358
  bool GeneratorActionsInvoked = false;
1359
1360
  cmFindPackageStack FindPackageStack;
1361
  unsigned int FindPackageStackNextIndex = 0;
1362
1363
  bool DebugFindPkg = false;
1364
1365
  bool CheckSystemVars;
1366
  bool CheckCMP0000;
1367
  std::set<std::string> WarnedCMP0074;
1368
  std::set<std::string> WarnedCMP0144;
1369
  std::set<std::string> WarnedCMP0219;
1370
  bool IsSourceFileTryCompile;
1371
  cm::ImportedTargetScope CurrentImportedTargetScope =
1372
    cm::ImportedTargetScope::Local;
1373
};