Coverage Report

Created: 2026-10-28 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmLocalGenerator.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 <iosfwd>
9
#include <map>
10
#include <memory>
11
#include <set>
12
#include <string>
13
#include <unordered_map>
14
#include <unordered_set>
15
#include <utility>
16
#include <vector>
17
18
#include <cm/optional>
19
#include <cm/string_view>
20
21
#include "cmCustomCommandTypes.h"
22
#include "cmDiagnosticContext.h"
23
#include "cmDiagnostics.h"
24
#include "cmGeneratorOptions.h"
25
#include "cmGeneratorTarget.h"
26
#include "cmListFileCache.h"
27
#include "cmMessageType.h" // IWYU pragma: keep
28
#include "cmOutputConverter.h"
29
#include "cmPolicies.h"
30
#include "cmStateSnapshot.h"
31
#include "cmStateTypes.h"
32
#include "cmValue.h"
33
34
class cmCompiledGeneratorExpression;
35
class cmComputeLinkInformation;
36
class cmGeneratorRule;
37
class cmCustomCommand;
38
class cmCustomCommandGenerator;
39
class cmCustomCommandLines;
40
class cmGlobalGenerator;
41
class cmImplicitDependsList;
42
class cmLinkLineComputer;
43
class cmLinkLineDeviceComputer;
44
class cmMakefile;
45
struct cmObjectLocation;
46
struct cmObjectLocations;
47
class cmRulePlaceholderExpander;
48
class cmSourceFile;
49
class cmSourceGroup;
50
class cmState;
51
class cmTarget;
52
class cmake;
53
54
template <typename Iter>
55
class cmRange;
56
57
namespace cm {
58
enum class TargetType;
59
} // namespace cm
60
61
/** Target and source file which have a specific output.  */
62
struct cmSourcesWithOutput
63
{
64
  /** Target with byproduct.  */
65
  cmTarget* Target = nullptr;
66
67
  /** Source file with output or byproduct.  */
68
  cmSourceFile* Source = nullptr;
69
  bool SourceIsByproduct = false;
70
};
71
72
/** \class cmLocalGenerator
73
 * \brief Create required build files for a directory.
74
 *
75
 * Subclasses of this abstract class generate makefiles, DSP, etc for various
76
 * platforms. This class should never be constructed directly. A
77
 * GlobalGenerator will create it and invoke the appropriate commands on it.
78
 */
79
class cmLocalGenerator : public cmOutputConverter
80
{
81
public:
82
  struct DirectoryTestPrepDependency
83
  {
84
    DirectoryTestPrepDependency(std::string raw, cmGeneratorTarget* target,
85
                                cmGeneratorTarget* owner = nullptr,
86
                                bool generated = false)
87
0
      : Raw(std::move(raw))
88
0
      , Target(target)
89
0
      , Owner(owner)
90
0
      , Generated(generated)
91
0
    {
92
0
    }
93
94
    std::string Raw;
95
    cmGeneratorTarget* Target;
96
    cmGeneratorTarget* Owner;
97
    bool Generated;
98
  };
99
100
  struct DirectoryTestPrepTarget
101
  {
102
    std::string Name;
103
    std::string Comment;
104
    std::vector<DirectoryTestPrepDependency> Dependencies;
105
  };
106
107
  cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile);
108
  ~cmLocalGenerator() override;
109
110
  /**
111
   * Generate the makefile for this directory.
112
   */
113
0
  virtual void Generate() {}
114
115
0
  virtual void ComputeHomeRelativeOutputPath() {}
116
117
  /**
118
   * Calls TraceVSDependencies() on all targets of this generator.
119
   */
120
  void TraceDependencies() const;
121
122
#ifndef CMAKE_BOOTSTRAP
123
  /**
124
   * Resolve source group genex.
125
   */
126
  void ResolveSourceGroupGenex();
127
#endif
128
129
0
  virtual void AddHelperCommands() {}
130
131
  /**
132
   * Generate the install rules files in this directory.
133
   */
134
  void GenerateInstallRules();
135
136
  /**
137
   * Generate the test files for tests.
138
   */
139
  void GenerateTestFiles();
140
141
  /**
142
   * Generate a manifest of target files that will be built.
143
   */
144
  void ComputeTargetManifest();
145
146
  bool ComputeTargetCompileFeatures();
147
148
  bool IsRootMakefile() const;
149
150
  //! Get the makefile for this generator
151
41.1k
  cmMakefile* GetMakefile() const { return this->Makefile; }
152
153
  //! Get the GlobalGenerator this is associated with
154
173k
  cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; }
155
  cmGlobalGenerator const* GetGlobalGenerator() const
156
136k
  {
157
136k
    return this->GlobalGenerator;
158
136k
  }
