Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmGeneratorTarget.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 <functional>
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 "cmAlgorithms.h"
22
#include "cmLinkItem.h"
23
#include "cmList.h"
24
#include "cmListFileCache.h"
25
#include "cmObjectLocation.h"
26
#include "cmPolicies.h"
27
#include "cmSourceFile.h"
28
#include "cmStandardLevel.h"
29
#include "cmStateTypes.h"
30
#include "cmTargetPropertyEntry.h"
31
#include "cmValue.h"
32
33
namespace cm {
34
namespace GenEx {
35
struct Context;
36
struct Evaluation;
37
}
38
}
39
40
enum class cmBuildStep;
41
class cmComputeLinkInformation;
42
class cmCustomCommand;
43
class cmGeneratorFileSets;
44
class cmGeneratorFileSet;
45
class cmGlobalGenerator;
46
class cmLocalGenerator;
47
class cmMakefile;
48
struct cmSyntheticTargetCache;
49
class cmTarget;
50
51
struct cmGeneratorExpressionDAGChecker;
52
53
class cmGeneratorTarget
54
{
55
public:
56
  using TargetPropertyEntry = cm::TargetPropertyEntry;
57
58
  cmGeneratorTarget(cmTarget*, cmLocalGenerator* lg);
59
  ~cmGeneratorTarget();
60
61
  cmGeneratorTarget(cmGeneratorTarget const&) = delete;
62
  cmGeneratorTarget& operator=(cmGeneratorTarget const&) = delete;
63
64
  cmLocalGenerator* GetLocalGenerator() const;
65
66
  cmGlobalGenerator* GetGlobalGenerator() const;
67
68
  bool IsInBuildSystem() const;
69
  bool IsNormal() const;
70
  bool IsRuntimeBinary() const;
71
  bool IsSynthetic() const;
72
  bool IsImported() const;
73
  bool IsImportedGloballyVisible() const;
74
  bool IsForeign() const;
75
  bool IsSymbolic() const;
76
  bool CanCompileSources() const;
77
  bool HasKnownRuntimeArtifactLocation(std::string const& config) const;
78
  std::string const& GetLocation(std::string const& config) const;
79
80
  /** Get the full path to the target's main artifact, if known.  */
81
  cm::optional<std::string> MaybeGetLocation(std::string const& config) const;
82
83
  std::vector<cmCustomCommand> const& GetPreBuildCommands() const;
84
  std::vector<cmCustomCommand> const& GetPreLinkCommands() const;
85
  std::vector<cmCustomCommand> const& GetPostBuildCommands() const;
86
87
  void AppendCustomCommandSideEffects(
88
    std::set<cmGeneratorTarget const*>& sideEffects) const;
89
  void AppendLanguageSideEffects(
90
    std::map<std::string, std::set<cmGeneratorTarget const*>>& sideEffects)
91
    const;
92
93
#define DECLARE_TARGET_POLICY(POLICY)                                         \
94
  cmPolicies::PolicyStatus GetPolicyStatus##POLICY() const                    \
95
0
  {                                                                           \
96
0
    return this->PolicyMap.Get(cmPolicies::POLICY);                           \
97
0
  }
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0003() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0004() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0008() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0020() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0021() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0022() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0027() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0037() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0038() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0041() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0042() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0046() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0052() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0060() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0063() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0065() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0068() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0069() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0073() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0076() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0081() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0083() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0095() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0099() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0104() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0105() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0108() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0112() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0113() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0119() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0131() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0142() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0154() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0155() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0156() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0157() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0160() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0162() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0179() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0181() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0182() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0195() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0199() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0200() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0202() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0203() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0204() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0209() const
Unexecuted instantiation: cmGeneratorTarget::GetPolicyStatusCMP0210() const
98
99
  CM_FOR_EACH_TARGET_POLICY(DECLARE_TARGET_POLICY)
100
101
#undef DECLARE_TARGET_POLICY
102
103
  /** Get the location of the target in the build tree with a placeholder
104
      referencing the configuration in the native build system.  This
105
      location is suitable for use as the LOCATION target property.  */
106
  std::string const& GetLocationForBuild() const;
107
108
  cmComputeLinkInformation* GetLinkInformation(
109
    std::string const& config) const;
110
111
  // Perform validation checks on memoized link structures.
112
  // Call this after generation is complete.
113
  void CheckLinkLibraries() const;
114
115
  class CheckLinkLibrariesSuppressionRAII
116
  {
117
  public:
118
    CheckLinkLibrariesSuppressionRAII();
119
    ~CheckLinkLibrariesSuppressionRAII();
120
  };
121
122
  cmStateEnums::TargetType GetType() const;
123
  std::string const& GetName() const;
124
  std::string GetFamilyName() const;
125
  std::string GetExportName() const;
126
  std::string GetFilesystemExportName() const;
127
128
  std::vector<std::string> GetPropertyKeys() const;
129
  //! Might return a nullptr if the property is not set or invalid
130
  cmValue GetProperty(std::string const& prop) const;
131
  //! Always returns a valid pointer
132
  std::string const& GetSafeProperty(std::string const& prop) const;
133
  bool GetPropertyAsBool(std::string const& prop) const;
134
  void GetSourceFiles(std::vector<cmSourceFile*>& files,
135
                      std::string const& config) const;
136
  std::vector<BT<cmSourceFile*>> GetSourceFiles(
137
    std::string const& config) const;
138
139
  /** Source file kinds (classifications).
140
      Generators use this to decide how to treat a source file.  */
141
  enum SourceKind
142
  {
143
    SourceKindAppManifest,
144
    SourceKindCertificate,
145
    SourceKindCustomCommand,
146
    SourceKindExternalObject,
147
    SourceKindCxxModuleSource,
148
    SourceKindExtra,
149
    SourceKindHeader,
150
    SourceKindIDL,
151
    SourceKindManifest,
152
    SourceKindModuleDefinition,
153
    SourceKindObjectSource,
154
    SourceKindResx,
155
    SourceKindXaml,
156
    SourceKindUnityBatched
157
  };
158
159
  /** A source file paired with a kind (classification).  */
160
  struct SourceAndKind
161
  {
162
    BT<cmSourceFile*> Source;
163
    SourceKind Kind;
164
  };
165
166
  /** All sources needed for a configuration with kinds assigned.  */
167
  struct KindedSources
168
  {
169
    std::vector<SourceAndKind> Sources;
170
    bool Initialized = false;
171
  };
172
173
  /** Get all sources needed for a configuration with kinds assigned.  */
174
  KindedSources const& GetKindedSources(std::string const& config) const;
175
176
  struct AllConfigSource
177
  {
178
    cmSourceFile* Source;
179
    cmGeneratorTarget::SourceKind Kind;
180
    std::vector<size_t> Configs;
181
  };
182
183
  /** Get all sources needed for all configurations with kinds and
184
      per-source configurations assigned.  */
185
  std::vector<AllConfigSource> const& GetAllConfigSources() const;
186
187
  /** Get all sources needed for all configurations with given kind.  */
188
  std::vector<AllConfigSource> GetAllConfigSources(SourceKind kind) const;
189
190
  /** Get all languages used to compile sources in any configuration.
191
      This excludes the languages of objects from object libraries.  */
192
  std::set<std::string> GetAllConfigCompileLanguages() const;
193
194
  void GetObjectSources(std::vector<cmSourceFile const*>&,
195
                        std::string const& config) const;
196
  std::string const& GetObjectName(cmSourceFile const* file);
197
  char const* GetCustomObjectExtension() const;
198
199
  bool HasExplicitObjectName(cmSourceFile const* file) const;
200
  void AddExplicitObjectName(cmSourceFile const* sf);
201
202
  BTs<std::string> const* GetLanguageStandardProperty(
203
    std::string const& lang, std::string const& config) const;
204
205
  cmValue GetLanguageStandard(std::string const& lang,
206
                              std::string const& config) const;
207
208
  cmValue GetLanguageExtensions(std::string const& lang) const;
209
210
  bool GetLanguageStandardRequired(std::string const& lang) const;
211
212
  void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&,
213
                                  std::string const& config) const;
214
  void GetExternalObjects(std::vector<cmSourceFile const*>&,
215
                          std::string const& config) const;
216
  void GetHeaderSources(std::vector<cmSourceFile const*>&,
217
                        std::string const& config) const;
218
  void GetCxxModuleSources(std::vector<cmSourceFile const*>&,
219
                           std::string const& config) const;
220
  void GetExtraSources(std::vector<cmSourceFile const*>&,
221
                       std::string const& config) const;
