Coverage Report

Created: 2026-09-14 06:43

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) const;
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() const;
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
  bool HasCxxImportModuleErrors() const;
1152
  cmCxxModuleUsageEffects const& GetCxxModuleUsageEffects(
1153
    std::string const& config) const;
1154
  cmGeneratorTarget const* GetTargetForCxxModules(
1155
    std::string const& config, cmGeneratorTarget const& bmiConsumer) const;
1156
  bool DiscoverSyntheticTargets(
1157
    std::string const& config, cmGeneratorTarget const* bmiConsumer = nullptr);
1158
1159
  using SyntheticDepsMap =
1160
    std::map<cmGeneratorTarget const*, std::set<cmGeneratorTarget const*>>;
1161
  SyntheticDepsMap const& GetSyntheticDeps(std::string const& config) const;
1162
1163
  class CustomTransitiveProperty : public TransitiveProperty
1164
  {
1165
    std::unique_ptr<std::string> InterfaceNameBuf;
1166
    CustomTransitiveProperty(std::unique_ptr<std::string> interfaceNameBuf,
1167
                             UseTo usage);
1168
1169
  public:
1170
    CustomTransitiveProperty(std::string interfaceName, UseTo usage);
1171
  };
1172
  struct CustomTransitiveProperties
1173
    : public std::map<std::string, CustomTransitiveProperty>
1174
  {
1175
    void Add(cmValue props, UseTo usage);
1176
  };
1177
1178
  enum class PropertyFor
1179
  {
1180
    Build,
1181
    Interface,
1182
  };
1183
1184
  CustomTransitiveProperties const& GetCustomTransitiveProperties(
1185
    std::string const& config, PropertyFor propertyFor) const;
1186
1187
private:
1188
  void AddSourceCommon(std::string const& src, bool before = false);
1189
1190
  cmGeneratorTarget const* GetCxxSyntheticTarget(
1191
    std::string const& config, cmGeneratorTarget const& bmiConsumer) const;
1192
1193
  std::string CreateFortranModuleDirectory(
1194
    std::string const& working_dir) const;
1195
  mutable bool FortranModuleDirectoryCreated = false;
1196
  mutable std::string FortranModuleDirectory;
1197
1198
  friend class cmTargetTraceDependencies;
1199
  struct SourceEntry
1200
  {
1201
    std::vector<cmSourceFile*> Depends;
1202
  };
1203
  using SourceEntriesType = std::map<cmSourceFile const*, SourceEntry>;
1204
  SourceEntriesType SourceDepends;
1205
  mutable std::set<std::string> VisitedConfigsForObjects;
1206
  mutable std::map<cmSourceFile const*, cmObjectLocations> Objects;
1207
  std::set<cmSourceFile const*> ExplicitObjectName;
1208
1209
  using TargetPtrToBoolMap = std::unordered_map<cmTarget*, bool>;
1210
  mutable std::unordered_map<std::string, TargetPtrToBoolMap>
1211
    MacOSXRpathInstallNameDirCache;
1212
  bool DetermineHasMacOSXRpathInstallNameDir(std::string const& config) const;
1213
1214
  // "config/language" is the key
1215
  mutable std::map<std::string, std::vector<std::string>> SystemIncludesCache;
1216
1217
  mutable std::string ExportMacro;
1218
  mutable std::unordered_map<std::string, cmList> SharedLibraryCompileDefs;
1219
1220
  void ConstructSourceFileFlags() const;
1221
  mutable bool SourceFileFlagsConstructed = false;
1222
  mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
1223
1224
  mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
1225
1226
  bool NeedImportLibraryName(std::string const& config) const;
1227
1228
  cmValue GetFilePrefixInternal(std::string const& config,
1229
                                cmStateEnums::ArtifactType artifact,
1230
                                std::string const& language = "") const;
1231
  cmValue GetFileSuffixInternal(std::string const& config,
1232
                                cmStateEnums::ArtifactType artifact,
1233
                                std::string const& language = "") const;
1234
1235
  std::string GetFullNameInternal(std::string const& config,
1236
                                  cmStateEnums::ArtifactType artifact) const;
1237
1238
  using FullNameCache = std::map<std::string, NameComponents>;
1239
1240
  mutable FullNameCache RuntimeBinaryFullNameCache;
1241
  mutable FullNameCache ImportLibraryFullNameCache;
1242
1243
  NameComponents const& GetFullNameInternalComponents(
1244
    std::string const& config, cmStateEnums::ArtifactType artifact) const;
