Coverage Report

Created: 2026-06-15 07:03

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