222
  void GetCustomCommands(std::vector<cmSourceFile const*>&,
223
                         std::string const& config) const;
224
  void GetManifests(std::vector<cmSourceFile const*>&,
225
                    std::string const& config) const;
226
227
  std::set<cmLinkItem> const& GetUtilityItems() const;
228
229
  void ComputeObjectMapping();
230
231
  cmValue GetFeature(std::string const& feature,
232
                     std::string const& config) const;
233
234
  std::string GetLinkerTypeProperty(std::string const& lang,
235
                                    std::string const& config) const;
236
237
  char const* GetLinkPIEProperty(std::string const& config) const;
238
239
  bool IsIPOEnabled(std::string const& lang, std::string const& config) const;
240
241
  bool IsLinkInterfaceDependentBoolProperty(std::string const& p,
242
                                            std::string const& config) const;
243
  bool IsLinkInterfaceDependentStringProperty(std::string const& p,
244
                                              std::string const& config) const;
245
  bool IsLinkInterfaceDependentNumberMinProperty(
246
    std::string const& p, std::string const& config) const;
247
  bool IsLinkInterfaceDependentNumberMaxProperty(
248
    std::string const& p, std::string const& config) const;
249
250
  bool GetLinkInterfaceDependentBoolProperty(std::string const& p,
251
                                             std::string const& config) const;
252
253
  char const* GetLinkInterfaceDependentStringProperty(
254
    std::string const& p, std::string const& config) const;
255
  char const* GetLinkInterfaceDependentNumberMinProperty(
256
    std::string const& p, std::string const& config) const;
257
  char const* GetLinkInterfaceDependentNumberMaxProperty(
258
    std::string const& p, std::string const& config) const;
259
260
  class DeviceLinkSetter
261
  {
262
  public:
263
    DeviceLinkSetter(cmGeneratorTarget& target)
264
0
      : Target(target)
265
0
    {
266
0
      this->PreviousState = target.SetDeviceLink(true);
267
0
    }
268
0
    ~DeviceLinkSetter() { this->Target.SetDeviceLink(this->PreviousState); }
269
270
  private:
271
    cmGeneratorTarget& Target;
272
    bool PreviousState;
273
  };
274
275
  bool SetDeviceLink(bool deviceLink);
276
0
  bool IsDeviceLink() const { return this->DeviceLink; }
277
278
  cmLinkInterface const* GetLinkInterface(
279
    std::string const& config, cmGeneratorTarget const* headTarget) const;
280
281
  enum class UseTo
282
  {
283
    Compile, // Usage requirements for compiling.  Excludes $<LINK_ONLY>.
284
    Link,    // Usage requirements for linking.  Includes $<LINK_ONLY>.
285
  };
286
287
  cmLinkInterfaceLibraries const* GetLinkInterfaceLibraries(
288
    std::string const& config, cmGeneratorTarget const* headTarget,
289
    UseTo usage) const;
290
291
  void ComputeLinkInterfaceLibraries(std::string const& config,
292
                                     cmOptionalLinkInterface& iface,
293
                                     cmGeneratorTarget const* head,
294
                                     UseTo usage) const;
295
296
  /** Get the library name for an imported interface library.  */
297
  std::string GetImportedLibName(std::string const& config) const;
298
299
  /** Get the full path to the target according to the settings in its
300
      makefile and the configuration type.  */
301
  std::string GetFullPath(
302
    std::string const& config,
303
    cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact,
304
    bool realname = false) const;
305
  std::string NormalGetFullPath(std::string const& config,
306
                                cmStateEnums::ArtifactType artifact,
307
                                bool realname) const;
308
  std::string NormalGetRealName(std::string const& config,
309
                                cmStateEnums::ArtifactType artifact =
310
                                  cmStateEnums::RuntimeBinaryArtifact) const;
311
312
  /** Get the names of an object library's object files underneath
313
      its object file directory for the build.  */
314
  void GetTargetObjectNames(std::string const& config,
315
                            std::vector<std::string>& objects) const;
316
  void GetTargetObjectNames(std::string const& config,
317
                            std::function<bool(cmSourceFile const&)> filter,
318
                            std::vector<std::string>& objects) const;
319
  /** Get the build and install locations of objects for a given context. */
320
  void GetTargetObjectLocations(
321
    std::string const& config,
322
    std::function<void(cmObjectLocation const&, cmObjectLocation const&)> cb)
323
    const;
324
  void GetTargetObjectLocations(
325
    std::string const& config, std::function<bool(cmSourceFile const&)> filter,
326
    std::function<void(cmObjectLocation const&, cmObjectLocation const&)> cb)
327
    const;
328
329
  /** What hierarchy level should the reported directory contain */
330
  enum BundleDirectoryLevel
331
  {
332
    BundleDirLevel,
333
    ContentLevel,
334
    FullLevel
335
  };
336
337
  /** @return the Mac App directory without the base */
338
  std::string GetAppBundleDirectory(std::string const& config,
339
                                    BundleDirectoryLevel level) const;
340
341
  /** Return whether this target is marked as deprecated by the
342
      maintainer  */
343
  bool IsDeprecated() const;
344
345
  /** Returns the deprecation message provided by the maintainer */
346
  std::string GetDeprecation() const;
347
348
  /** Return whether this target is an executable Bundle, a framework
349
      or CFBundle on Apple.  */
350
  bool IsBundleOnApple() const;
351
352
  /** Return whether this target is a Win32 executable */
353
  bool IsWin32Executable(std::string const& config) const;
354
355
  /** Get the full name of the target according to the settings in its
356
      makefile.  */
357
  std::string GetFullName(std::string const& config,
358
                          cmStateEnums::ArtifactType artifact =
359
                            cmStateEnums::RuntimeBinaryArtifact) const;
360
361
  /** @return the Mac framework directory without the base. */
362
  std::string GetFrameworkDirectory(std::string const& config,
363
                                    BundleDirectoryLevel level) const;
364
365
  /** Return the framework version string.  Undefined if
366
      IsFrameworkOnApple returns false.  */
367
  std::string GetFrameworkVersion() const;
368
369
  /** @return the Mac CFBundle directory without the base */
370
  std::string GetCFBundleDirectory(std::string const& config,
371
                                   BundleDirectoryLevel level) const;
372
373
  /** Return the install name directory for the target in the
374
   * build tree.  For example: "\@rpath/", "\@loader_path/",
375
   * or "/full/path/to/library".  */
376
  std::string GetInstallNameDirForBuildTree(std::string const& config) const;
377
378
  /** Return the install name directory for the target in the
379
   * install tree.  For example: "\@rpath/" or "\@loader_path/". */
380
  std::string GetInstallNameDirForInstallTree(
381
    std::string const& config, std::string const& installPrefix) const;
382
383
  cmListFileBacktrace GetBacktrace() const;
384
385
  std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
386
387
  bool LinkLanguagePropagatesToDependents() const
388
0
  {
389
0
    return this->GetType() == cmStateEnums::STATIC_LIBRARY;
390
0
  }
391
392
  /** Get the macro to define when building sources in this target.
393
      If no macro should be defined null is returned.  */
394
  std::string const* GetExportMacro() const;
395
396
  /** Get the list of preprocessor definitions, that should be defined
397
      when building sources in this target.
398
      If no macro should be defined the empty list is returned.  */
399
  cmList const& GetSharedLibraryCompileDefs(std::string const& config) const;
400
401
  /** Get the soname of the target.  Allowed only for a shared library.  */
402
  std::string GetSOName(std::string const& config,
403
                        cmStateEnums::ArtifactType artifact =
404
                          cmStateEnums::RuntimeBinaryArtifact) const;
405
406
  struct NameComponents
407
  {
408
    std::string prefix;
409
    std::string base;
410
    std::string suffix;
411
  };
412
  NameComponents const& GetFullNameComponents(
413
    std::string const& config,
414
    cmStateEnums::ArtifactType artifact =
415
      cmStateEnums::RuntimeBinaryArtifact) const;
416
417
  /** Append to @a base the bundle directory hierarchy up to a certain @a level
418
   * and return it. */
419
  std::string BuildBundleDirectory(std::string const& base,
420
                                   std::string const& config,
421
                                   BundleDirectoryLevel level) const;
422
423
  /** @return the mac content directory for this target. */
424
  std::string GetMacContentDirectory(
425
    std::string const& config, cmStateEnums::ArtifactType artifact) const;
426
427
  /** @return folder prefix for IDEs. */