1245
1246
  mutable std::string LinkerLanguage;
1247
  using LinkClosureMapType = std::map<std::string, LinkClosure>;
1248
  mutable LinkClosureMapType LinkClosureMap;
1249
  bool DeviceLink = false;
1250
1251
  // Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
1252
  char const* GetOutputTargetType(cmStateEnums::ArtifactType artifact) const;
1253
1254
  std::string ComputeVersionedName(std::string const& prefix,
1255
                                   std::string const& base,
1256
                                   std::string const& suffix,
1257
                                   std::string const& name,
1258
                                   cmValue version) const;
1259
1260
  mutable std::map<std::string, CustomTransitiveProperties>
1261
    CustomTransitiveBuildPropertiesMap;
1262
  mutable std::map<std::string, CustomTransitiveProperties>
1263
    CustomTransitiveInterfacePropertiesMap;
1264
1265
  struct CompatibleInterfacesBase
1266
  {
1267
    std::set<std::string> PropsBool;
1268
    std::set<std::string> PropsString;
1269
    std::set<std::string> PropsNumberMax;
1270
    std::set<std::string> PropsNumberMin;
1271
  };
1272
  CompatibleInterfacesBase const& GetCompatibleInterfaces(
1273
    std::string const& config) const;
1274
1275
  struct CompatibleInterfaces : public CompatibleInterfacesBase
1276
  {
1277
    bool Done = false;
1278
  };
1279
  mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
1280
1281
  using cmTargetLinkInformationMap =
1282
    std::map<std::string, std::unique_ptr<cmComputeLinkInformation>>;
1283
  mutable cmTargetLinkInformationMap LinkInformation;
1284
1285
  void CheckPropertyCompatibility(cmComputeLinkInformation& info,
1286
                                  std::string const& config) const;
1287
1288
  void ComputeLinkClosure(std::string const& config, LinkClosure& lc) const;
1289
  bool ComputeLinkClosure(std::string const& config, LinkClosure& lc,
1290
                          bool secondPass) const;
1291
1292
  struct LinkImplClosure : public std::vector<cmGeneratorTarget const*>
1293
  {
1294
    bool Done = false;
1295
  };
1296
  mutable std::map<std::string, LinkImplClosure> LinkImplClosureForLinkMap;
1297
  mutable std::map<std::string, LinkImplClosure> LinkImplClosureForUsageMap;
1298
1299
  using LinkInterfaceMapType = std::map<std::string, cmHeadToLinkInterfaceMap>;
1300
  mutable LinkInterfaceMapType LinkInterfaceMap;
1301
  mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
1302
1303
  cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceMap(
1304
    std::string const& config) const;
1305
  cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceUsageRequirementsMap(
1306
    std::string const& config) const;
1307
1308
  std::string GetLinkInterfaceDependentStringAsBoolProperty(
1309
    std::string const& p, std::string const& config) const;
1310
1311
  friend class cmTargetCollectLinkLanguages;
1312
  cmLinkInterface const* GetLinkInterface(std::string const& config,
1313
                                          cmGeneratorTarget const* headTarget,
1314
                                          bool secondPass) const;
1315
  void ComputeLinkInterface(std::string const& config,
1316
                            cmOptionalLinkInterface& iface,
1317
                            bool secondPass) const;
1318
  cmLinkImplementation const* GetLinkImplementation(std::string const& config,
1319
                                                    UseTo usage,
1320
                                                    bool secondPass) const;
1321
1322
  enum class LinkItemRole
1323
  {
1324
    Implementation,
1325
    Interface,
1326
  };
1327
  bool VerifyLinkItemIsTarget(LinkItemRole role, cmLinkItem const& item) const;
1328
  bool VerifyLinkItemColons(LinkItemRole role, cmLinkItem const& item) const;
1329
1330
  // Cache import information from properties for each configuration.
1331
  struct ImportInfo
1332
  {
1333
    bool NoSOName = false;
1334
    ManagedType Managed = Native;
1335
    unsigned int Multiplicity = 0;
1336
    std::string Location;
1337
    std::string SOName;
1338
    std::string ImportLibrary;
1339
    std::string LibName;
1340
    std::string Languages;
1341
    std::string LibrariesProp;
1342
    std::vector<BT<std::string>> Libraries;
1343
    std::vector<BT<std::string>> LibrariesHeadInclude;
1344
    std::vector<BT<std::string>> LibrariesHeadExclude;
1345
    std::string SharedDeps;
1346
  };