159
160
  virtual std::unique_ptr<cmRulePlaceholderExpander>
161
  CreateRulePlaceholderExpander(
162
    cmBuildStep buildStep = cmBuildStep::Compile) const;
163
164
  void AddDirectoryTestPrepDependency(std::string const& config,
165
                                      DirectoryTestPrepDependency dependency);
166
  bool GetDirectoryTestPrepTarget(DirectoryTestPrepTarget& out,
167
                                  std::string const& config);
168
169
  std::string GetExeExportFlags(std::string const& linkLanguage,
170
                                cmGeneratorTarget& tgt) const;
171
172
  cmState* GetState() const;
173
  cmStateSnapshot GetStateSnapshot() const;
174
175
  void AddArchitectureFlags(std::string& flags,
176
                            cmGeneratorTarget const* target,
177
                            std::string const& lang, std::string const& config,
178
                            std::string const& filterArch = std::string());
179
180
  void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target,
181
                        cmBuildStep compileOrLink, std::string const& lang,
182
                        std::string const& config);
183
  void AddLanguageFlagsForLinking(std::string& flags,
184
                                  cmGeneratorTarget const* target,
185
                                  std::string const& lang,
186
                                  std::string const& config);
187
  void AddFeatureFlags(std::string& flags, cmGeneratorTarget const* target,
188
                       std::string const& lang, std::string const& config);
189
  void AddVisibilityPresetFlags(std::string& flags,
190
                                cmGeneratorTarget const* target,
191
                                std::string const& lang);
192
  void AddConfigVariableFlags(std::string& flags, std::string const& var,
193
                              std::string const& config);
194
  // Handle prefixes processing (like LINKER:)
195
  void AddConfigVariableFlags(std::string& flags, std::string const& var,
196
                              cmGeneratorTarget const* target,
197
                              cmBuildStep compileOrLink,
198
                              std::string const& lang,
199
                              std::string const& config);
200
  void AddColorDiagnosticsFlags(std::string& flags, std::string const& lang);
201
  //! Append flags to a string.
202
  virtual void AppendFlags(std::string& flags,
203
                           std::string const& newFlags) const;
204
  virtual void AppendFlags(std::string& flags,
205
                           std::vector<BT<std::string>> const& newFlags) const;
206
  virtual void AppendFlagEscape(std::string& flags,
207
                                std::string const& rawFlag) const;
208
  /**
209
   * Append flags after parsing, prefixes processing (like LINKER:) and
210
   * escaping
211
   */
212
  void AppendLinkFlagsWithParsing(std::string& flags,
213
                                  std::string const& newFlags,
214
                                  cmGeneratorTarget const* target,
215
                                  std::string const& lang);
216
  void AppendFlags(std::string& flags, std::string const& newFlags,
217
                   std::string const& name, cmGeneratorTarget const* target,
218
                   cmBuildStep compileOrLink, std::string const& lang);
219
  void AddISPCDependencies(cmGeneratorTarget* target);
220
  void AddPchDependencies(cmGeneratorTarget* target);
221
  void AddUnityBuild(cmGeneratorTarget* target);
222
0
  virtual void AddXCConfigSources(cmGeneratorTarget* /* target */) {}
223
  void AddPerLanguageLinkFlags(std::string& flags,
224
                               cmGeneratorTarget const* target,
225
                               std::string const& lang,
226
                               std::string const& config);
227
  void AppendTargetCreationLinkFlags(std::string& flags,
228
                                     cmGeneratorTarget const* target,
229
                                     std::string const& linkLanguage);
230
  void AppendLinkerTypeFlags(std::string& flags, cmGeneratorTarget* target,
231
                             std::string const& config,
232
                             std::string const& linkLanguage);
233
  void AddTargetTypeLinkerFlags(std::string& flags,
234
                                cmGeneratorTarget const* target,
235
                                std::string const& lang,
236
                                std::string const& config);
237
  void AddTargetPropertyLinkFlags(std::string& flags,
238
                                  cmGeneratorTarget const* target,
239
                                  std::string const& config);
240
  void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
241
                            std::string const& config,
242
                            std::string const& lang);
243
  void AppendPositionIndependentLinkerFlags(std::string& flags,
244
                                            cmGeneratorTarget* target,
245
                                            std::string const& config,
246
                                            std::string const& lang);
247
  void AppendWarningAsErrorLinkerFlags(std::string& flags,
248
                                       cmGeneratorTarget* target,
249
                                       std::string const& lang);
250
  void AppendDependencyInfoLinkerFlags(std::string& flags,
251
                                       cmGeneratorTarget* target,
252
                                       std::string const& config,
253
                                       std::string const& lang);
