Coverage Report

Created: 2026-07-14 07:09

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