428
  std::string GetEffectiveFolderName() const;
429
430
  cmTarget* Target;
431
  cmMakefile* Makefile;
432
  cmLocalGenerator* LocalGenerator;
433
  cmGlobalGenerator const* GlobalGenerator;
434
435
  std::string targetLabelsString;
436
437
  struct ModuleDefinitionInfo
438
  {
439
    std::string DefFile;
440
    bool DefFileGenerated;
441
    bool WindowsExportAllSymbols;
442
    std::vector<cmSourceFile const*> Sources;
443
  };
444
  ModuleDefinitionInfo const* GetModuleDefinitionInfo(
445
    std::string const& config) const;
446
447
  /** Return whether or not we are targeting AIX. */
448
  bool IsAIX() const;
449
  /** Return whether or not we are targeting Apple. */
450
  bool IsApple() const;
451
452
  /** Return whether or not the target is for a DLL platform.  */
453
  bool IsDLLPlatform() const;
454
455
  /** @return whether this target have a well defined output file name. */
456
  bool HaveWellDefinedOutputFiles() const;
457
458
  /** Link information from the transitive closure of the link
459
      implementation and the interfaces of its dependencies.  */
460
  struct LinkClosure
461
  {
462
    // The preferred linker language.
463
    std::string LinkerLanguage;
464
465
    // Languages whose runtime libraries must be linked.
466
    std::vector<std::string> Languages;
467
  };
468
469
  LinkClosure const* GetLinkClosure(std::string const& config) const;
470
471
  cmLinkImplementation const* GetLinkImplementation(std::string const& config,
472
                                                    UseTo usage) const;
473
474
  void ComputeLinkImplementationLanguages(
475
    std::string const& config, cmOptionalLinkImplementation& impl) const;
476
477
  cmLinkImplementationLibraries const* GetLinkImplementationLibraries(
478
    std::string const& config, UseTo usage) const;
479
480
  void ComputeLinkImplementationLibraries(std::string const& config,
481
                                          cmOptionalLinkImplementation& impl,
482
                                          UseTo usage) const;
483
484
  struct TargetOrString
485
  {
486
    std::string String;
487
    cmGeneratorTarget* Target = nullptr;
488
  };
489
  TargetOrString ResolveTargetReference(std::string const& name) const;
490
  TargetOrString ResolveTargetReference(std::string const& name,
491
                                        cmLocalGenerator const* lg) const;
492
493
  cmLinkItem ResolveLinkItem(
494
    BT<std::string> const& name,
495
    std::string const& linkFeature = cmLinkItem::DEFAULT) const;
496
  cmLinkItem ResolveLinkItem(
497
    BT<std::string> const& name, cmLocalGenerator const* lg,
498
    std::string const& linkFeature = cmLinkItem::DEFAULT) const;
499
500
  bool HasPackageReferences() const;
501
  std::vector<std::string> GetPackageReferences() const;
502
503
  // Compute the set of languages compiled by the target.  This is
504
  // computed every time it is called because the languages can change
505
  // when source file properties are changed and we do not have enough
506
  // information to forward these property changes to the targets
507
  // until we have per-target object file properties.
508
  void GetLanguages(std::set<std::string>& languages,
509
                    std::string const& config) const;
510
  bool IsLanguageUsed(std::string const& language,
511
                      std::string const& config) const;
512
513
  // Get the set of targets directly referenced via `TARGET_OBJECTS` in the
514
  // source list for a configuration.
515
  std::set<cmGeneratorTarget const*> GetSourceObjectLibraries(
516
    std::string const& config) const;
517
518
  bool IsCSharpOnly() const;
519
520
  bool IsDotNetSdkTarget() const;
521
522
  void GetObjectLibrariesInSources(
523
    std::vector<BT<cmGeneratorTarget*>>& objlibs) const;
524
525
  std::string GetFullNameImported(std::string const& config,
526
                                  cmStateEnums::ArtifactType artifact) const;
527
528
  /** Get source files common to all configurations and diagnose cases
529
      with per-config sources.  Excludes sources added by a TARGET_OBJECTS
530
      generator expression.  Do not use outside the Xcode generator.  */
531
  bool GetConfigCommonSourceFilesForXcode(
532
    std::vector<cmSourceFile*>& files) const;
533
534
  bool HaveBuildTreeRPATH(std::string const& config) const;
535
536
  /** Full path with trailing slash to the top-level directory
537
      holding object files for this target.  Includes the build
538
      time config name placeholder if needed for the generator.  */
539
  std::string ObjectDirectory;
540
541
  /** Full path with trailing slash to the top-level directory
542
      holding object files for the given configuration.  */
543
  std::string GetObjectDirectory(std::string const& config) const;
544
545
  std::vector<std::string> GetAppleArchs(std::string const& config,
546
                                         cm::optional<std::string> lang) const;
547
548
  // The classification of the flag.
549
  enum class FlagClassification
550
  {
551
    // The flag is for the execution of the tool (e.g., the compiler itself,
552
    // any launchers, etc.).
553
    ExecutionFlag,
554
    // The flag is "baseline" and should be apply to TUs which may interact
555
    // with this compilation (e.g., imported modules).
556
    BaselineFlag,
557
    // The flag is "private" and doesn't need to apply to interacting TUs.
558
    PrivateFlag,
559
    // Flags for the TU itself (e.g., output paths, dependency scanning, etc.).
560
    LocationFlag,
561
  };
562
  enum class FlagKind
563
  {
564
    // Not a flag (executable or other entries).
565
    NotAFlag,
566
    // Flags for support of the build system.
567
    BuildSystem,
568
    // A compilation flag.
569
    Compile,
570
    // An include flag.
571
    Include,
572
    // A compile definition.
573
    Definition,
574
  };
575
  struct ClassifiedFlag
576
  {
577
    ClassifiedFlag(FlagClassification cls, FlagKind kind, std::string flag)
578
0
      : Classification(cls)
579
0
      , Kind(kind)
580
0
      , Flag(std::move(flag))
581
0
    {
582
0
    }
583
584
    FlagClassification Classification;
585
    FlagKind Kind;
586
    std::string Flag;
587
  };
588
  using ClassifiedFlags = std::vector<ClassifiedFlag>;
589
  ClassifiedFlags GetClassifiedFlagsForSource(cmSourceFile const* sf,
590
                                              std::string const& config);
591
  struct SourceVariables
592
  {
593
    std::string TargetPDB;
594
    std::string TargetCompilePDB;
595
    std::string ObjectDir;
596
    std::string TargetSupportDir;
597
    std::string ObjectFileDir;
598
    std::string DependencyFile;
599
    std::string DependencyTarget;
600
601
    // Dependency flags (if used)
602
    std::string DependencyFlags;
603
  };
604
  SourceVariables GetSourceVariables(cmSourceFile const* sf,
605
                                     std::string const& config);
606
607
  void AddExplicitLanguageFlags(std::string& flags,
608
                                cmSourceFile const& sf) const;
609
610
  void AddCUDAArchitectureFlags(cmBuildStep compileOrLink,
611
                                std::string const& config,
612
                                std::string& flags) const;
613
  void AddCUDAArchitectureFlagsImpl(cmBuildStep compileOrLink,
614
                                    std::string const& config,
615
                                    std::string const& lang, std::string arch,
616
                                    std::string& flags) const;
617
  void AddCUDAToolkitFlags(std::string& flags) const;
618
619
  void AddHIPArchitectureFlags(cmBuildStep compileOrLink,
620
                               std::string const& config,
621
                               std::string& flags) const;
622
623
  void AddISPCTargetFlags(std::string& flags) const;
624
625
  std::string GetFeatureSpecificLinkRuleVariable(
626
    std::string const& var, std::string const& lang,
627
    std::string const& config) const;
628
629
  /** Return the rule variable used to create this type of target.  */
630
  std::string GetCreateRuleVariable(std::string const& lang,
631
                                    std::string const& config) const;
632
633
  std::string GetClangTidyExportFixesDirectory(std::string const& lang) const;
634
635
  /** Return the swift module name for this target. */
636
  std::string GetSwiftModuleName() const;
637
638
  /** Return the path of the `.swiftmodule` for this target in
639
      the given configuration.  */
640
  std::string GetSwiftModulePath(std::string const& config) const;
641
642
  /** Return the directory containing Swift module interface
643
      descriptions for this target (including its `.swiftmodule`,
644
      `.abi.json`, and `.swiftdoc`) in the given configuration.  */
645
  std::string GetSwiftModuleDirectory(std::string const& config) const;