254
  virtual std::string GetLinkDependencyFile(cmGeneratorTarget* target,
255
                                            std::string const& config) const;
256
  void AppendModuleDefinitionFlag(std::string& flags,
257
                                  cmGeneratorTarget const* target,
258
                                  cmLinkLineComputer* linkLineComputer,
259
                                  std::string const& config,
260
                                  std::string const& lang);
261
  bool AppendLWYUFlags(std::string& flags, cmGeneratorTarget const* target,
262
                       std::string const& lang);
263
264
  //! Get the include flags for the current makefile and language
265
  std::string GetIncludeFlags(std::vector<std::string> const& includes,
266
                              cmGeneratorTarget* target,
267
                              std::string const& lang,
268
                              std::string const& config,
269
                              bool forResponseFile = false);
270
271
  using GeneratorTargetVector =
272
    std::vector<std::unique_ptr<cmGeneratorTarget>>;
273
  GeneratorTargetVector const& GetGeneratorTargets() const
274
0
  {
275
0
    return this->GeneratorTargets;
276
0
  }
277
278
  GeneratorTargetVector const& GetOwnedImportedGeneratorTargets() const
279
0
  {
280
0
    return this->OwnedImportedGeneratorTargets;
281
0
  }
282
283
  void AddGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt);
284
  void AddImportedGeneratorTarget(cmGeneratorTarget* gt);
285
  void AddOwnedImportedGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt);
286
287
  cmGeneratorTarget* FindLocalNonAliasGeneratorTarget(
288
    std::string const& name) const;
289
  cmGeneratorTarget* FindGeneratorTargetToUse(std::string const& name) const;
290
291
  void AddGeneratorRule(std::unique_ptr<cmGeneratorRule> gr);
292
  cmGeneratorRule* FindGeneratorRuleToUse(std::string const& name) const;
293
294
  /**
295
   * Process a list of include directories
296
   */
297
  void AppendIncludeDirectories(std::vector<std::string>& includes,
298
                                std::string const& includes_list,
299
                                cmSourceFile const& sourceFile) const;
300
  void AppendIncludeDirectories(std::vector<std::string>& includes,
301
                                std::vector<std::string> const& includes_vec,
302
                                cmSourceFile const& sourceFile) const;
303
304
  /**
305
   * Encode a list of preprocessor definitions for the compiler
306
   * command line.
307
   */
308
  void AppendDefines(std::set<std::string>& defines,
309
                     std::string const& defines_list) const;
310
  void AppendDefines(std::set<std::string>& defines,
311
                     std::vector<BT<std::string>> const& defines_vec) const;
312
  void AppendDefines(std::set<BT<std::string>>& defines,
313
                     std::string const& defines_list) const;
314
  void AppendDefines(std::set<BT<std::string>>& defines,
315
                     std::vector<BT<std::string>> const& defines_vec) const;
316
317
  /**
318
   * Encode a list of compile options for the compiler
319
   * command line.
320
   */
321
  void AppendCompileOptions(std::string& options,
322
                            std::string const& options_list,
323
                            char const* regex = nullptr) const;
324
  void AppendCompileOptions(std::string& options,
325
                            std::vector<std::string> const& options_vec,
326
                            char const* regex = nullptr) const;
327
  void AppendCompileOptions(std::vector<BT<std::string>>& options,
328
                            std::vector<BT<std::string>> const& options_vec,
329
                            char const* regex = nullptr) const;
330
331
  /**
332
   * Join a set of defines into a definesString with a space separator.
333
   */
334
  void JoinDefines(std::set<std::string> const& defines,
335
                   std::string& definesString, std::string const& lang);
336
337
  /** Lookup and append options associated with a particular feature.  */
338
  void AppendFeatureOptions(std::string& flags, std::string const& lang,
339
                            char const* feature);
340
341
  cmValue GetFeature(std::string const& feature, std::string const& config);
342
343
  /** \brief Get absolute path to dependency \a name
344
   *
345
   * Translate a dependency as given in CMake code to the name to
346
   * appear in a generated build file.
347
   * - If \a name is a utility target, returns false.
348
   * - If \a name is a CMake target, it will be transformed to the real output
349
   *   location of that target for the given configuration.
350
   * - If \a name is the full path to a file, it will be returned.
351
   * - Otherwise \a name is treated as a relative path with respect to
352
   *   the source directory of this generator.  This should only be
353
   *   used for dependencies of custom commands.
354
   */
355
  bool GetRealDependency(std::string const& name, std::string const& config,
356
                         std::string& dep, cmPolicies::PolicyStatus cmp0212);