1347
1348
  using ImportInfoMapType = std::map<std::string, ImportInfo>;
1349
  mutable ImportInfoMapType ImportInfoMap;
1350
  void ComputeImportInfo(std::string const& desired_config,
1351
                         ImportInfo& info) const;
1352
  ImportInfo const* GetImportInfo(std::string const& config) const;
1353
1354
  /** Strip off leading and trailing whitespace from an item named in
1355
      the link dependencies of this target.  */
1356
  std::string CheckCMP0004(std::string const& item) const;
1357
1358
  cmLinkInterface const* GetImportLinkInterface(std::string const& config,
1359
                                                cmGeneratorTarget const* head,
1360
                                                UseTo usage,
1361
                                                bool secondPass = false) const;
1362
1363
  using KindedSourcesMapType = std::map<std::string, KindedSources>;
1364
  mutable KindedSourcesMapType KindedSourcesMap;
1365
  void ComputeKindedSources(KindedSources& files,
1366
                            std::string const& config) const;
1367
1368
  mutable std::vector<AllConfigSource> AllConfigSources;
1369
  void ComputeAllConfigSources() const;
1370
1371
  mutable std::set<std::string> AllConfigCompileLanguages;
1372
  void ComputeAllConfigCompileLanguages() const;
1373
1374
  mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists;
1375
  bool MaybeHaveInterfaceProperty(std::string const& prop,
1376
                                  cm::GenEx::Evaluation* eval,
1377
                                  UseTo usage) const;
1378
1379
  using TargetPropertyEntryVector =
1380
    std::vector<std::unique_ptr<TargetPropertyEntry>>;
1381
1382
  TargetPropertyEntryVector IncludeDirectoriesEntries;
1383
  TargetPropertyEntryVector CompileOptionsEntries;
1384
  TargetPropertyEntryVector CompileFeaturesEntries;
1385
  TargetPropertyEntryVector CompileDefinitionsEntries;
1386
  TargetPropertyEntryVector LinkOptionsEntries;
1387
  TargetPropertyEntryVector LinkDirectoriesEntries;
1388
  TargetPropertyEntryVector PrecompileHeadersEntries;
1389
  TargetPropertyEntryVector SourceEntries;
1390
  mutable std::set<std::string> LinkImplicitNullProperties;
1391
  mutable std::map<std::string, std::string> PchHeaders;
1392
  mutable std::map<std::string, std::string> PchSources;
1393
  mutable std::map<std::string, std::string> PchObjectFiles;
1394
  mutable std::map<std::string, std::string> PchFiles;
1395
  mutable std::map<std::string, std::string> PchCreateCompileOptions;
1396
  mutable std::map<std::string, std::string> PchUseCompileOptions;
1397
1398
  std::unordered_set<std::string> UnityBatchedSourceFiles;
1399
1400
  std::unordered_map<std::string, std::vector<std::string>>
1401
    ISPCGeneratedHeaders;
1402
  std::unordered_map<std::string,
1403
                     std::vector<std::pair<cmSourceFile const*, std::string>>>
1404
    ISPCGeneratedObjects;
1405
1406
  enum class LinkInterfaceField
1407
  {
1408
    Libraries,
1409
    HeadExclude,
1410
    HeadInclude,
1411
  };
1412
  void ExpandLinkItems(std::string const& prop, cmBTStringRange entries,
1413
                       std::string const& config,
1414
                       cmGeneratorTarget const* headTarget, UseTo usage,
1415
                       LinkInterfaceField field, cmLinkInterface& iface) const;
1416
1417
  struct LookupLinkItemScope
1418
  {
1419
    cmLocalGenerator const* LG;
1420
  };
1421
  enum class LookupSelf
1422
  {
1423
    No,
1424
    Yes,
1425
  };
1426
  cm::optional<cmLinkItem> LookupLinkItem(std::string const& n,
1427
                                          cmListFileBacktrace const& bt,
1428
                                          std::string const& linkFeature,
1429
                                          LookupLinkItemScope* scope,
1430
                                          LookupSelf lookupSelf) const;
1431
1432
  std::vector<BT<std::string>>& ResolvePrefixWrapper(
1433
    std::vector<BT<std::string>>& result, cm::string_view prefix,
1434
    std::string const& language, bool joinItems) const;
1435
1436
  std::vector<BT<std::string>> GetSourceFilePaths(
1437
    std::string const& config) const;