646
647
private:
648
  /** Return the given property of this target if it exists; otherwise
649
      return defaultValue. */
650
  std::string GetPropertyOrDefault(std::string const& property,
651
                                   std::string defaultValue) const;
652
653
  /** Return the name of the `.swiftmodule` file for this target. */
654
  std::string GetSwiftModuleFileName() const;
655
656
  using ConfigAndLanguage = std::pair<std::string, std::string>;
657
  using ConfigAndLanguageToBTStrings =
658
    std::map<ConfigAndLanguage, std::vector<BT<std::string>>>;
659
  mutable ConfigAndLanguageToBTStrings IncludeDirectoriesCache;
660
  mutable ConfigAndLanguageToBTStrings CompileOptionsCache;
661
  mutable ConfigAndLanguageToBTStrings CompileDefinitionsCache;
662
  mutable ConfigAndLanguageToBTStrings PrecompileHeadersCache;
663
  mutable ConfigAndLanguageToBTStrings LinkOptionsCache;
664
  mutable ConfigAndLanguageToBTStrings LinkDirectoriesCache;
665
666
public:
667
  /** Get the include directories for this target.  */
668
  std::vector<BT<std::string>> GetIncludeDirectories(
669
    std::string const& config, std::string const& lang) const;
670
671
  void GetCompileOptions(std::vector<std::string>& result,
672
                         std::string const& config,
673
                         std::string const& language) const;
674
  std::vector<BT<std::string>> GetCompileOptions(
675
    std::string const& config, std::string const& language) const;
676
677
  void GetCompileFeatures(std::vector<std::string>& features,
678
                          std::string const& config) const;
679
  std::vector<BT<std::string>> GetCompileFeatures(
680
    std::string const& config) const;
681
682
  void GetCompileDefinitions(std::vector<std::string>& result,
683
                             std::string const& config,
684
                             std::string const& language) const;
685
  std::vector<BT<std::string>> GetCompileDefinitions(
686
    std::string const& config, std::string const& language) const;
687
688
  void GetLinkOptions(std::vector<std::string>& result,
689
                      std::string const& config,
690
                      std::string const& language) const;
691
  std::vector<BT<std::string>> GetLinkOptions(
692
    std::string const& config, std::string const& language) const;
693
694
  std::vector<BT<std::string>>& ResolveLinkerWrapper(
695
    std::vector<BT<std::string>>& result, std::string const& language,
696
    bool joinItems = false) const;
697
698
  void GetStaticLibraryLinkOptions(std::vector<std::string>& result,
699
                                   std::string const& config,
700
                                   std::string const& language) const;
701
  std::vector<BT<std::string>> GetStaticLibraryLinkOptions(
702
    std::string const& config, std::string const& language) const;
703
704
  std::vector<BT<std::string>>& ResolveArchiverWrapper(
705
    std::vector<BT<std::string>>& result, std::string const& language,
706
    bool joinItems = false) const;
707
708
  void GetLinkDirectories(std::vector<std::string>& result,
709
                          std::string const& config,
710
                          std::string const& language) const;
711
  std::vector<BT<std::string>> GetLinkDirectories(
712
    std::string const& config, std::string const& language) const;
713
714
  void GetLinkDepends(std::vector<std::string>& result,
715
                      std::string const& config,
716
                      std::string const& language) const;
717
  std::vector<BT<std::string>> GetLinkDepends(
718
    std::string const& config, std::string const& language) const;
719
720
  std::vector<BT<std::string>> GetPrecompileHeaders(
721
    std::string const& config, std::string const& language) const;
722
723
0
  void MarkAsPchReused() { this->PchReused = true; }
724
  cmGeneratorTarget const* GetPchReuseTarget() const;
725
  cmGeneratorTarget* GetPchReuseTarget();
726
  std::vector<std::string> GetPchArchs(std::string const& config,
727
                                       std::string const& lang) const;
728
  std::string GetPchHeader(std::string const& config,
729
                           std::string const& language,
730
                           std::string const& arch = std::string()) const;
731
  std::string GetPchSource(std::string const& config,
732
                           std::string const& language,
733
                           std::string const& arch = std::string()) const;
734
  std::string GetPchFileObject(std::string const& config,
735
                               std::string const& language,
736
                               std::string const& arch = std::string());
737
  std::string GetPchFile(std::string const& config,
738
                         std::string const& language,
739
                         std::string const& arch = std::string());
740
  std::string GetPchCreateCompileOptions(
741
    std::string const& config, std::string const& language,
742
    std::string const& arch = std::string());
743
  std::string GetPchUseCompileOptions(std::string const& config,
744
                                      std::string const& language,
745
                                      std::string const& arch = std::string());
746
747
  void AddSourceFileToUnityBatch(std::string const& sourceFilename);
748
  bool IsSourceFilePartOfUnityBatch(std::string const& sourceFilename) const;
749
750
  bool IsSystemIncludeDirectory(std::string const& dir,
751
                                std::string const& config,
752
                                std::string const& language) const;
753
754
  void AddSystemIncludeCacheKey(std::string const& key,
755
                                std::string const& config,
756
                                std::string const& language) const;
757
758
  /** Add the target output files to the global generator manifest.  */
759
  void ComputeTargetManifest(std::string const& config) const;
760
761
  bool ComputeCompileFeatures(std::string const& config);
762
763
  using LanguagePair = std::pair<std::string, std::string>;
764
  bool ComputeCompileFeatures(std::string const& config,
765
                              std::set<LanguagePair> const& languagePairs);
766
767
  /**
768
   * Trace through the source files in this target and add al source files
769
   * that they depend on, used by all generators
770
   */
771
  void TraceDependencies();
772
773
  /** Get the directory in which this target will be built.  If the
774
      configuration name is given then the generator will add its
775
      subdirectory for that configuration.  Otherwise just the canonical
776
      output directory is given.  */
777
  std::string GetDirectory(std::string const& config,
778
                           cmStateEnums::ArtifactType artifact =
779
                             cmStateEnums::RuntimeBinaryArtifact) const;
780
781
  /** Get the directory in which to place the target compiler .pdb file.
782
      If the configuration name is given then the generator will add its
783
      subdirectory for that configuration.  Otherwise just the canonical
784
      compiler pdb output directory is given.  */
785
  std::string GetCompilePDBDirectory(std::string const& config) const;
786
787
  /** Get sources that must be built before the given source.  */
788
  std::vector<cmSourceFile*> const* GetSourceDepends(
789
    cmSourceFile const* sf) const;
790
791
  /** Return whether this target uses the default value for its output
792
      directory.  */
793
  bool UsesDefaultOutputDir(std::string const& config,
794
                            cmStateEnums::ArtifactType artifact) const;
795
796
  // Cache target output paths for each configuration.
797
  struct OutputInfo
798
  {
799
    std::string OutDir;
800
    std::string ImpDir;
801
    std::string PdbDir;
802
    bool empty() const
803
0
    {
804
0
      return this->OutDir.empty() && this->ImpDir.empty() &&
805
0
        this->PdbDir.empty();
806
0
    }
807
  };
808
809
  OutputInfo const* GetOutputInfo(std::string const& config) const;
810
811
  // Get the target PDB base name.
812
  std::string GetPDBOutputName(std::string const& config) const;
813
814
  /** Get the name of the pdb file for the target.  */
815
  std::string GetPDBName(std::string const& config) const;
816
817
  /** Whether this library has soname enabled and platform supports it.  */
818
  bool HasSOName(std::string const& config) const;
819
820
  struct CompileInfo
821
  {
822
    std::string CompilePdbDir;
823
  };
824
825
  CompileInfo const* GetCompileInfo(std::string const& config) const;
826
827
  using CompileInfoMapType = std::map<std::string, CompileInfo>;
828
  mutable CompileInfoMapType CompileInfoMap;
829
830
  bool IsNullImpliedByLinkLibraries(std::string const& p) const;
831
832
  /** Get the name of the compiler pdb file for the target.  */
833
  std::string GetCompilePDBName(std::string const& config) const;
834
835
  /** Get the path for the MSVC /Fd option for this target.  */
836
  std::string GetCompilePDBPath(std::string const& config) const;
837
838
  // Get the target base name.
839
  std::string GetOutputName(std::string const& config,
840
                            cmStateEnums::ArtifactType artifact) const;
841
842
  /** Get target file prefix */
843
  std::string GetFilePrefix(std::string const& config,
844
                            cmStateEnums::ArtifactType artifact =
845
                              cmStateEnums::RuntimeBinaryArtifact) const;