357
358
  /**
359
   * Translate a file dependency as given in CMake code to a full path.
360
   * - If \a name is a full path, it will be returned.
361
   * - If \a name names a source file known to this directory, such as the
362
   *   output of a custom command, its full path will be returned.
363
   * - Otherwise \a name is treated as a relative path with respect to the
364
   *   source directory of this generator if it exists there, or else with
365
   *   respect to its binary directory.
366
   */
367
  std::string GetRealFileDependency(std::string const& name) const;
368
369
  /** Called from command-line hook to clear dependencies.  */
370
0
  virtual void ClearDependencies(cmMakefile* /* mf */, bool /* verbose */) {}
371
372
  /** Called from command-line hook to update dependencies.  */
373
  virtual bool UpdateDependencies(std::string const& /* tgtInfo */,
374
                                  std::string const& /* targetName */,
375
                                  bool /*verbose*/, bool /*color*/)
376
0
  {
377
0
    return true;
378
0
  }
379
380
  /** @brief Get the include directories for the current makefile and language
381
   * and optional the compiler implicit include directories.
382
   *
383
   * @arg stripImplicitDirs Strip all directories found in
384
   *      CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES from the result.
385
   * @arg appendAllImplicitDirs Append all directories found in
386
   *      CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES to the result.
387
   */
388
  std::vector<BT<std::string>> GetIncludeDirectoriesImplicit(
389
    cmGeneratorTarget const* target, std::string const& lang = "C",
390
    std::string const& config = "", bool stripImplicitDirs = true,
391
    bool appendAllImplicitDirs = false) const;
392
393
  /** @brief Get the include directories for the current makefile and language
394
   * and optional the compiler implicit include directories.
395
   *
396
   * @arg dirs Directories are appended to this list
397
   */
398
  void GetIncludeDirectoriesImplicit(std::vector<std::string>& dirs,
399
                                     cmGeneratorTarget const* target,
400
                                     std::string const& lang = "C",
401
                                     std::string const& config = "",
402
                                     bool stripImplicitDirs = true,
403
                                     bool appendAllImplicitDirs = false) const;
404
405
  /** @brief Get the include directories for the current makefile and language.
406
   * @arg dirs Include directories are appended to this list
407
   */
408
  void GetIncludeDirectories(std::vector<std::string>& dirs,
409
                             cmGeneratorTarget const* target,
410
                             std::string const& lang = "C",
411
                             std::string const& config = "") const;
412
413
  /** @brief Get the include directories for the current makefile and language.
414
   * @return The include directory list
415
   */
416
  std::vector<BT<std::string>> GetIncludeDirectories(
417
    cmGeneratorTarget const* target, std::string const& lang = "C",
418
    std::string const& config = "") const;
419
420
  void AddCompileOptions(std::string& flags, cmGeneratorTarget* target,
421
                         std::string const& lang, std::string const& config);
422
  void AddCompileOptions(std::vector<BT<std::string>>& flags,
423
                         cmGeneratorTarget* target, std::string const& lang,
424
                         std::string const& config);
425
426
  /**
427
   * Add a custom PRE_BUILD, PRE_LINK, or POST_BUILD command to a target.
428
   */
429
  cmTarget* AddCustomCommandToTarget(
430
    std::string const& target, cmCustomCommandType type,
431
    std::unique_ptr<cmCustomCommand> cc,
432
    cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject);
433
434
  /**
435
   * Add a custom command to a source file.
436
   */
437
  cmSourceFile* AddCustomCommandToOutput(std::unique_ptr<cmCustomCommand> cc,
438
                                         bool replace = false);
439
440
  /**
441
   * Add a utility to the build.  A utility target is a command that is run
442
   * every time the target is built.
443
   */
444
  cmTarget* AddUtilityCommand(std::string const& utilityName,
445
                              bool excludeFromAll,
446
                              std::unique_ptr<cmCustomCommand> cc);
447
448
  virtual std::string CreateUtilityOutput(
449
    std::string const& targetName, std::vector<std::string> const& byproducts,
450
    cmListFileBacktrace const& bt);
451
452
  virtual std::vector<cmCustomCommandGenerator> MakeCustomCommandGenerators(
453
    cmCustomCommand const& cc, std::string const& config);
454
455
  std::vector<std::string> ExpandCustomCommandOutputPaths(
456
    cmCompiledGeneratorExpression const& cge, std::string const& config);
457
  std::vector<std::string> ExpandCustomCommandOutputGenex(
458
    std::string const& o, cmListFileBacktrace const& bt);
459
460
  /**
461
   * Add target byproducts.
462
   */
463
  void AddTargetByproducts(cmTarget* target,
464
                           std::vector<std::string> const& byproducts,
465
                           cmListFileBacktrace const& bt,
466
                           cmCommandOrigin origin);
467
468
  enum class OutputRole
469
  {
470
    Primary,
471
    Byproduct,
472
  };