1438
  std::vector<BT<cmSourceFile*>> GetSourceFilesWithoutObjectLibraries(
1439
    std::string const& config) const;
1440
  void GetSourceFilesWithoutObjectLibraries(std::vector<cmSourceFile*>& files,
1441
                                            std::string const& config) const;
1442
1443
  using LinkImplMapType = std::map<std::string, cmOptionalLinkImplementation>;
1444
  mutable LinkImplMapType LinkImplMap;
1445
  mutable LinkImplMapType LinkImplUsageRequirementsOnlyMap;
1446
1447
  bool ComputeOutputDir(std::string const& config,
1448
                        cmStateEnums::ArtifactType artifact,
1449
                        std::string& out) const;
1450
1451
  using OutputInfoMapType = std::map<std::string, OutputInfo>;
1452
  mutable OutputInfoMapType OutputInfoMap;
1453
1454
  using PdbOutputNameMapType = std::map<std::string, std::string>;
1455
  mutable PdbOutputNameMapType PdbOutputNameMap;
1456
1457
  using ModuleDefinitionInfoMapType =
1458
    std::map<std::string, ModuleDefinitionInfo>;
1459
  mutable ModuleDefinitionInfoMapType ModuleDefinitionInfoMap;
1460
  void ComputeModuleDefinitionInfo(std::string const& config,
1461
                                   ModuleDefinitionInfo& info) const;
1462
1463
  using OutputNameKey = std::pair<std::string, cmStateEnums::ArtifactType>;
1464
  using OutputNameMapType = std::map<OutputNameKey, std::string>;
1465
  mutable OutputNameMapType OutputNameMap;
1466
  mutable std::set<cmLinkItem> UtilityItems;
1467
  cmPolicies::PolicyMap PolicyMap;
1468
  mutable bool PolicyReportedCMP0069 = false;
1469
  mutable bool DebugIncludesDone = false;
1470
  mutable bool DebugCompileOptionsDone = false;
1471
  mutable bool DebugCompileFeaturesDone = false;
1472
  mutable bool DebugCompileDefinitionsDone = false;
1473
  mutable bool DebugLinkOptionsDone = false;
1474
  mutable bool DebugLinkDirectoriesDone = false;
1475
  mutable bool DebugPrecompileHeadersDone = false;
1476
  mutable bool DebugSourcesDone = false;
1477
  mutable bool UtilityItemsDone = false;
1478
  enum class Tribool
1479
  {
1480
    False = 0x0,
1481
    True = 0x1,
1482
    Indeterminate = 0x2
1483
  };
1484
  mutable Tribool SourcesAreContextDependent = Tribool::Indeterminate;
1485
1486
  bool ComputePDBOutputDir(std::string const& kind, std::string const& config,
1487
                           std::string& out) const;
1488
1489
  ManagedType CheckManagedType(std::string const& propval) const;
1490
1491
  bool GetRPATH(std::string const& config, std::string const& prop,
1492
                std::string& rpath) const;
1493
1494
  std::map<std::string, BTs<std::string>> LanguageStandardMap;
1495
1496
  cm::optional<cmStandardLevel> GetExplicitStandardLevel(
1497
    std::string const& lang, std::string const& config) const;
1498
  void UpdateExplicitStandardLevel(std::string const& lang,
1499
                                   std::string const& config,
1500
                                   cmStandardLevel level);
1501
  std::map<std::string, cmStandardLevel> ExplicitStandardLevel;
1502
1503
  cmValue GetPropertyWithPairedLanguageSupport(std::string const& lang,
1504
                                               char const* suffix) const;
1505
1506
  std::vector<cmLinkItem> ComputeImplicitLanguageTargets(
1507
    std::string const& lang, std::string const& config) const;
1508
1509
  void ComputeLinkImplementationRuntimeLibraries(
1510
    std::string const& config, cmOptionalLinkImplementation& impl) const;
1511
1512
  void ComputeLinkInterfaceRuntimeLibraries(
1513
    std::string const& config, cmOptionalLinkInterface& iface) const;
1514
1515
  // If this method is made public, or call sites are added outside of
1516
  // methods computing cached members, add dedicated caching members.
1517
  std::vector<cmGeneratorTarget const*> GetLinkInterfaceClosure(
1518
    std::string const& config, cmGeneratorTarget const* headTarget,
1519
    UseTo usage) const;