846
  /** Get target file prefix */
847
  std::string GetFileSuffix(std::string const& config,
848
                            cmStateEnums::ArtifactType artifact =
849
                              cmStateEnums::RuntimeBinaryArtifact) const;
850
851
  /** Get target file postfix */
852
  std::string GetFilePostfix(std::string const& config) const;
853
854
  /** Get framework multi-config-specific postfix */
855
  std::string GetFrameworkMultiConfigPostfix(std::string const& config) const;
856
857
  /** Clears cached meta data for local and external source files.
858
   * The meta data will be recomputed on demand.
859
   */
860
  void ClearSourcesCache();
861
862
  /**
863
   * Clears cached evaluations of INTERFACE_LINK_LIBRARIES.
864
   * They will be recomputed on demand.
865
   */
866
  void ClearLinkInterfaceCache();
867
868
  cmSourceFile* AddSource(std::string const& src, bool before = false);
869
  void AddTracedSources(std::vector<std::string> const& srcs);
870
871
  /**
872
   * Adds an entry to the INCLUDE_DIRECTORIES list.
873
   * If before is true the entry is pushed at the front.
874
   */
875
  void AddIncludeDirectory(std::string const& src, bool before = false);
876
877
  /**
878
   * Flags for a given source file as used in this target. Typically assigned
879
   * via SET_TARGET_PROPERTIES when the property is a list of source files.
880
   */
881
  enum SourceFileType
882
  {
883
    SourceFileTypeNormal,
884
    SourceFileTypePrivateHeader, // is in "PRIVATE_HEADER" target property
885
    SourceFileTypePublicHeader,  // is in "PUBLIC_HEADER" target property
886
    SourceFileTypeResource,      // is in "RESOURCE" target property *or*
887
                                 // has MACOSX_PACKAGE_LOCATION=="Resources"
888
    SourceFileTypeDeepResource,  // MACOSX_PACKAGE_LOCATION starts with
889
                                 // "Resources/"
890
    SourceFileTypeMacContent     // has MACOSX_PACKAGE_LOCATION!="Resources[/]"
891
  };
892
  struct SourceFileFlags
893
  {
894
    SourceFileType Type = SourceFileTypeNormal;
895
    char const* MacFolder = nullptr; // location inside Mac content folders
896
  };
897
  void GetAutoUicOptions(std::vector<std::string>& result,
898
                         std::string const& config) const;
899
900
  struct Names
901
  {
902
    std::string Base;
903
    std::string Output;
904
    std::string Real;
905
    std::string ImportOutput;
906
    std::string ImportReal;
907
    std::string ImportLibrary;
908
    std::string PDB;
909
    std::string SharedObject;
910
  };
911
912
  /** Get the names of the executable needed to generate a build rule
913
      that takes into account executable version numbers.  This should
914
      be called only on an executable target.  */
915
  Names GetExecutableNames(std::string const& config) const;
916
917
  /** Get the names of the library needed to generate a build rule
918
      that takes into account shared library version numbers.  This
919
      should be called only on a library target.  */
920
  Names GetLibraryNames(std::string const& config) const;
921
922
  /**
923
   * Compute whether this target must be relinked before installing.
924
   */
925
  bool NeedRelinkBeforeInstall(std::string const& config) const;
926
927
  /** Return true if builtin chrpath will work for this target */
928
  bool IsChrpathUsed(std::string const& config) const;
929
930
  /** Get the directory in which this targets .pdb files will be placed.
931
      If the configuration name is given then the generator will add its
932
      subdirectory for that configuration.  Otherwise just the canonical
933
      pdb output directory is given.  */
934
  std::string GetPDBDirectory(std::string const& config) const;
935
936
  //! Return the preferred linker language for this target
937
  std::string GetLinkerLanguage(std::string const& config) const;
938
  //! Return the preferred linker tool for this target
939
  std::string GetLinkerTool(std::string const& config) const;
940
  std::string GetLinkerTool(std::string const& lang,
941
                            std::string const& config) const;
942
943
  /** Is the linker known to enforce '--no-allow-shlib-undefined'? */
944
  bool LinkerEnforcesNoAllowShLibUndefined(std::string const& config) const;
945
946
  /** Does this target have a GNU implib to convert to MS format?  */
947
  bool HasImplibGNUtoMS(std::string const& config) const;
948
949
  /** Convert the given GNU import library name (.dll.a) to a name with a new
950
      extension (.lib or ${CMAKE_IMPORT_LIBRARY_SUFFIX}).  */
951
  bool GetImplibGNUtoMS(std::string const& config, std::string const& gnuName,
952
                        std::string& out, char const* newExt = nullptr) const;
953
954
  /** Can only ever return true if GetSourceFilePaths() was called before.
955
      Otherwise, this is indeterminate and false will be assumed/returned!  */
956
  bool HasContextDependentSources() const;
957
958
  bool IsExecutableWithExports() const;
959
960
  /* Return whether this target is a shared library with capability to generate
961
   * a file describing symbols exported (for example, .tbd file on Apple). */
962
  bool IsSharedLibraryWithExports() const;
963
964
  /** Return whether or not the target has a DLL import library.  */
965
  bool HasImportLibrary(std::string const& config) const;
966
967
  bool GetUseShortObjectNames(
968
    cmStateEnums::IntermediateDirKind kind =
969
      cmStateEnums::IntermediateDirKind::ObjectFiles) const;
970
  cmObjectLocations::UseShortPath GetUseShortObjectNamesForInstall() const;
971
972
  /** Get a build-tree directory in which to place target support files.  */
973
  std::string GetSupportDirectory(
974
    cmStateEnums::IntermediateDirKind kind =
975
      cmStateEnums::IntermediateDirKind::ObjectFiles) const;
976
  std::string GetCMFSupportDirectory(
977
    cmStateEnums::IntermediateDirKind kind =
978
      cmStateEnums::IntermediateDirKind::ObjectFiles) const;
979
980
  /** Return whether this target may be used to link another target.  */
981
  bool IsLinkable() const;
982
983
  /** Return whether the link step generates a dependency file. */
984
  bool HasLinkDependencyFile(std::string const& config) const;
985
986
  /** Return whether this target is a shared library Framework on
987
      Apple.  */
988
  bool IsFrameworkOnApple() const;
989
990
  /** Return whether this target is an IMPORTED library target on Apple
991
      with a .framework folder as its location.  */
992
  bool IsImportedFrameworkFolderOnApple(std::string const& config) const;
993
994
  /** Return whether this target is an executable Bundle on Apple.  */
995
  bool IsAppBundleOnApple() const;
996
997
  /** Return whether this target is an XCTest on Apple.  */
998
  bool IsXCTestOnApple() const;
999
1000
  /** Return whether this target is a CFBundle (plugin) on Apple.  */
1001
  bool IsCFBundleOnApple() const;
1002
1003
  /** Return whether this target is a shared library on AIX.  */
1004
  bool IsArchivedAIXSharedLibrary() const;
1005
1006
  /** Assembly types. The order of the values of this enum is relevant
1007
      because of smaller/larger comparison operations! */
1008
  enum ManagedType
1009
  {
1010
    Undefined = 0, // target is no lib or executable
1011
    Native,        // target compiles to unmanaged binary.
1012
    Mixed,         // target compiles to mixed (managed and unmanaged) binary.
1013
    Managed        // target compiles to managed binary.
1014
  };
1015
1016
  /** Return the type of assembly this target compiles to. */
1017
  ManagedType GetManagedType(std::string const& config) const;
1018
1019
  struct SourceFileFlags GetTargetSourceFileFlags(
1020
    cmSourceFile const* sf) const;
1021
1022
  void ReportPropertyOrigin(std::string const& p, std::string const& result,
1023
                            std::string const& report,
1024
                            std::string const& compatibilityType) const;
1025
1026
  std::string EvaluateInterfaceProperty(
1027
    std::string const& prop, cm::GenEx::Evaluation* eval,
1028
    cmGeneratorExpressionDAGChecker* dagCheckerParent, UseTo usage) const;
1029
1030
  struct TransitiveProperty
1031
  {
1032
#if defined(__SUNPRO_CC) || (defined(__ibmxl__) && defined(__clang__))
1033
    TransitiveProperty(cm::string_view interfaceName, UseTo usage)
1034
      : InterfaceName(interfaceName)
1035
      , Usage(usage)
1036
    {
1037
    }
1038
#endif
1039
    cm::string_view InterfaceName;
1040
    UseTo Usage;
1041
  };