473
474
  /**
475
   * Add source file outputs.
476
   */
477
  void AddSourceOutputs(cmSourceFile* source,
478
                        std::vector<std::string> const& outputs,
479
                        OutputRole role, cmListFileBacktrace const& bt,
480
                        cmCommandOrigin origin);
481
482
  /**
483
   * Return the target if the provided source name is a byproduct of a utility
484
   * target or a PRE_BUILD, PRE_LINK, or POST_BUILD command.
485
   * Return the source file which has the provided source name as output.
486
   */
487
  cmSourcesWithOutput GetSourcesWithOutput(std::string const& name) const;
488
489
  /**
490
   * Add every path recorded as an output or byproduct of a custom command or
491
   * custom target in this directory, as they are keyed for the efficient
492
   * full-path lookup of GetSourcesWithOutput.
493
   */
494
  void AppendOutputsAndByproducts(
495
    std::unordered_set<std::string>& outputs) const;
496
497
  /**
498
   * Is there a source file that has the provided source name as an output?
499
   * If so then return it.
500
   */
501
  cmSourceFile* GetSourceFileWithOutput(
502
    std::string const& name,
503
    cmSourceOutputKind kind = cmSourceOutputKind::OutputOnly) const;
504
505
  std::string GetProjectName() const;
506
507
  /** Compute the language used to compile the given source file.  */
508
  std::string GetSourceFileLanguage(cmSourceFile const& source);
509
510
  // Fill the vector with the target names for the object files,
511
  // preprocessed files and assembly files.
512
0
  void GetIndividualFileTargets(std::vector<std::string>&) {}
513
514
  /**
515
   * Get the relative path from the generator output directory to a
516
   * per-target support directory.
517
   */
518
  virtual std::string GetTargetDirectory(
519
    cmGeneratorTarget const* target,
520
    cmStateEnums::IntermediateDirKind kind) const;
521
522
  cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id) const;
523
524
  cmake* GetCMakeInstance() const;
525
526
  std::string const& GetSourceDirectory() const;
527
  std::string const& GetBinaryDirectory() const;
528
529
  std::string const& GetCurrentBinaryDirectory() const;
530
  std::string const& GetCurrentSourceDirectory() const;
531
532
  bool UseShortObjectNames(
533
    cmStateEnums::IntermediateDirKind kind =
534
      cmStateEnums::IntermediateDirKind::ObjectFiles) const;
535
  virtual std::string GetObjectOutputRoot(
536
    cmStateEnums::IntermediateDirKind kind =
537
      cmStateEnums::IntermediateDirKind::ObjectFiles) const;
538
  virtual bool AlwaysUsesCMFPaths() const;
539
  virtual std::string GetShortObjectFileName(cmSourceFile const& source) const;
540
  virtual std::string ComputeShortTargetDirectory(
541
    cmGeneratorTarget const* gt) const;
542
  std::string GetCustomObjectFileName(cmSourceFile const& source) const;
543
  std::string GetCustomInstallObjectFileName(cmSourceFile const& source,
544
                                             std::string const& config,
545
                                             char const* custom_ext) const;
546
  void FillCustomInstallObjectLocations(
547
    cmSourceFile const& source, std::string const& config,
548
    char const* custom_ext,
549
    std::map<std::string, cmObjectLocation>& mapping) const;
550
551
  /**
552
   * Generate a macOS application bundle Info.plist file.
553
   */
554
  void GenerateAppleInfoPList(cmGeneratorTarget* target,
555
                              std::string const& targetName,
556
                              std::string const& fname);
557
558
  /**
559
   * Generate a macOS framework Info.plist file.
560
   */
561
  void GenerateFrameworkInfoPList(cmGeneratorTarget* target,
562
                                  std::string const& targetName,
563
                                  std::string const& fname);
564
  /** Construct a comment for a custom command.  */
565
  std::string ConstructComment(cmCustomCommandGenerator const& ccg,
566
                               char const* default_comment = "") const;
567
  // Computes relative path to source respective to source or binary dir.
568
  std::string GetRelativeSourceFileName(cmSourceFile const& source) const;
569
  // Compute object file names.
570
  std::string GetObjectFileNameWithoutTarget(
571
    cmSourceFile const& source, std::string const& dir_max,
572
    bool* hasSourceExtension = nullptr,
573
    char const* customOutputExtension = nullptr,
574
    bool const* forceShortObjectName = nullptr);
575
576
  /** Fill out the static linker flags for the given target.  */
577
  void GetStaticLibraryFlags(std::string& flags, std::string const& config,
578
                             std::string const& linkLanguage,
579
                             cmGeneratorTarget* target);
