Coverage Report

Created: 2026-10-28 06:38

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