1042
1043
  static std::map<cm::string_view, TransitiveProperty> const
1044
    BuiltinTransitiveProperties;
1045
1046
  cm::optional<TransitiveProperty> IsTransitiveProperty(
1047
    cm::string_view prop, cm::GenEx::Context const& context,
1048
    cmGeneratorExpressionDAGChecker const* dagChecker) const;
1049
1050
  bool HaveInstallTreeRPATH(std::string const& config) const;
1051
1052
  bool GetBuildRPATH(std::string const& config, std::string& rpath) const;
1053
  bool GetInstallRPATH(std::string const& config, std::string& rpath) const;
1054
1055
  /** Whether this library has \@rpath and platform supports it.  */
1056
  bool HasMacOSXRpathInstallNameDir(std::string const& config) const;
1057
1058
  /** Whether this library defaults to \@rpath.  */
1059
  bool MacOSXRpathInstallNameDirDefault() const;
1060
1061
  enum InstallNameType
1062
  {
1063
    INSTALL_NAME_FOR_BUILD,
1064
    INSTALL_NAME_FOR_INSTALL
1065
  };
1066
  /** Whether to use INSTALL_NAME_DIR. */
1067
  bool MacOSXUseInstallNameDir() const;
1068
  /** Whether to generate an install_name. */
1069
  bool CanGenerateInstallNameDir(InstallNameType t) const;
1070
1071
  /** Test for special case of a third-party shared library that has
1072
      no soname at all.  */
1073
  bool IsImportedSharedLibWithoutSOName(std::string const& config) const;
1074
1075
  std::string ImportedGetLocation(std::string const& config) const;
1076
1077
  /** Get the target major and minor version numbers interpreted from
1078
      the VERSION property.  Version 0 is returned if the property is
1079
      not set or cannot be parsed.  */
1080
  void GetTargetVersion(int& major, int& minor) const;
1081
1082
  /** Get the target major, minor, and patch version numbers
1083
      interpreted from the given property.  Version 0
1084
      is returned if the property is not set or cannot be parsed.  */
1085
  void GetTargetVersion(std::string const& property, int& major, int& minor,
1086
                        int& patch) const;
1087
1088
  /** Get the target major, minor, and patch version numbers
1089
      interpreted from the given property and if empty use the
1090
      fallback property.  Version 0 is returned if the property is
1091
      not set or cannot be parsed.  */
1092
  void GetTargetVersionFallback(std::string const& property,
1093
                                std::string const& fallback_property,
1094
                                int& major, int& minor, int& patch) const;
1095
1096
  std::string GetRuntimeLinkLibrary(std::string const& lang,
1097
                                    std::string const& config) const;
1098
1099
  std::string GetFortranModuleDirectory(std::string const& working_dir) const;
1100
  bool IsFortranBuildingIntrinsicModules() const;
1101
1102
  bool IsLinkLookupScope(std::string const& n,
1103
                         cmLocalGenerator const*& lg) const;
1104
1105
  cmValue GetSourcesProperty() const;
1106
1107
  void AddISPCGeneratedHeader(std::string const& header,
1108
                              std::string const& config);
1109
  std::vector<std::string> GetGeneratedISPCHeaders(
1110
    std::string const& config) const;
1111
1112
  void AddISPCGeneratedObject(
1113
    std::vector<std::pair<cmSourceFile const*, std::string>>&& objs,
1114
    std::string const& config);
1115
  std::vector<std::pair<cmSourceFile const*, std::string>>
1116
  GetGeneratedISPCObjects(std::string const& config) const;
1117
1118
  void AddSystemIncludeDirectory(std::string const& inc,
1119
                                 std::string const& lang);
1120
  bool AddHeaderSetVerification();
1121
  cm::optional<std::string> GenerateHeaderSetVerificationFile(
1122
    cmSourceFile& source, std::string const& dir,
1123
    std::string const& verifyTargetName,
1124
    cm::optional<cm::optional<std::string>>& defaultLanguage) const;
1125
1126
  cm::optional<std::string> ResolveHeaderLanguage(
1127
    cmSourceFile& source,
1128
    cm::optional<cm::optional<std::string>>& defaultLanguage) const;
1129
1130
  cm::optional<std::string> GenerateStubForLanguage(
1131
    std::string const& language, std::string const& headerFilename,
1132
    std::string const& verifyTargetName, cmSourceFile& source) const;
1133
1134
  std::string GetImportedXcFrameworkPath(std::string const& config) const;
1135
1136
  bool ApplyCXXStdTargets();
1137
  bool DiscoverSyntheticTargets(
1138
    cmSyntheticTargetCache& cache, std::string const& config,
1139
    cmGeneratorTarget const* bmiConsumer = nullptr);
1140
1141
  using SyntheticDepsMap =
1142
    std::map<cmGeneratorTarget const*, std::vector<cmGeneratorTarget const*>>;
1143
  SyntheticDepsMap const& GetSyntheticDeps(std::string const& config) const;
1144
1145
  class CustomTransitiveProperty : public TransitiveProperty
1146
  {
1147
    std::unique_ptr<std::string> InterfaceNameBuf;
1148
    CustomTransitiveProperty(std::unique_ptr<std::string> interfaceNameBuf,
1149
                             UseTo usage);
1150
1151
  public:
1152
    CustomTransitiveProperty(std::string interfaceName, UseTo usage);
1153
  };
1154
  struct CustomTransitiveProperties
1155
    : public std::map<std::string, CustomTransitiveProperty>
1156
  {
1157
    void Add(cmValue props, UseTo usage);
1158
  };
1159
1160
  enum class PropertyFor
1161
  {
1162
    Build,
1163
    Interface,
1164
  };
1165
1166
  CustomTransitiveProperties const& GetCustomTransitiveProperties(
1167
    std::string const& config, PropertyFor propertyFor) const;
1168
1169
private:
1170
  void AddSourceCommon(std::string const& src, bool before = false);
1171
1172
  std::string CreateFortranModuleDirectory(
1173
    std::string const& working_dir) const;
1174
  mutable bool FortranModuleDirectoryCreated = false;
1175
  mutable std::string FortranModuleDirectory;
1176
1177
  friend class cmTargetTraceDependencies;
1178
  struct SourceEntry
1179
  {
1180
    std::vector<cmSourceFile*> Depends;
1181
  };
1182
  using SourceEntriesType = std::map<cmSourceFile const*, SourceEntry>;
1183
  SourceEntriesType SourceDepends;
1184
  mutable std::set<std::string> VisitedConfigsForObjects;
1185
  mutable std::map<cmSourceFile const*, cmObjectLocations> Objects;
1186
  std::set<cmSourceFile const*> ExplicitObjectName;
1187
1188
  using TargetPtrToBoolMap = std::unordered_map<cmTarget*, bool>;
1189
  mutable std::unordered_map<std::string, TargetPtrToBoolMap>
1190
    MacOSXRpathInstallNameDirCache;
1191
  bool DetermineHasMacOSXRpathInstallNameDir(std::string const& config) const;
1192
1193
  // "config/language" is the key
1194
  mutable std::map<std::string, std::vector<std::string>> SystemIncludesCache;
1195
1196
  mutable std::string ExportMacro;
1197
  mutable std::unordered_map<std::string, cmList> SharedLibraryCompileDefs;
1198
1199
  void ConstructSourceFileFlags() const;
1200
  mutable bool SourceFileFlagsConstructed = false;
1201
  mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
1202
1203
  mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
1204
1205
  bool NeedImportLibraryName(std::string const& config) const;
1206
1207
  cmValue GetFilePrefixInternal(std::string const& config,
1208
                                cmStateEnums::ArtifactType artifact,
1209
                                std::string const& language = "") const;
1210
  cmValue GetFileSuffixInternal(std::string const& config,
1211
                                cmStateEnums::ArtifactType artifact,
1212
                                std::string const& language = "") const;
1213
1214
  std::string GetFullNameInternal(std::string const& config,
1215
                                  cmStateEnums::ArtifactType artifact) const;
1216
1217
  using FullNameCache = std::map<std::string, NameComponents>;
1218
1219
  mutable FullNameCache RuntimeBinaryFullNameCache;
1220
  mutable FullNameCache ImportLibraryFullNameCache;
1221
1222
  NameComponents const& GetFullNameInternalComponents(
1223
    std::string const& config, cmStateEnums::ArtifactType artifact) const;
1224
1225
  mutable std::string LinkerLanguage;