1520
1521
public:
1522
  std::vector<cmGeneratorTarget const*> const& GetLinkImplementationClosure(
1523
    std::string const& config, UseTo usage) const;
1524
1525
  mutable std::map<std::string, std::string> MaxLanguageStandards;
1526
  std::map<std::string, std::string> const& GetMaxLanguageStandards() const
1527
0
  {
1528
0
    return this->MaxLanguageStandards;
1529
0
  }
1530
1531
  struct StrictTargetComparison
1532
  {
1533
    bool operator()(cmGeneratorTarget const* t1,
1534
                    cmGeneratorTarget const* t2) const;
1535
  };
1536
1537
  bool HaveFortranSources() const;
1538
  bool HaveFortranSources(std::string const& config) const;
1539
1540
  // File sets support queries
1541
1542
  bool HasFileSets() const;
1543
  cmGeneratorFileSets const* GetGeneratorFileSets() const
1544
0
  {
1545
0
    return this->FileSets.get();
1546
0
  }
1547
  std::vector<cmGeneratorFileSet const*> const& GetAllFileSets() const;
1548
  std::vector<cmGeneratorFileSet const*> const& GetFileSets(
1549
    cm::string_view type) const;
1550
  std::vector<cmGeneratorFileSet const*> const& GetInterfaceFileSets(
1551
    cm::string_view type) const;
1552
  cmGeneratorFileSet const* GetFileSet(std::string const& name) const;
1553
  cmGeneratorFileSet const* GetFileSetForSource(std::string const& config,
1554
                                                cmSourceFile const* sf) const;
1555
1556
  // C++20 module support queries.
1557
1558
  /**
1559
   * Query whether the target expects C++20 module support.
1560
   *
1561
   * This will inspect the target itself to see if C++20 module
1562
   * support is expected to work based on its sources.
1563
   */
1564
  bool HaveInterfaceCxx20ModuleSources() const;
1565
  bool HaveCxx20ModuleSources() const;
1566
1567
  enum class Cxx20SupportLevel
1568
  {
1569
    // C++ is not available.
1570
    MissingCxx,
1571
    // The target does not require at least C++20.
1572
    NoCxx20,
1573
    // C++20 module scanning rules are not present.
1574
    MissingRule,
1575
    // C++20 modules are available and working.
1576
    Supported,
1577
  };
1578
1579
  /**
1580
   * Query whether the target has C++20 module support available (regardless of
1581
   * whether it is required or not).
1582
   */
1583
  Cxx20SupportLevel HaveCxxModuleSupport(std::string const& config) const;
1584
1585
  // Check C++ module status for the target.
1586
  void CheckCxxModuleStatus(std::string const& config) const;
1587
1588
  bool NeedCxxModuleSupport(std::string const& lang,
1589
                            std::string const& config) const;
1590
  bool NeedDyndep(std::string const& lang, std::string const& config) const;
1591
  bool NeedDyndepForSource(std::string const& lang, std::string const& config,
1592
                           cmSourceFile const* sf) const;
1593
  enum class CxxModuleSupport
1594
  {
1595
    Unavailable,
1596
    Enabled,
1597
    Disabled,
1598
  };
1599
  CxxModuleSupport NeedCxxDyndep(std::string const& config) const;
1600
1601
  std::string BuildDatabasePath(std::string const& lang,
1602
                                std::string const& config) const;
1603
1604
  enum class MsvcCharSet
1605
  {
1606
    None,
1607
    Unicode,
1608
    MultiByte,
1609
    SingleByte,
1610
  };
1611
1612
  // Detect if the current define selects any known charset entry or not
1613
  static MsvcCharSet GetMsvcCharSet(std::string const& singleDefine);
1614
1615
private:
1616
  struct InfoByConfig
1617
  {
1618
    std::map<cmGeneratorTarget const*, std::set<cmGeneratorTarget const*>>
1619
      SyntheticDeps;
1620
    std::map<cmSourceFile const*, ClassifiedFlags> SourceFlags;
1621
  };
1622
  mutable std::map<std::string, cmGeneratorTarget*> SynthCxxTargets;
1623
  mutable std::map<std::string, cmCxxModuleUsageEffects> CxxModuleUsageEffects;
1624
  mutable std::map<std::string, InfoByConfig> Configs;
1625
  std::unique_ptr<cmGeneratorFileSets> FileSets;
1626
  bool PchReused = false;
1627
  mutable bool ComputingPchReuse = false;
1628
  mutable bool PchReuseCycleDetected = false;
1629
};