580
  std::vector<BT<std::string>> GetStaticLibraryFlags(
581
    std::string const& config, std::string const& linkLanguage,
582
    cmGeneratorTarget* target);
583
584
  /** Fill out these strings for the given target.  Libraries to link,
585
   *  flags, and linkflags. */
586
  void GetDeviceLinkFlags(cmLinkLineDeviceComputer& linkLineComputer,
587
                          std::string const& config, std::string& linkLibs,
588
                          std::string& linkFlags, std::string& frameworkPath,
589
                          std::string& linkPath, cmGeneratorTarget* target);
590
591
  void GetTargetFlags(cmLinkLineComputer* linkLineComputer,
592
                      std::string const& config, std::string& linkLibs,
593
                      std::string& flags, std::string& linkFlags,
594
                      std::string& frameworkPath, std::string& linkPath,
595
                      cmGeneratorTarget* target);
596
  void GetTargetFlags(
597
    cmLinkLineComputer* linkLineComputer, std::string const& config,
598
    std::vector<BT<std::string>>& linkLibs, std::string& flags,
599
    std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath,
600
    std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target);
601
  void GetTargetDefines(cmGeneratorTarget const* target,
602
                        std::string const& config, std::string const& lang,
603
                        std::set<std::string>& defines) const;
604
  std::set<BT<std::string>> GetTargetDefines(cmGeneratorTarget const* target,
605
                                             std::string const& config,
606
                                             std::string const& lang) const;
607
  void GetTargetCompileFlags(cmGeneratorTarget* target,
608
                             std::string const& config,
609
                             std::string const& lang, std::string& flags,
610
                             std::string const& arch);
611
  std::vector<BT<std::string>> GetTargetCompileFlags(
612
    cmGeneratorTarget* target, std::string const& config,
613
    std::string const& lang, std::string const& arch = std::string());
614
615
  std::string GetFrameworkFlags(std::string const& l,
616
                                std::string const& config,
617
                                cmGeneratorTarget* target);
618
  std::string GetXcFrameworkFlags(std::string const& l,
619
                                  std::string const& config,
620
                                  cmGeneratorTarget* target);
621
  virtual std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
622
                                            std::string const& config);
623
624
  virtual void ComputeObjectFilenames(
625
    std::map<cmSourceFile const*, cmObjectLocations>& mapping,
626
    std::string const& config, cmGeneratorTarget const* gt = nullptr);
627
628
  bool IsWindowsShell() const;
629
  bool IsWatcomWMake() const;
630
  bool IsMinGWMake() const;
631
  bool IsNMake() const;
632
  bool IsNinjaMulti() const;
633
  bool IsWindowsVSIDE() const;
634
635
  void IssueMessage(MessageType type, std::string const& text) const
636
0
  {
637
0
    this->IssueMessage(type, text, this->DirectoryBacktrace);
638
0
  }
639
  void IssueMessage(MessageType type, std::string const& text,
640
                    cmListFileBacktrace const& bt) const;
641
  void IssueDiagnostic(cmDiagnosticCategory category,
642
                       std::string const& text) const
643
0
  {
644
0
    this->IssueDiagnostic(category, text,
645
0
                          cmDiagnosticContext{ this->DirectoryBacktrace });
646
0
  }
647
  void IssueDiagnostic(cmDiagnosticCategory category, std::string const& text,
648
                       cmListFileBacktrace const& bt) const
649
0
  {
650
0
    this->IssueDiagnostic(category, text, cmDiagnosticContext{ bt });
651
0
  }
652
  void IssueDiagnostic(cmDiagnosticCategory category, std::string const& text,
653
                       cmDiagnosticContext const& context) const;
654
  void IssuePolicyWarning(cmPolicies::PolicyID policy, cm::string_view preface,
655
                          cm::string_view postface,
656
                          cmListFileBacktrace const& bt) const;
657
  void IssuePolicyWarning(cmPolicies::PolicyID policy,
658
                          cm::string_view preface = {},
659
                          cm::string_view postface = {}) const
660
0
  {
661
0
    this->IssuePolicyWarning(policy, preface, postface,
662
0
                             this->DirectoryBacktrace);
663
0
  }
664
665
  void CreateEvaluationFileOutputs();
666
  void CreateEvaluationFileOutputs(std::string const& config);
667
  void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
668
669
  std::string GetRuleLauncher(cmGeneratorTarget* target,
670
                              std::string const& prop,
671
                              std::string const& config);
672
673
  // Return Swift_COMPILATION_MODE value if CMP0157 is NEW.
674
  cm::optional<cmSwiftCompileMode> GetSwiftCompileMode(
675
    cmGeneratorTarget const* target, std::string const& config);
676
677
  // Can we build Swift with a separate object build and link step
678
  // (If CMP0157 is NEW, we can do a split build)