1226
  using LinkClosureMapType = std::map<std::string, LinkClosure>;
1227
  mutable LinkClosureMapType LinkClosureMap;
1228
  bool DeviceLink = false;
1229
1230
  // Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
1231
  char const* GetOutputTargetType(cmStateEnums::ArtifactType artifact) const;
1232
1233
  std::string ComputeVersionedName(std::string const& prefix,
1234
                                   std::string const& base,
1235
                                   std::string const& suffix,
1236
                                   std::string const& name,
1237
                                   cmValue version) const;
1238
1239
  mutable std::map<std::string, CustomTransitiveProperties>
1240
    CustomTransitiveBuildPropertiesMap;
1241
  mutable std::map<std::string, CustomTransitiveProperties>
1242
    CustomTransitiveInterfacePropertiesMap;
1243
1244
  struct CompatibleInterfacesBase
1245
  {
1246
    std::set<std::string> PropsBool;
1247
    std::set<std::string> PropsString;
1248
    std::set<std::string> PropsNumberMax;
1249
    std::set<std::string> PropsNumberMin;
1250
  };
1251
  CompatibleInterfacesBase const& GetCompatibleInterfaces(
1252
    std::string const& config) const;
1253
1254
  struct CompatibleInterfaces : public CompatibleInterfacesBase
1255
  {
1256
    bool Done = false;
1257
  };
1258
  mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
1259
1260
  using cmTargetLinkInformationMap =
1261
    std::map<std::string, std::unique_ptr<cmComputeLinkInformation>>;
1262
  mutable cmTargetLinkInformationMap LinkInformation;
1263
1264
  void CheckPropertyCompatibility(cmComputeLinkInformation& info,
1265
                                  std::string const& config) const;
1266
1267
  void ComputeLinkClosure(std::string const& config, LinkClosure& lc) const;
1268
  bool ComputeLinkClosure(std::string const& config, LinkClosure& lc,
1269
                          bool secondPass) const;
1270
1271
  struct LinkImplClosure : public std::vector<cmGeneratorTarget const*>
1272
  {
1273
    bool Done = false;
1274
  };
1275
  mutable std::map<std::string, LinkImplClosure> LinkImplClosureForLinkMap;
1276
  mutable std::map<std::string, LinkImplClosure> LinkImplClosureForUsageMap;
1277
1278
  using LinkInterfaceMapType = std::map<std::string, cmHeadToLinkInterfaceMap>;
1279
  mutable LinkInterfaceMapType LinkInterfaceMap;
1280
  mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
1281
1282
  cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceMap(
1283
    std::string const& config) const;
1284
  cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceUsageRequirementsMap(
1285
    std::string const& config) const;
1286
1287
  std::string GetLinkInterfaceDependentStringAsBoolProperty(
1288
    std::string const& p, std::string const& config) const;
1289
1290
  friend class cmTargetCollectLinkLanguages;
1291
  cmLinkInterface const* GetLinkInterface(std::string const& config,
1292
                                          cmGeneratorTarget const* headTarget,
1293
                                          bool secondPass) const;
1294
  void ComputeLinkInterface(std::string const& config,
1295
                            cmOptionalLinkInterface& iface,
1296
                            bool secondPass) const;
1297
  cmLinkImplementation const* GetLinkImplementation(std::string const& config,
1298
                                                    UseTo usage,
1299
                                                    bool secondPass) const;
1300
1301
  enum class LinkItemRole
1302
  {
1303
    Implementation,
1304
    Interface,
1305
  };
1306
  bool VerifyLinkItemIsTarget(LinkItemRole role, cmLinkItem const& item) const;
1307
  bool VerifyLinkItemColons(LinkItemRole role, cmLinkItem const& item) const;
1308
1309
  // Cache import information from properties for each configuration.
1310
  struct ImportInfo
1311
  {
1312
    bool NoSOName = false;
1313
    ManagedType Managed = Native;
1314
    unsigned int Multiplicity = 0;
1315
    std::string Location;
1316
    std::string SOName;
1317
    std::string ImportLibrary;
1318
    std::string LibName;
1319
    std::string Languages;
1320
    std::string LibrariesProp;
1321
    std::vector<BT<std::string>> Libraries;
1322
    std::vector<BT<std::string>> LibrariesHeadInclude;
1323
    std::vector<BT<std::string>> LibrariesHeadExclude;
1324
    std::string SharedDeps;
1325
  };
1326
1327
  using ImportInfoMapType = std::map<std::string, ImportInfo>;
1328
  mutable ImportInfoMapType ImportInfoMap;
1329
  void ComputeImportInfo(std::string const& desired_config,
1330
                         ImportInfo& info) const;
1331
  ImportInfo const* GetImportInfo(std::string const& config) const;
1332
1333
  /** Strip off leading and trailing whitespace from an item named in
1334
      the link dependencies of this target.  */
1335
  std::string CheckCMP0004(std::string const& item) const;
1336
1337
  cmLinkInterface const* GetImportLinkInterface(std::string const& config,
1338
                                                cmGeneratorTarget const* head,
1339
                                                UseTo usage,
1340
                                                bool secondPass = false) const;
1341
1342
  using KindedSourcesMapType = std::map<std::string, KindedSources>;
1343
  mutable KindedSourcesMapType KindedSourcesMap;
1344
  void ComputeKindedSources(KindedSources& files,
1345
                            std::string const& config) const;
1346
1347
  mutable std::vector<AllConfigSource> AllConfigSources;
1348
  void ComputeAllConfigSources() const;
1349
1350
  mutable std::set<std::string> AllConfigCompileLanguages;
1351
  void ComputeAllConfigCompileLanguages() const;
1352
1353
  mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists;
1354
  bool MaybeHaveInterfaceProperty(std::string const& prop,
1355
                                  cm::GenEx::Evaluation* eval,
1356
                                  UseTo usage) const;
1357
1358
  using TargetPropertyEntryVector =
1359
    std::vector<std::unique_ptr<TargetPropertyEntry>>;
1360
1361
  TargetPropertyEntryVector IncludeDirectoriesEntries;
1362
  TargetPropertyEntryVector CompileOptionsEntries;
1363
  TargetPropertyEntryVector CompileFeaturesEntries;
1364
  TargetPropertyEntryVector CompileDefinitionsEntries;
1365
  TargetPropertyEntryVector LinkOptionsEntries;
1366
  TargetPropertyEntryVector LinkDirectoriesEntries;
1367
  TargetPropertyEntryVector PrecompileHeadersEntries;
1368
  TargetPropertyEntryVector SourceEntries;
1369
  mutable std::set<std::string> LinkImplicitNullProperties;
1370
  mutable std::map<std::string, std::string> PchHeaders;
1371
  mutable std::map<std::string, std::string> PchSources;
1372
  mutable std::map<std::string, std::string> PchObjectFiles;
1373
  mutable std::map<std::string, std::string> PchFiles;
1374
  mutable std::map<std::string, std::string> PchCreateCompileOptions;
1375
  mutable std::map<std::string, std::string> PchUseCompileOptions;
1376
1377
  std::unordered_set<std::string> UnityBatchedSourceFiles;
1378
1379
  std::unordered_map<std::string, std::vector<std::string>>
1380
    ISPCGeneratedHeaders;
1381
  std::unordered_map<std::string,
1382
                     std::vector<std::pair<cmSourceFile const*, std::string>>>
1383
    ISPCGeneratedObjects;
1384
1385
  enum class LinkInterfaceField
1386
  {
1387
    Libraries,
1388
    HeadExclude,
1389
    HeadInclude,
1390
  };
1391
  void ExpandLinkItems(std::string const& prop, cmBTStringRange entries,
1392
                       std::string const& config,
1393
                       cmGeneratorTarget const* headTarget, UseTo usage,
1394
                       LinkInterfaceField field, cmLinkInterface& iface) const;
1395
1396
  struct LookupLinkItemScope
1397
  {
1398
    cmLocalGenerator const* LG;
1399
  };
1400
  enum class LookupSelf
1401
  {
1402
    No,
1403
    Yes,
1404
  };
1405
  cm::optional<cmLinkItem> LookupLinkItem(std::string const& n,
1406
                                          cmListFileBacktrace const& bt,
1407
                                          std::string const& linkFeature,
1408
                                          LookupLinkItemScope* scope,
1409
                                          LookupSelf lookupSelf) const;
1410
1411
  std::vector<BT<std::string>>& ResolvePrefixWrapper(
1412
    std::vector<BT<std::string>>& result, cm::string_view prefix,
1413
    std::string const& language, bool joinItems) const;
