Coverage Report

Created: 2026-04-29 07:01

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