679
  bool IsSplitSwiftBuild() const;
680
681
  std::string CreateSafeObjectFileName(std::string const& sin) const;
682
683
  /**
684
   * find what source group this source is in
685
   */
686
  cmSourceGroup* FindSourceGroup(cmGeneratorTarget const* target,
687
                                 cmSourceFile const* source,
688
                                 std::string const& config);
689
  cmSourceGroup* FindSourceGroup(std::string const& source);
690
691
protected:
692
  // The default implementation converts to a Windows shortpath to
693
  // help older toolchains handle spaces and such.  A generator may
694
  // override this to avoid that conversion.
695
  virtual std::string ConvertToIncludeReference(
696
    std::string const& path, cmOutputConverter::OutputFormat format);
697
698
  //! put all the libraries for a target on into the given stream
699
  void OutputLinkLibraries(cmComputeLinkInformation* pcli,
700
                           cmLinkLineComputer* linkLineComputer,
701
                           std::string& linkLibraries,
702
                           std::string& frameworkPath, std::string& linkPath);
703
  void OutputLinkLibraries(cmComputeLinkInformation* pcli,
704
                           cmLinkLineComputer* linkLineComputer,
705
                           std::vector<BT<std::string>>& linkLibraries,
706
                           std::string& frameworkPath,
707
                           std::vector<BT<std::string>>& linkPath);
708
709
  // Handle old-style install rules stored in the targets.
710
  void GenerateTargetInstallRules(
711
    std::ostream& os, std::string const& config,
712
    std::vector<std::string> const& configurationTypes);
713
714
0
  virtual void AddGeneratorSpecificInstallSetup(std::ostream&) {}
715
716
  std::string& CreateSafeUniqueObjectFileName(std::string const& sin,
717
                                              std::string const& dir_max);
718
719
  /** Check whether the native build system supports the given
720
      definition.  Issues a warning.  */
721
  virtual bool CheckDefinition(std::string const& define) const;
722
723
  cmMakefile* Makefile;
724
  cmListFileBacktrace DirectoryBacktrace;
725
  cmGlobalGenerator* GlobalGenerator;
726
  std::map<std::string, std::string> UniqueObjectNamesMap;
727
  std::string::size_type ObjectPathMax;
728
  std::set<std::string> ObjectMaxPathViolations;
729
730
  std::vector<std::string> EnvCPATH;
731
732
  using GeneratorTargetMap =
733
    std::unordered_map<std::string, cmGeneratorTarget*>;
734
  GeneratorTargetMap GeneratorTargetSearchIndex;
735
  GeneratorTargetVector GeneratorTargets;
736
737
  GeneratorTargetMap ImportedGeneratorTargets;
738
  GeneratorTargetVector OwnedImportedGeneratorTargets;
739
  std::map<std::string, std::string> AliasTargets;
740
741
  using GeneratorRuleMap = std::unordered_map<std::string, cmGeneratorRule*>;
742
  GeneratorRuleMap GeneratorRuleSearchIndex;
743
  using GeneratorRuleVector = std::vector<std::unique_ptr<cmGeneratorRule>>;
744
  GeneratorRuleVector GeneratorRules;
745
746
  std::map<std::string, std::string> Compilers;
747
  std::map<std::string, std::string> VariableMappings;
748
  std::string CompilerSysroot;
749
  std::string LinkerSysroot;
750
  std::unordered_map<std::string, std::string> AppleArchSysroots;
751
752
  bool EmitUniversalBinaryFlags;
753
754
#if !defined(CMAKE_BOOTSTRAP)
755
  // Map from source file path to source group for lookup acceleration
756
  using SourceGroupMap = std::unordered_map<std::string, cmSourceGroup*>;
757
  SourceGroupMap SourceGroupSearchIndex;
758
#endif
759
760
private:
761
  std::map<std::string, std::vector<DirectoryTestPrepDependency>>
762
    DiscoveryTestPrepDependencies;
763
  /**
764
   * See LinearGetSourceFileWithOutput for background information
765
   */
766
  cmTarget* LinearGetTargetWithOutput(std::string const& name) const;
767
768
  /**
769
   * Generalized old version of GetSourceFileWithOutput kept for
770
   * backward-compatibility. It implements a linear search and supports
771
   * relative file paths. It is used as a fall back by GetSourceFileWithOutput
772
   * and GetSourcesWithOutput.
773
   */
774
  cmSourceFile* LinearGetSourceFileWithOutput(std::string const& name,
775
                                              cmSourceOutputKind kind,
776
                                              bool& byproduct) const;
777
  struct SourceEntry
778
  {
779
    cmSourcesWithOutput Sources;
780
  };
781
782
  // A map for fast output to input look up.
783
  using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>;