1414
1415
  std::vector<BT<std::string>> GetSourceFilePaths(
1416
    std::string const& config) const;
1417
  std::vector<BT<cmSourceFile*>> GetSourceFilesWithoutObjectLibraries(
1418
    std::string const& config) const;
1419
  void GetSourceFilesWithoutObjectLibraries(std::vector<cmSourceFile*>& files,
1420
                                            std::string const& config) const;
1421
1422
  using LinkImplMapType = std::map<std::string, cmOptionalLinkImplementation>;
1423
  mutable LinkImplMapType LinkImplMap;
1424
  mutable LinkImplMapType LinkImplUsageRequirementsOnlyMap;
1425
1426
  bool ComputeOutputDir(std::string const& config,
1427
                        cmStateEnums::ArtifactType artifact,
1428
                        std::string& out) const;
1429
1430
  using OutputInfoMapType = std::map<std::string, OutputInfo>;
1431
  mutable OutputInfoMapType OutputInfoMap;
1432
1433
  using PdbOutputNameMapType = std::map<std::string, std::string>;
1434
  mutable PdbOutputNameMapType PdbOutputNameMap;
1435
1436
  using ModuleDefinitionInfoMapType =
1437
    std::map<std::string, ModuleDefinitionInfo>;
1438
  mutable ModuleDefinitionInfoMapType ModuleDefinitionInfoMap;
1439
  void ComputeModuleDefinitionInfo(std::string const& config,
1440
                                   ModuleDefinitionInfo& info) const;
1441
1442
  using OutputNameKey = std::pair<std::string, cmStateEnums::ArtifactType>;
1443
  using OutputNameMapType = std::map<OutputNameKey, std::string>;
1444
  mutable OutputNameMapType OutputNameMap;
1445
  mutable std::set<cmLinkItem> UtilityItems;
1446
  cmPolicies::PolicyMap PolicyMap;
1447
  mutable bool PolicyReportedCMP0069 = false;
1448
  mutable bool DebugIncludesDone = false;
1449
  mutable bool DebugCompileOptionsDone = false;
1450
  mutable bool DebugCompileFeaturesDone = false;
1451
  mutable bool DebugCompileDefinitionsDone = false;
1452
  mutable bool DebugLinkOptionsDone = false;
1453
  mutable bool DebugLinkDirectoriesDone = false;
1454
  mutable bool DebugPrecompileHeadersDone = false;
1455
  mutable bool DebugSourcesDone = false;
1456
  mutable bool UtilityItemsDone = false;
1457
  enum class Tribool
1458
  {
1459
    False = 0x0,
1460
    True = 0x1,
1461
    Indeterminate = 0x2
1462
  };
1463
  mutable Tribool SourcesAreContextDependent = Tribool::Indeterminate;
1464
1465
  bool ComputePDBOutputDir(std::string const& kind, std::string const& config,
1466
                           std::string& out) const;
1467
1468
  ManagedType CheckManagedType(std::string const& propval) const;
1469
1470
  bool GetRPATH(std::string const& config, std::string const& prop,
1471
                std::string& rpath) const;
1472
1473
  std::map<std::string, BTs<std::string>> LanguageStandardMap;
1474
1475
  cm::optional<cmStandardLevel> GetExplicitStandardLevel(
1476
    std::string const& lang, std::string const& config) const;
1477
  void UpdateExplicitStandardLevel(std::string const& lang,
1478
                                   std::string const& config,
1479
                                   cmStandardLevel level);
1480
  std::map<std::string, cmStandardLevel> ExplicitStandardLevel;
1481
1482
  cmValue GetPropertyWithPairedLanguageSupport(std::string const& lang,
1483
                                               char const* suffix) const;
1484
1485
  std::vector<cmLinkItem> ComputeImplicitLanguageTargets(
1486
    std::string const& lang, std::string const& config) const;
1487
1488
  void ComputeLinkImplementationRuntimeLibraries(
1489
    std::string const& config, cmOptionalLinkImplementation& impl) const;
1490
1491
  void ComputeLinkInterfaceRuntimeLibraries(
1492
    std::string const& config, cmOptionalLinkInterface& iface) const;
1493
1494
  // If this method is made public, or call sites are added outside of
1495
  // methods computing cached members, add dedicated caching members.
1496
  std::vector<cmGeneratorTarget const*> GetLinkInterfaceClosure(
1497
    std::string const& config, cmGeneratorTarget const* headTarget,
1498
    UseTo usage) const;
1499
1500
public:
1501
  std::vector<cmGeneratorTarget const*> const& GetLinkImplementationClosure(
1502
    std::string const& config, UseTo usage) const;
1503
1504
  mutable std::map<std::string, std::string> MaxLanguageStandards;
1505
  std::map<std::string, std::string> const& GetMaxLanguageStandards() const
1506
0
  {
1507
0
    return this->MaxLanguageStandards;
1508
0
  }
1509
1510
  struct StrictTargetComparison
1511
  {
1512
    bool operator()(cmGeneratorTarget const* t1,
1513
                    cmGeneratorTarget const* t2) const;
1514
  };
1515
1516
  bool HaveFortranSources() const;
1517
  bool HaveFortranSources(std::string const& config) const;
1518
1519
  // File sets support queries
1520
1521
  bool HasFileSets() const;
1522
  std::vector<cmGeneratorFileSet const*> const& GetAllFileSets() const;
1523
  std::vector<cmGeneratorFileSet const*> const& GetFileSets(
1524
    cm::string_view type) const;
1525
  std::vector<cmGeneratorFileSet const*> const& GetInterfaceFileSets(
1526
    cm::string_view type) const;
1527
  cmGeneratorFileSet const* GetFileSet(std::string const& name) const;
1528
  cmGeneratorFileSet const* GetFileSetForSource(std::string const& config,
1529
                                                cmSourceFile const* sf) const;
1530
1531
  // C++20 module support queries.
1532
1533
  /**
1534
   * Query whether the target expects C++20 module support.
1535
   *
1536
   * This will inspect the target itself to see if C++20 module
1537
   * support is expected to work based on its sources.
1538
   */
1539
  bool HaveCxx20ModuleSources() const;
1540
1541
  enum class Cxx20SupportLevel
1542
  {
1543
    // C++ is not available.
1544
    MissingCxx,
1545
    // The target does not require at least C++20.
1546
    NoCxx20,
1547
    // C++20 module scanning rules are not present.
1548
    MissingRule,
1549
    // C++20 modules are available and working.
1550
    Supported,
1551
  };
1552
1553
  /**
1554
   * Query whether the target has C++20 module support available (regardless of
1555
   * whether it is required or not).
1556
   */
1557
  Cxx20SupportLevel HaveCxxModuleSupport(std::string const& config) const;
1558
1559
  // Check C++ module status for the target.
1560
  void CheckCxxModuleStatus(std::string const& config) const;
1561
1562
  bool NeedCxxModuleSupport(std::string const& lang,
1563
                            std::string const& config) const;
1564
  bool NeedDyndep(std::string const& lang, std::string const& config) const;
1565
  bool NeedDyndepForSource(std::string const& lang, std::string const& config,
1566
                           cmSourceFile const* sf) const;
1567
  enum class CxxModuleSupport
1568
  {
1569
    Unavailable,
1570
    Enabled,
1571
    Disabled,
1572
  };
1573
  CxxModuleSupport NeedCxxDyndep(std::string const& config) const;
1574
1575
  std::string BuildDatabasePath(std::string const& lang,
1576
                                std::string const& config) const;
1577
1578
  enum class MsvcCharSet
1579
  {
1580
    None,
1581
    Unicode,
1582
    MultiByte,
1583
    SingleByte,
1584
  };
1585
1586
  // Detect if the current define selects any known charset entry or not
1587
  static MsvcCharSet GetMsvcCharSet(std::string const& singleDefine);
1588
1589
private:
1590
  struct InfoByConfig
1591
  {
1592
    std::map<cmGeneratorTarget const*, std::vector<cmGeneratorTarget const*>>
1593
      SyntheticDeps;
1594
    std::map<cmSourceFile const*, ClassifiedFlags> SourceFlags;
1595
  };
1596
  mutable std::map<std::string, InfoByConfig> Configs;
1597
  std::unique_ptr<cmGeneratorFileSets> FileSets;
1598
  bool PchReused = false;
1599
  mutable bool ComputingPchReuse = false;
1600
  mutable bool PchReuseCycleDetected = false;
1601
};