Coverage Report

Created: 2026-02-09 06:05

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