784
  OutputToSourceMap OutputToSource;
785
786
  void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target,
787
                               cmListFileBacktrace const& bt,
788
                               cmCommandOrigin origin);
789
  void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source,
790
                               OutputRole role, cmListFileBacktrace const& bt,
791
                               cmCommandOrigin origin);
792
793
  void AddPositionIndependentFlags(std::string& flags, std::string const& l,
794
                                   cm::TargetType targetType);
795
796
  void ComputeObjectMaxPath();
797
  bool AllAppleArchSysrootsAreTheSame(std::vector<std::string> const& archs,
798
                                      cmValue sysroot);
799
800
  void CopyPchCompilePdb(std::string const& config,
801
                         std::string const& language,
802
                         cmGeneratorTarget* target,
803
                         cmGeneratorTarget* reuseTarget,
804
                         std::vector<std::string> const& extensions);
805
806
  // Returns MSVC_DEBUG_INFORMATION_FORMAT value if CMP0141 is NEW.
807
  cm::optional<std::string> GetMSVCDebugFormatName(
808
    std::string const& config, cmGeneratorTarget const* target);
809
810
  struct UnityBatchedSource
811
  {
812
    cmSourceFile* Source = nullptr;
813
    std::vector<size_t> Configs;
814
    UnityBatchedSource(cmSourceFile* sf)
815
0
      : Source(sf)
816
0
    {
817
0
    }
818
  };
819
  struct UnitySource
820
  {
821
    std::string Path;
822
    bool PerConfig = false;
823
    UnitySource(std::string path, bool perConfig)
824
0
      : Path(std::move(path))
825
0
      , PerConfig(perConfig)
826
0
    {
827
0
    }
828
  };
829
  /** Whether to insert relative or absolute paths into unity files */
830
  enum class UnityPathMode
831
  {
832
    Absolute,
833
    Relative
834
  };
835
836
  UnitySource WriteUnitySource(
837
    cmGeneratorTarget* target, std::vector<std::string> const& configs,
838
    cmRange<std::vector<UnityBatchedSource>::const_iterator> sources,
839
    cmValue beforeInclude, cmValue afterInclude, std::string filename,
840
    std::string const& unityFileDirectory, UnityPathMode pathMode) const;
841
  void WriteUnitySourceInclude(std::ostream& unity_file,
842
                               cm::optional<std::string> const& cond,
843
                               std::string const& sf_full_path,
844
                               cmValue beforeInclude, cmValue afterInclude,
845
                               cmValue uniqueIdName, UnityPathMode pathMode,
846
                               std::string const& unityFileDirectory) const;
847
  std::vector<UnitySource> AddUnityFilesModeAuto(
848
    cmGeneratorTarget* target, std::string const& lang,
849
    std::vector<std::string> const& configs,
850
    std::vector<UnityBatchedSource> const& filtered_sources,
851
    cmValue beforeInclude, cmValue afterInclude,
852
    std::string const& filename_base, UnityPathMode pathMode,
853
    size_t batchSize);
854
  std::vector<UnitySource> AddUnityFilesModeGroup(
855
    cmGeneratorTarget* target, std::string const& lang,
856
    std::vector<std::string> const& configs,
857
    std::vector<UnityBatchedSource> const& filtered_sources,
858
    cmValue beforeInclude, cmValue afterInclude,
859
    std::string const& filename_base, UnityPathMode pathMode);
860
};
861
862
namespace detail {
863
void AddCustomCommandToTarget(cmLocalGenerator& lg, cmCommandOrigin origin,
864
                              cmTarget* target, cmCustomCommandType type,
865
                              std::unique_ptr<cmCustomCommand> cc);
866
867
cmSourceFile* AddCustomCommandToOutput(cmLocalGenerator& lg,
868
                                       cmCommandOrigin origin,
869
                                       std::unique_ptr<cmCustomCommand> cc,
870
                                       bool replace);
871
872
void AppendCustomCommandToOutput(cmLocalGenerator& lg,
873
                                 cmListFileBacktrace const& lfbt,
874
                                 std::string const& output,
875
                                 std::vector<std::string> const& depends,
876
                                 cmImplicitDependsList const& implicit_depends,
877
                                 cmCustomCommandLines const& commandLines);
878
879
void AddUtilityCommand(cmLocalGenerator& lg, cmCommandOrigin origin,
880
                       cmTarget* target, std::unique_ptr<cmCustomCommand> cc);
881
882
std::vector<std::string> ComputeISPCObjectSuffixes(cmGeneratorTarget* target);
883
std::vector<std::string> ComputeISPCExtraObjects(
884
  std::string const& objectName, std::string const& buildDirectory,
885
  std::vector<std::string> const& ispcSuffixes);
886
}