resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmGeneratorTarget.h
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #pragma once
4
5 #include "cmConfigure.h" // IWYU pragma: keep
6
7 #include <cstddef>
8 #include <map>
9 #include <memory>
10 #include <set>
11 #include <string>
12 #include <unordered_map>
13 #include <unordered_set>
14 #include <utility>
15 #include <vector>
16
17 #include <cm/optional>
18
19 #include "cmAlgorithms.h"
20 #include "cmLinkItem.h"
21 #include "cmListFileCache.h"
22 #include "cmPolicies.h"
23 #include "cmStateTypes.h"
24 #include "cmValue.h"
25
26 enum class cmBuildStep;
27 class cmComputeLinkInformation;
28 class cmCustomCommand;
29 class cmGlobalGenerator;
30 class cmLocalGenerator;
31 class cmMakefile;
32 class cmSourceFile;
33 class cmTarget;
34
35 struct cmGeneratorExpressionContext;
36 struct cmGeneratorExpressionDAGChecker;
37
38 class cmGeneratorTarget
39 {
40 public:
41   cmGeneratorTarget(cmTarget*, cmLocalGenerator* lg);
42   ~cmGeneratorTarget();
43
44   cmGeneratorTarget(cmGeneratorTarget const&) = delete;
45   cmGeneratorTarget& operator=(cmGeneratorTarget const&) = delete;
46
47   cmLocalGenerator* GetLocalGenerator() const;
48
49   cmGlobalGenerator* GetGlobalGenerator() const;
50
51   bool IsInBuildSystem() const;
52   bool IsImported() const;
53   bool IsImportedGloballyVisible() const;
54   bool CanCompileSources() const;
55   const std::string& GetLocation(const std::string& config) const;
56
57   /** Get the full path to the target's main artifact, if known.  */
58   cm::optional<std::string> MaybeGetLocation(std::string const& config) const;
59
60   std::vector<cmCustomCommand> const& GetPreBuildCommands() const;
61   std::vector<cmCustomCommand> const& GetPreLinkCommands() const;
62   std::vector<cmCustomCommand> const& GetPostBuildCommands() const;
63
64   void AppendCustomCommandSideEffects(
65     std::set<cmGeneratorTarget const*>& sideEffects) const;
66   void AppendLanguageSideEffects(
67     std::map<std::string, std::set<cmGeneratorTarget const*>>& sideEffects)
68     const;
69
70 #define DECLARE_TARGET_POLICY(POLICY)                                         \
71   cmPolicies::PolicyStatus GetPolicyStatus##POLICY() const                    \
72   {                                                                           \
73     return this->PolicyMap.Get(cmPolicies::POLICY);                           \
74   }
75
76   CM_FOR_EACH_TARGET_POLICY(DECLARE_TARGET_POLICY)
77
78 #undef DECLARE_TARGET_POLICY
79
80   /** Get the location of the target in the build tree with a placeholder
81       referencing the configuration in the native build system.  This
82       location is suitable for use as the LOCATION target property.  */
83   const std::string& GetLocationForBuild() const;
84
85   cmComputeLinkInformation* GetLinkInformation(
86     const std::string& config) const;
87
88   // Perform validation checks on memoized link structures.
89   // Call this after generation is complete.
90   void CheckLinkLibraries() const;
91
92   cmStateEnums::TargetType GetType() const;
93   const std::string& GetName() const;
94   std::string GetExportName() const;
95
96   std::vector<std::string> GetPropertyKeys() const;
97   //! Might return a nullptr if the property is not set or invalid
98   cmValue GetProperty(const std::string& prop) const;
99   //! Always returns a valid pointer
100   std::string const& GetSafeProperty(std::string const& prop) const;
101   bool GetPropertyAsBool(const std::string& prop) const;
102   void GetSourceFiles(std::vector<cmSourceFile*>& files,
103                       const std::string& config) const;
104   std::vector<BT<cmSourceFile*>> GetSourceFiles(
105     std::string const& config) const;
106
107   /** Source file kinds (classifications).
108       Generators use this to decide how to treat a source file.  */
109   enum SourceKind
110   {
111     SourceKindAppManifest,
112     SourceKindCertificate,
113     SourceKindCustomCommand,
114     SourceKindExternalObject,
115     SourceKindExtra,
116     SourceKindHeader,
117     SourceKindIDL,
118     SourceKindManifest,
119     SourceKindModuleDefinition,
120     SourceKindObjectSource,
121     SourceKindResx,
122     SourceKindXaml,
123     SourceKindUnityBatched
124   };
125
126   /** A source file paired with a kind (classification).  */
127   struct SourceAndKind
128   {
129     BT<cmSourceFile*> Source;
130     SourceKind Kind;
131   };
132
133   /** All sources needed for a configuration with kinds assigned.  */
134   struct KindedSources
135   {
136     std::vector<SourceAndKind> Sources;
137     bool Initialized = false;
138   };
139
140   /** Get all sources needed for a configuration with kinds assigned.  */
141   KindedSources const& GetKindedSources(std::string const& config) const;
142
143   struct AllConfigSource
144   {
145     cmSourceFile* Source;
146     cmGeneratorTarget::SourceKind Kind;
147     std::vector<size_t> Configs;
148   };
149
150   /** Get all sources needed for all configurations with kinds and
151       per-source configurations assigned.  */
152   std::vector<AllConfigSource> const& GetAllConfigSources() const;
153
154   /** Get all sources needed for all configurations with given kind.  */
155   std::vector<AllConfigSource> GetAllConfigSources(SourceKind kind) const;
156
157   /** Get all languages used to compile sources in any configuration.
158       This excludes the languages of objects from object libraries.  */
159   std::set<std::string> GetAllConfigCompileLanguages() const;
160
161   void GetObjectSources(std::vector<cmSourceFile const*>&,
162                         const std::string& config) const;
163   const std::string& GetObjectName(cmSourceFile const* file);
164   const char* GetCustomObjectExtension() const;
165
166   bool HasExplicitObjectName(cmSourceFile const* file) const;
167   void AddExplicitObjectName(cmSourceFile const* sf);
168
169   BTs<std::string> const* GetLanguageStandardProperty(
170     std::string const& lang, std::string const& config) const;
171
172   cmValue GetLanguageStandard(std::string const& lang,
173                               std::string const& config) const;
174
175   cmValue GetLanguageExtensions(std::string const& lang) const;
176
177   bool GetLanguageStandardRequired(std::string const& lang) const;
178
179   void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&,
180                                   const std::string& config) const;
181   void GetExternalObjects(std::vector<cmSourceFile const*>&,
182                           const std::string& config) const;
183   void GetHeaderSources(std::vector<cmSourceFile const*>&,
184                         const std::string& config) const;
185   void GetExtraSources(std::vector<cmSourceFile const*>&,
186                        const std::string& config) const;
187   void GetCustomCommands(std::vector<cmSourceFile const*>&,
188                          const std::string& config) const;
189   void GetManifests(std::vector<cmSourceFile const*>&,
190                     const std::string& config) const;
191
192   std::set<cmLinkItem> const& GetUtilityItems() const;
193
194   void ComputeObjectMapping();
195
196   cmValue GetFeature(const std::string& feature,
197                      const std::string& config) const;
198
199   const char* GetLinkPIEProperty(const std::string& config) const;
200
201   bool IsIPOEnabled(std::string const& lang, std::string const& config) const;
202
203   bool IsLinkInterfaceDependentBoolProperty(const std::string& p,
204                                             const std::string& config) const;
205   bool IsLinkInterfaceDependentStringProperty(const std::string& p,
206                                               const std::string& config) const;
207   bool IsLinkInterfaceDependentNumberMinProperty(
208     const std::string& p, const std::string& config) const;
209   bool IsLinkInterfaceDependentNumberMaxProperty(
210     const std::string& p, const std::string& config) const;
211
212   bool GetLinkInterfaceDependentBoolProperty(const std::string& p,
213                                              const std::string& config) const;
214
215   const char* GetLinkInterfaceDependentStringProperty(
216     const std::string& p, const std::string& config) const;
217   const char* GetLinkInterfaceDependentNumberMinProperty(
218     const std::string& p, const std::string& config) const;
219   const char* GetLinkInterfaceDependentNumberMaxProperty(
220     const std::string& p, const std::string& config) const;
221
222   class DeviceLinkSetter
223   {
224   public:
225     DeviceLinkSetter(cmGeneratorTarget& target)
226       : Target(target)
227     {
228       this->PreviousState = target.SetDeviceLink(true);
229     }
230     ~DeviceLinkSetter() { this->Target.SetDeviceLink(this->PreviousState); }
231
232   private:
233     cmGeneratorTarget& Target;
234     bool PreviousState;
235   };
236
237   bool SetDeviceLink(bool deviceLink);
238   bool IsDeviceLink() const { return this->DeviceLink; }
239
240   cmLinkInterface const* GetLinkInterface(
241     const std::string& config, const cmGeneratorTarget* headTarget) const;
242   void ComputeLinkInterface(const std::string& config,
243                             cmOptionalLinkInterface& iface,
244                             const cmGeneratorTarget* head) const;
245
246   enum class LinkInterfaceFor
247   {
248     Usage, // Interface for usage requirements excludes $<LINK_ONLY>.
249     Link,  // Interface for linking includes $<LINK_ONLY>.
250   };
251
252   cmLinkInterfaceLibraries const* GetLinkInterfaceLibraries(
253     const std::string& config, const cmGeneratorTarget* headTarget,
254     LinkInterfaceFor interfaceFor) const;
255
256   void ComputeLinkInterfaceLibraries(const std::string& config,
257                                      cmOptionalLinkInterface& iface,
258                                      const cmGeneratorTarget* head,
259                                      LinkInterfaceFor interfaceFor) const;
260
261   /** Get the library name for an imported interface library.  */
262   std::string GetImportedLibName(std::string const& config) const;
263
264   /** Get the full path to the target according to the settings in its
265       makefile and the configuration type.  */
266   std::string GetFullPath(
267     const std::string& config,
268     cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact,
269     bool realname = false) const;
270   std::string NormalGetFullPath(const std::string& config,
271                                 cmStateEnums::ArtifactType artifact,
272                                 bool realname) const;
273   std::string NormalGetRealName(const std::string& config) const;
274
275   /** Get the names of an object library's object files underneath
276       its object file directory.  */
277   void GetTargetObjectNames(std::string const& config,
278                             std::vector<std::string>& objects) const;
279
280   /** What hierarchy level should the reported directory contain */
281   enum BundleDirectoryLevel
282   {
283     BundleDirLevel,
284     ContentLevel,
285     FullLevel
286   };
287
288   /** @return the Mac App directory without the base */
289   std::string GetAppBundleDirectory(const std::string& config,
290                                     BundleDirectoryLevel level) const;
291
292   /** Return whether this target is marked as deprecated by the
293       maintainer  */
294   bool IsDeprecated() const;
295
296   /** Returns the deprecation message provided by the maintainer */
297   std::string GetDeprecation() const;
298
299   /** Return whether this target is an executable Bundle, a framework
300       or CFBundle on Apple.  */
301   bool IsBundleOnApple() const;
302
303   /** Return whether this target is a Win32 executable */
304   bool IsWin32Executable(const std::string& config) const;
305
306   /** Get the full name of the target according to the settings in its
307       makefile.  */
308   std::string GetFullName(const std::string& config,
309                           cmStateEnums::ArtifactType artifact =
310                             cmStateEnums::RuntimeBinaryArtifact) const;
311
312   /** @return the Mac framework directory without the base. */
313   std::string GetFrameworkDirectory(const std::string& config,
314                                     BundleDirectoryLevel level) const;
315
316   /** Return the framework version string.  Undefined if
317       IsFrameworkOnApple returns false.  */
318   std::string GetFrameworkVersion() const;
319
320   /** @return the Mac CFBundle directory without the base */
321   std::string GetCFBundleDirectory(const std::string& config,
322                                    BundleDirectoryLevel level) const;
323
324   /** Return the install name directory for the target in the
325    * build tree.  For example: "\@rpath/", "\@loader_path/",
326    * or "/full/path/to/library".  */
327   std::string GetInstallNameDirForBuildTree(const std::string& config) const;
328
329   /** Return the install name directory for the target in the
330    * install tree.  For example: "\@rpath/" or "\@loader_path/". */
331   std::string GetInstallNameDirForInstallTree(
332     const std::string& config, const std::string& installPrefix) const;
333
334   cmListFileBacktrace GetBacktrace() const;
335
336   std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
337
338   bool LinkLanguagePropagatesToDependents() const
339   {
340     return this->GetType() == cmStateEnums::STATIC_LIBRARY;
341   }
342
343   /** Get the macro to define when building sources in this target.
344       If no macro should be defined null is returned.  */
345   const std::string* GetExportMacro() const;
346
347   /** Get the soname of the target.  Allowed only for a shared library.  */
348   std::string GetSOName(const std::string& config) const;
349
350   void GetFullNameComponents(std::string& prefix, std::string& base,
351                              std::string& suffix, const std::string& config,
352                              cmStateEnums::ArtifactType artifact =
353                                cmStateEnums::RuntimeBinaryArtifact) const;
354
355   /** Append to @a base the bundle directory hierarchy up to a certain @a level
356    * and return it. */
357   std::string BuildBundleDirectory(const std::string& base,
358                                    const std::string& config,
359                                    BundleDirectoryLevel level) const;
360
361   /** @return the mac content directory for this target. */
362   std::string GetMacContentDirectory(
363     const std::string& config, cmStateEnums::ArtifactType artifact) const;
364
365   /** @return folder prefix for IDEs. */
366   std::string GetEffectiveFolderName() const;
367
368   cmTarget* Target;
369   cmMakefile* Makefile;
370   cmLocalGenerator* LocalGenerator;
371   cmGlobalGenerator const* GlobalGenerator;
372
373   struct ModuleDefinitionInfo
374   {
375     std::string DefFile;
376     bool DefFileGenerated;
377     bool WindowsExportAllSymbols;
378     std::vector<cmSourceFile const*> Sources;
379   };
380   ModuleDefinitionInfo const* GetModuleDefinitionInfo(
381     std::string const& config) const;
382
383   /** Return whether or not the target is for a DLL platform.  */
384   bool IsDLLPlatform() const;
385
386   /** @return whether this target have a well defined output file name. */
387   bool HaveWellDefinedOutputFiles() const;
388
389   /** Link information from the transitive closure of the link
390       implementation and the interfaces of its dependencies.  */
391   struct LinkClosure
392   {
393     // The preferred linker language.
394     std::string LinkerLanguage;
395
396     // Languages whose runtime libraries must be linked.
397     std::vector<std::string> Languages;
398   };
399
400   LinkClosure const* GetLinkClosure(const std::string& config) const;
401
402   cmLinkImplementation const* GetLinkImplementation(
403     const std::string& config, LinkInterfaceFor implFor) const;
404
405   void ComputeLinkImplementationLanguages(
406     const std::string& config, cmOptionalLinkImplementation& impl) const;
407
408   cmLinkImplementationLibraries const* GetLinkImplementationLibraries(
409     const std::string& config, LinkInterfaceFor implFor) const;
410
411   void ComputeLinkImplementationLibraries(const std::string& config,
412                                           cmOptionalLinkImplementation& impl,
413                                           const cmGeneratorTarget* head,
414                                           LinkInterfaceFor implFor) const;
415
416   struct TargetOrString
417   {
418     std::string String;
419     cmGeneratorTarget* Target = nullptr;
420   };
421   TargetOrString ResolveTargetReference(std::string const& name) const;
422   TargetOrString ResolveTargetReference(std::string const& name,
423                                         cmLocalGenerator const* lg) const;
424
425   cmLinkItem ResolveLinkItem(BT<std::string> const& name) const;
426   cmLinkItem ResolveLinkItem(BT<std::string> const& name,
427                              cmLocalGenerator const* lg) const;
428
429   bool HasPackageReferences() const;
430   std::vector<std::string> GetPackageReferences() const;
431
432   // Compute the set of languages compiled by the target.  This is
433   // computed every time it is called because the languages can change
434   // when source file properties are changed and we do not have enough
435   // information to forward these property changes to the targets
436   // until we have per-target object file properties.
437   void GetLanguages(std::set<std::string>& languages,
438                     std::string const& config) const;
439   bool IsLanguageUsed(std::string const& language,
440                       std::string const& config) const;
441
442   bool IsCSharpOnly() const;
443
444   bool IsDotNetSdkTarget() const;
445
446   void GetObjectLibrariesCMP0026(
447     std::vector<cmGeneratorTarget*>& objlibs) const;
448
449   std::string GetFullNameImported(const std::string& config,
450                                   cmStateEnums::ArtifactType artifact) const;
451
452   /** Get source files common to all configurations and diagnose cases
453       with per-config sources.  Excludes sources added by a TARGET_OBJECTS
454       generator expression.  Do not use outside the Xcode generator.  */
455   bool GetConfigCommonSourceFilesForXcode(
456     std::vector<cmSourceFile*>& files) const;
457
458   bool HaveBuildTreeRPATH(const std::string& config) const;
459
460   /** Full path with trailing slash to the top-level directory
461       holding object files for this target.  Includes the build
462       time config name placeholder if needed for the generator.  */
463   std::string ObjectDirectory;
464
465   /** Full path with trailing slash to the top-level directory
466       holding object files for the given configuration.  */
467   std::string GetObjectDirectory(std::string const& config) const;
468
469   void GetAppleArchs(const std::string& config,
470                      std::vector<std::string>& archVec) const;
471
472   void AddExplicitLanguageFlags(std::string& flags,
473                                 cmSourceFile const& sf) const;
474
475   void AddCUDAArchitectureFlags(cmBuildStep compileOrLink,
476                                 const std::string& config,
477                                 std::string& flags) const;
478   void AddCUDAToolkitFlags(std::string& flags) const;
479
480   void AddHIPArchitectureFlags(std::string& flags) const;
481
482   void AddISPCTargetFlags(std::string& flags) const;
483
484   std::string GetFeatureSpecificLinkRuleVariable(
485     std::string const& var, std::string const& lang,
486     std::string const& config) const;
487
488   /** Return the rule variable used to create this type of target.  */
489   std::string GetCreateRuleVariable(std::string const& lang,
490                                     std::string const& config) const;
491
492   /** Get the include directories for this target.  */
493   std::vector<BT<std::string>> GetIncludeDirectories(
494     const std::string& config, const std::string& lang) const;
495
496   void GetCompileOptions(std::vector<std::string>& result,
497                          const std::string& config,
498                          const std::string& language) const;
499   std::vector<BT<std::string>> GetCompileOptions(
500     std::string const& config, std::string const& language) const;
501
502   void GetCompileFeatures(std::vector<std::string>& features,
503                           const std::string& config) const;
504   std::vector<BT<std::string>> GetCompileFeatures(
505     std::string const& config) const;
506
507   void GetCompileDefinitions(std::vector<std::string>& result,
508                              const std::string& config,
509                              const std::string& language) const;
510   std::vector<BT<std::string>> GetCompileDefinitions(
511     std::string const& config, std::string const& language) const;
512
513   void GetLinkOptions(std::vector<std::string>& result,
514                       const std::string& config,
515                       const std::string& language) const;
516   std::vector<BT<std::string>> GetLinkOptions(
517     std::string const& config, std::string const& language) const;
518
519   std::vector<BT<std::string>>& ResolveLinkerWrapper(
520     std::vector<BT<std::string>>& result, const std::string& language,
521     bool joinItems = false) const;
522
523   void GetStaticLibraryLinkOptions(std::vector<std::string>& result,
524                                    const std::string& config,
525                                    const std::string& language) const;
526   std::vector<BT<std::string>> GetStaticLibraryLinkOptions(
527     std::string const& config, std::string const& language) const;
528
529   void GetLinkDirectories(std::vector<std::string>& result,
530                           const std::string& config,
531                           const std::string& language) const;
532   std::vector<BT<std::string>> GetLinkDirectories(
533     std::string const& config, std::string const& language) const;
534
535   void GetLinkDepends(std::vector<std::string>& result,
536                       const std::string& config,
537                       const std::string& language) const;
538   std::vector<BT<std::string>> GetLinkDepends(
539     std::string const& config, std::string const& language) const;
540
541   std::vector<BT<std::string>> GetPrecompileHeaders(
542     const std::string& config, const std::string& language) const;
543
544   std::string GetPchHeader(const std::string& config,
545                            const std::string& language,
546                            const std::string& arch = std::string()) const;
547   std::string GetPchSource(const std::string& config,
548                            const std::string& language,
549                            const std::string& arch = std::string()) const;
550   std::string GetPchFileObject(const std::string& config,
551                                const std::string& language,
552                                const std::string& arch = std::string());
553   std::string GetPchFile(const std::string& config,
554                          const std::string& language,
555                          const std::string& arch = std::string());
556   std::string GetPchCreateCompileOptions(
557     const std::string& config, const std::string& language,
558     const std::string& arch = std::string());
559   std::string GetPchUseCompileOptions(const std::string& config,
560                                       const std::string& language,
561                                       const std::string& arch = std::string());
562
563   void AddSourceFileToUnityBatch(const std::string& sourceFilename);
564   bool IsSourceFilePartOfUnityBatch(const std::string& sourceFilename) const;
565
566   bool IsSystemIncludeDirectory(const std::string& dir,
567                                 const std::string& config,
568                                 const std::string& language) const;
569
570   /** Add the target output files to the global generator manifest.  */
571   void ComputeTargetManifest(const std::string& config) const;
572
573   bool ComputeCompileFeatures(std::string const& config) const;
574
575   using LanguagePair = std::pair<std::string, std::string>;
576   bool ComputeCompileFeatures(
577     std::string const& config,
578     std::set<LanguagePair> const& languagePairs) const;
579
580   /**
581    * Trace through the source files in this target and add al source files
582    * that they depend on, used by all generators
583    */
584   void TraceDependencies();
585
586   /** Get the directory in which this target will be built.  If the
587       configuration name is given then the generator will add its
588       subdirectory for that configuration.  Otherwise just the canonical
589       output directory is given.  */
590   std::string GetDirectory(const std::string& config,
591                            cmStateEnums::ArtifactType artifact =
592                              cmStateEnums::RuntimeBinaryArtifact) const;
593
594   /** Get the directory in which to place the target compiler .pdb file.
595       If the configuration name is given then the generator will add its
596       subdirectory for that configuration.  Otherwise just the canonical
597       compiler pdb output directory is given.  */
598   std::string GetCompilePDBDirectory(const std::string& config) const;
599
600   /** Get sources that must be built before the given source.  */
601   std::vector<cmSourceFile*> const* GetSourceDepends(
602     cmSourceFile const* sf) const;
603
604   /** Return whether this target uses the default value for its output
605       directory.  */
606   bool UsesDefaultOutputDir(const std::string& config,
607                             cmStateEnums::ArtifactType artifact) const;
608
609   // Cache target output paths for each configuration.
610   struct OutputInfo
611   {
612     std::string OutDir;
613     std::string ImpDir;
614     std::string PdbDir;
615     bool empty() const
616     {
617       return this->OutDir.empty() && this->ImpDir.empty() &&
618         this->PdbDir.empty();
619     }
620   };
621
622   OutputInfo const* GetOutputInfo(const std::string& config) const;
623
624   // Get the target PDB base name.
625   std::string GetPDBOutputName(const std::string& config) const;
626
627   /** Get the name of the pdb file for the target.  */
628   std::string GetPDBName(const std::string& config) const;
629
630   /** Whether this library has soname enabled and platform supports it.  */
631   bool HasSOName(const std::string& config) const;
632
633   struct CompileInfo
634   {
635     std::string CompilePdbDir;
636   };
637
638   CompileInfo const* GetCompileInfo(const std::string& config) const;
639
640   using CompileInfoMapType = std::map<std::string, CompileInfo>;
641   mutable CompileInfoMapType CompileInfoMap;
642
643   bool IsNullImpliedByLinkLibraries(const std::string& p) const;
644
645   /** Get the name of the compiler pdb file for the target.  */
646   std::string GetCompilePDBName(const std::string& config) const;
647
648   /** Get the path for the MSVC /Fd option for this target.  */
649   std::string GetCompilePDBPath(const std::string& config) const;
650
651   // Get the target base name.
652   std::string GetOutputName(const std::string& config,
653                             cmStateEnums::ArtifactType artifact) const;
654
655   /** Get target file prefix */
656   std::string GetFilePrefix(const std::string& config,
657                             cmStateEnums::ArtifactType artifact =
658                               cmStateEnums::RuntimeBinaryArtifact) const;
659   /** Get target file prefix */
660   std::string GetFileSuffix(const std::string& config,
661                             cmStateEnums::ArtifactType artifact =
662                               cmStateEnums::RuntimeBinaryArtifact) const;
663
664   /** Get target file postfix */
665   std::string GetFilePostfix(const std::string& config) const;
666
667   /** Get framework multi-config-specific postfix */
668   std::string GetFrameworkMultiConfigPostfix(const std::string& config) const;
669
670   /** Clears cached meta data for local and external source files.
671    * The meta data will be recomputed on demand.
672    */
673   void ClearSourcesCache();
674
675   // Do not use.  This is only for a specific call site with a FIXME comment.
676   void ClearLinkInterfaceCache();
677
678   void AddSource(const std::string& src, bool before = false);
679   void AddTracedSources(std::vector<std::string> const& srcs);
680
681   /**
682    * Adds an entry to the INCLUDE_DIRECTORIES list.
683    * If before is true the entry is pushed at the front.
684    */
685   void AddIncludeDirectory(const std::string& src, bool before = false);
686
687   /**
688    * Flags for a given source file as used in this target. Typically assigned
689    * via SET_TARGET_PROPERTIES when the property is a list of source files.
690    */
691   enum SourceFileType
692   {
693     SourceFileTypeNormal,
694     SourceFileTypePrivateHeader, // is in "PRIVATE_HEADER" target property
695     SourceFileTypePublicHeader,  // is in "PUBLIC_HEADER" target property
696     SourceFileTypeResource,      // is in "RESOURCE" target property *or*
697                                  // has MACOSX_PACKAGE_LOCATION=="Resources"
698     SourceFileTypeDeepResource,  // MACOSX_PACKAGE_LOCATION starts with
699                                  // "Resources/"
700     SourceFileTypeMacContent     // has MACOSX_PACKAGE_LOCATION!="Resources[/]"
701   };
702   struct SourceFileFlags
703   {
704     SourceFileType Type = SourceFileTypeNormal;
705     const char* MacFolder = nullptr; // location inside Mac content folders
706   };
707   void GetAutoUicOptions(std::vector<std::string>& result,
708                          const std::string& config) const;
709
710   struct Names
711   {
712     std::string Base;
713     std::string Output;
714     std::string Real;
715     std::string ImportLibrary;
716     std::string PDB;
717     std::string SharedObject;
718   };
719
720   /** Get the names of the executable needed to generate a build rule
721       that takes into account executable version numbers.  This should
722       be called only on an executable target.  */
723   Names GetExecutableNames(const std::string& config) const;
724
725   /** Get the names of the library needed to generate a build rule
726       that takes into account shared library version numbers.  This
727       should be called only on a library target.  */
728   Names GetLibraryNames(const std::string& config) const;
729
730   /**
731    * Compute whether this target must be relinked before installing.
732    */
733   bool NeedRelinkBeforeInstall(const std::string& config) const;
734
735   /** Return true if builtin chrpath will work for this target */
736   bool IsChrpathUsed(const std::string& config) const;
737
738   /** Get the directory in which this targets .pdb files will be placed.
739       If the configuration name is given then the generator will add its
740       subdirectory for that configuration.  Otherwise just the canonical
741       pdb output directory is given.  */
742   std::string GetPDBDirectory(const std::string& config) const;
743
744   //! Return the preferred linker language for this target
745   std::string GetLinkerLanguage(const std::string& config) const;
746
747   /** Does this target have a GNU implib to convert to MS format?  */
748   bool HasImplibGNUtoMS(std::string const& config) const;
749
750   /** Convert the given GNU import library name (.dll.a) to a name with a new
751       extension (.lib or ${CMAKE_IMPORT_LIBRARY_SUFFIX}).  */
752   bool GetImplibGNUtoMS(std::string const& config, std::string const& gnuName,
753                         std::string& out, const char* newExt = nullptr) const;
754
755   /** Can only ever return true if GetSourceFilePaths() was called before.
756       Otherwise, this is indeterminate and false will be assumed/returned!  */
757   bool HasContextDependentSources() const;
758
759   bool IsExecutableWithExports() const;
760
761   /** Return whether or not the target has a DLL import library.  */
762   bool HasImportLibrary(std::string const& config) const;
763
764   /** Get a build-tree directory in which to place target support files.  */
765   std::string GetSupportDirectory() const;
766
767   /** Return whether this target may be used to link another target.  */
768   bool IsLinkable() const;
769
770   /** Return whether this target is a shared library Framework on
771       Apple.  */
772   bool IsFrameworkOnApple() const;
773
774   /** Return whether this target is an executable Bundle on Apple.  */
775   bool IsAppBundleOnApple() const;
776
777   /** Return whether this target is a XCTest on Apple.  */
778   bool IsXCTestOnApple() const;
779
780   /** Return whether this target is a CFBundle (plugin) on Apple.  */
781   bool IsCFBundleOnApple() const;
782
783   /** Assembly types. The order of the values of this enum is relevant
784       because of smaller/larger comparison operations! */
785   enum ManagedType
786   {
787     Undefined = 0, // target is no lib or executable
788     Native,        // target compiles to unmanaged binary.
789     Mixed,         // target compiles to mixed (managed and unmanaged) binary.
790     Managed        // target compiles to managed binary.
791   };
792
793   /** Return the type of assembly this target compiles to. */
794   ManagedType GetManagedType(const std::string& config) const;
795
796   struct SourceFileFlags GetTargetSourceFileFlags(
797     const cmSourceFile* sf) const;
798
799   void ReportPropertyOrigin(const std::string& p, const std::string& result,
800                             const std::string& report,
801                             const std::string& compatibilityType) const;
802
803   class TargetPropertyEntry;
804
805   std::string EvaluateInterfaceProperty(
806     std::string const& prop, cmGeneratorExpressionContext* context,
807     cmGeneratorExpressionDAGChecker* dagCheckerParent,
808     LinkInterfaceFor interfaceFor = LinkInterfaceFor::Usage) const;
809
810   bool HaveInstallTreeRPATH(const std::string& config) const;
811
812   bool GetBuildRPATH(const std::string& config, std::string& rpath) const;
813   bool GetInstallRPATH(const std::string& config, std::string& rpath) const;
814
815   /** Whether this library has \@rpath and platform supports it.  */
816   bool HasMacOSXRpathInstallNameDir(const std::string& config) const;
817
818   /** Whether this library defaults to \@rpath.  */
819   bool MacOSXRpathInstallNameDirDefault() const;
820
821   enum InstallNameType
822   {
823     INSTALL_NAME_FOR_BUILD,
824     INSTALL_NAME_FOR_INSTALL
825   };
826   /** Whether to use INSTALL_NAME_DIR. */
827   bool MacOSXUseInstallNameDir() const;
828   /** Whether to generate an install_name. */
829   bool CanGenerateInstallNameDir(InstallNameType t) const;
830
831   /** Test for special case of a third-party shared library that has
832       no soname at all.  */
833   bool IsImportedSharedLibWithoutSOName(const std::string& config) const;
834
835   std::string ImportedGetLocation(const std::string& config) const;
836
837   /** Get the target major and minor version numbers interpreted from
838       the VERSION property.  Version 0 is returned if the property is
839       not set or cannot be parsed.  */
840   void GetTargetVersion(int& major, int& minor) const;
841
842   /** Get the target major, minor, and patch version numbers
843       interpreted from the given property.  Version 0
844       is returned if the property is not set or cannot be parsed.  */
845   void GetTargetVersion(std::string const& property, int& major, int& minor,
846                         int& patch) const;
847
848   /** Get the target major, minor, and patch version numbers
849       interpreted from the given property and if empty use the
850       fallback property.  Version 0 is returned if the property is
851       not set or cannot be parsed.  */
852   void GetTargetVersionFallback(const std::string& property,
853                                 const std::string& fallback_property,
854                                 int& major, int& minor, int& patch) const;
855
856   std::string GetRuntimeLinkLibrary(std::string const& lang,
857                                     std::string const& config) const;
858
859   std::string GetFortranModuleDirectory(std::string const& working_dir) const;
860   bool IsFortranBuildingInstrinsicModules() const;
861
862   bool IsLinkLookupScope(std::string const& n,
863                          cmLocalGenerator const*& lg) const;
864
865   cmValue GetSourcesProperty() const;
866
867   void AddISPCGeneratedHeader(std::string const& header,
868                               std::string const& config);
869   std::vector<std::string> GetGeneratedISPCHeaders(
870     std::string const& config) const;
871
872   void AddISPCGeneratedObject(std::vector<std::string>&& objs,
873                               std::string const& config);
874   std::vector<std::string> GetGeneratedISPCObjects(
875     std::string const& config) const;
876
877   bool AddHeaderSetVerification();
878   std::string GenerateHeaderSetVerificationFile(
879     cmSourceFile& source, const std::string& dir,
880     cm::optional<std::set<std::string>>& languages) const;
881
882 private:
883   void AddSourceCommon(const std::string& src, bool before = false);
884
885   std::string CreateFortranModuleDirectory(
886     std::string const& working_dir) const;
887   mutable bool FortranModuleDirectoryCreated = false;
888   mutable std::string FortranModuleDirectory;
889
890   friend class cmTargetTraceDependencies;
891   struct SourceEntry
892   {
893     std::vector<cmSourceFile*> Depends;
894   };
895   using SourceEntriesType = std::map<cmSourceFile const*, SourceEntry>;
896   SourceEntriesType SourceDepends;
897   mutable std::set<std::string> VisitedConfigsForObjects;
898   mutable std::map<cmSourceFile const*, std::string> Objects;
899   std::set<cmSourceFile const*> ExplicitObjectName;
900
901   using TargetPtrToBoolMap = std::unordered_map<cmTarget*, bool>;
902   mutable std::unordered_map<std::string, TargetPtrToBoolMap>
903     MacOSXRpathInstallNameDirCache;
904   bool DetermineHasMacOSXRpathInstallNameDir(const std::string& config) const;
905
906   // "config/language" is the key
907   mutable std::map<std::string, std::vector<std::string>> SystemIncludesCache;
908
909   mutable std::string ExportMacro;
910
911   void ConstructSourceFileFlags() const;
912   mutable bool SourceFileFlagsConstructed = false;
913   mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
914
915   mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
916
917   bool NeedImportLibraryName(std::string const& config) const;
918
919   cmValue GetFilePrefixInternal(std::string const& config,
920                                 cmStateEnums::ArtifactType artifact,
921                                 const std::string& language = "") const;
922   cmValue GetFileSuffixInternal(std::string const& config,
923                                 cmStateEnums::ArtifactType artifact,
924                                 const std::string& language = "") const;
925
926   std::string GetFullNameInternal(const std::string& config,
927                                   cmStateEnums::ArtifactType artifact) const;
928   void GetFullNameInternal(const std::string& config,
929                            cmStateEnums::ArtifactType artifact,
930                            std::string& outPrefix, std::string& outBase,
931                            std::string& outSuffix) const;
932
933   mutable std::string LinkerLanguage;
934   using LinkClosureMapType = std::map<std::string, LinkClosure>;
935   mutable LinkClosureMapType LinkClosureMap;
936   bool DeviceLink = false;
937
938   // Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
939   const char* GetOutputTargetType(cmStateEnums::ArtifactType artifact) const;
940
941   void ComputeVersionedName(std::string& vName, std::string const& prefix,
942                             std::string const& base, std::string const& suffix,
943                             std::string const& name, cmValue version) const;
944
945   struct CompatibleInterfacesBase
946   {
947     std::set<std::string> PropsBool;
948     std::set<std::string> PropsString;
949     std::set<std::string> PropsNumberMax;
950     std::set<std::string> PropsNumberMin;
951   };
952   CompatibleInterfacesBase const& GetCompatibleInterfaces(
953     std::string const& config) const;
954
955   struct CompatibleInterfaces : public CompatibleInterfacesBase
956   {
957     bool Done = false;
958   };
959   mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
960
961   using cmTargetLinkInformationMap =
962     std::map<std::string, std::unique_ptr<cmComputeLinkInformation>>;
963   mutable cmTargetLinkInformationMap LinkInformation;
964
965   void CheckPropertyCompatibility(cmComputeLinkInformation& info,
966                                   const std::string& config) const;
967
968   void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
969   bool ComputeLinkClosure(const std::string& config, LinkClosure& lc,
970                           bool secondPass) const;
971
972   struct LinkImplClosure : public std::vector<cmGeneratorTarget const*>
973   {
974     bool Done = false;
975   };
976   mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap;
977
978   using LinkInterfaceMapType = std::map<std::string, cmHeadToLinkInterfaceMap>;
979   mutable LinkInterfaceMapType LinkInterfaceMap;
980   mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
981
982   cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceMap(
983     std::string const& config) const;
984   cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceUsageRequirementsMap(
985     std::string const& config) const;
986
987   std::string GetLinkInterfaceDependentStringAsBoolProperty(
988     const std::string& p, const std::string& config) const;
989
990   friend class cmTargetCollectLinkLanguages;
991   cmLinkInterface const* GetLinkInterface(const std::string& config,
992                                           const cmGeneratorTarget* headTarget,
993                                           bool secondPass) const;
994   void ComputeLinkInterface(const std::string& config,
995                             cmOptionalLinkInterface& iface,
996                             const cmGeneratorTarget* head,
997                             bool secondPass) const;
998   cmLinkImplementation const* GetLinkImplementation(const std::string& config,
999                                                     LinkInterfaceFor implFor,
1000                                                     bool secondPass) const;
1001
1002   enum class LinkItemRole
1003   {
1004     Implementation,
1005     Interface,
1006   };
1007   bool VerifyLinkItemIsTarget(LinkItemRole role, cmLinkItem const& item) const;
1008   bool VerifyLinkItemColons(LinkItemRole role, cmLinkItem const& item) const;
1009
1010   // Cache import information from properties for each configuration.
1011   struct ImportInfo
1012   {
1013     bool NoSOName = false;
1014     ManagedType Managed = Native;
1015     unsigned int Multiplicity = 0;
1016     std::string Location;
1017     std::string SOName;
1018     std::string ImportLibrary;
1019     std::string LibName;
1020     std::string Languages;
1021     std::string LibrariesProp;
1022     std::vector<BT<std::string>> Libraries;
1023     std::vector<BT<std::string>> LibrariesHeadInclude;
1024     std::vector<BT<std::string>> LibrariesHeadExclude;
1025     std::string SharedDeps;
1026   };
1027
1028   using ImportInfoMapType = std::map<std::string, ImportInfo>;
1029   mutable ImportInfoMapType ImportInfoMap;
1030   void ComputeImportInfo(std::string const& desired_config,
1031                          ImportInfo& info) const;
1032   ImportInfo const* GetImportInfo(const std::string& config) const;
1033
1034   /** Strip off leading and trailing whitespace from an item named in
1035       the link dependencies of this target.  */
1036   std::string CheckCMP0004(std::string const& item) const;
1037
1038   cmLinkInterface const* GetImportLinkInterface(const std::string& config,
1039                                                 const cmGeneratorTarget* head,
1040                                                 LinkInterfaceFor interfaceFor,
1041                                                 bool secondPass = false) const;
1042
1043   using KindedSourcesMapType = std::map<std::string, KindedSources>;
1044   mutable KindedSourcesMapType KindedSourcesMap;
1045   void ComputeKindedSources(KindedSources& files,
1046                             std::string const& config) const;
1047
1048   mutable std::vector<AllConfigSource> AllConfigSources;
1049   void ComputeAllConfigSources() const;
1050
1051   mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists;
1052   bool MaybeHaveInterfaceProperty(std::string const& prop,
1053                                   cmGeneratorExpressionContext* context,
1054                                   LinkInterfaceFor interfaceFor) const;
1055
1056   using TargetPropertyEntryVector =
1057     std::vector<std::unique_ptr<TargetPropertyEntry>>;
1058
1059   TargetPropertyEntryVector IncludeDirectoriesEntries;
1060   TargetPropertyEntryVector CompileOptionsEntries;
1061   TargetPropertyEntryVector CompileFeaturesEntries;
1062   TargetPropertyEntryVector CompileDefinitionsEntries;
1063   TargetPropertyEntryVector LinkOptionsEntries;
1064   TargetPropertyEntryVector LinkDirectoriesEntries;
1065   TargetPropertyEntryVector PrecompileHeadersEntries;
1066   TargetPropertyEntryVector SourceEntries;
1067   mutable std::set<std::string> LinkImplicitNullProperties;
1068   mutable std::map<std::string, std::string> PchHeaders;
1069   mutable std::map<std::string, std::string> PchSources;
1070   mutable std::map<std::string, std::string> PchObjectFiles;
1071   mutable std::map<std::string, std::string> PchFiles;
1072   mutable std::map<std::string, std::string> PchCreateCompileOptions;
1073   mutable std::map<std::string, std::string> PchUseCompileOptions;
1074
1075   std::unordered_set<std::string> UnityBatchedSourceFiles;
1076
1077   std::unordered_map<std::string, std::vector<std::string>>
1078     ISPCGeneratedHeaders;
1079   std::unordered_map<std::string, std::vector<std::string>>
1080     ISPCGeneratedObjects;
1081
1082   enum class LinkInterfaceField
1083   {
1084     Libraries,
1085     HeadExclude,
1086     HeadInclude,
1087   };
1088   void ExpandLinkItems(std::string const& prop, cmBTStringRange entries,
1089                        std::string const& config,
1090                        const cmGeneratorTarget* headTarget,
1091                        LinkInterfaceFor interfaceFor, LinkInterfaceField field,
1092                        cmLinkInterface& iface) const;
1093
1094   struct LookupLinkItemScope
1095   {
1096     cmLocalGenerator const* LG;
1097   };
1098   enum class LookupSelf
1099   {
1100     No,
1101     Yes,
1102   };
1103   cm::optional<cmLinkItem> LookupLinkItem(std::string const& n,
1104                                           cmListFileBacktrace const& bt,
1105                                           LookupLinkItemScope* scope,
1106                                           LookupSelf lookupSelf) const;
1107
1108   std::vector<BT<std::string>> GetSourceFilePaths(
1109     std::string const& config) const;
1110   std::vector<BT<cmSourceFile*>> GetSourceFilesWithoutObjectLibraries(
1111     std::string const& config) const;
1112   void GetSourceFilesWithoutObjectLibraries(std::vector<cmSourceFile*>& files,
1113                                             const std::string& config) const;
1114
1115   struct HeadToLinkImplementationMap
1116     : public std::map<cmGeneratorTarget const*, cmOptionalLinkImplementation>
1117   {
1118   };
1119   using LinkImplMapType = std::map<std::string, HeadToLinkImplementationMap>;
1120   mutable LinkImplMapType LinkImplMap;
1121   mutable LinkImplMapType LinkImplUsageRequirementsOnlyMap;
1122
1123   HeadToLinkImplementationMap& GetHeadToLinkImplementationMap(
1124     std::string const& config) const;
1125   HeadToLinkImplementationMap& GetHeadToLinkImplementationUsageRequirementsMap(
1126     std::string const& config) const;
1127
1128   cmLinkImplementationLibraries const* GetLinkImplementationLibrariesInternal(
1129     const std::string& config, const cmGeneratorTarget* head,
1130     LinkInterfaceFor implFor) const;
1131   bool ComputeOutputDir(const std::string& config,
1132                         cmStateEnums::ArtifactType artifact,
1133                         std::string& out) const;
1134
1135   using OutputInfoMapType = std::map<std::string, OutputInfo>;
1136   mutable OutputInfoMapType OutputInfoMap;
1137
1138   using ModuleDefinitionInfoMapType =
1139     std::map<std::string, ModuleDefinitionInfo>;
1140   mutable ModuleDefinitionInfoMapType ModuleDefinitionInfoMap;
1141   void ComputeModuleDefinitionInfo(std::string const& config,
1142                                    ModuleDefinitionInfo& info) const;
1143
1144   using OutputNameKey = std::pair<std::string, cmStateEnums::ArtifactType>;
1145   using OutputNameMapType = std::map<OutputNameKey, std::string>;
1146   mutable OutputNameMapType OutputNameMap;
1147   mutable std::set<cmLinkItem> UtilityItems;
1148   cmPolicies::PolicyMap PolicyMap;
1149   mutable bool PolicyWarnedCMP0022 = false;
1150   mutable bool PolicyReportedCMP0069 = false;
1151   mutable bool DebugIncludesDone = false;
1152   mutable bool DebugCompileOptionsDone = false;
1153   mutable bool DebugCompileFeaturesDone = false;
1154   mutable bool DebugCompileDefinitionsDone = false;
1155   mutable bool DebugLinkOptionsDone = false;
1156   mutable bool DebugLinkDirectoriesDone = false;
1157   mutable bool DebugPrecompileHeadersDone = false;
1158   mutable bool DebugSourcesDone = false;
1159   mutable bool UtilityItemsDone = false;
1160   enum class Tribool
1161   {
1162     False = 0x0,
1163     True = 0x1,
1164     Indeterminate = 0x2
1165   };
1166   mutable Tribool SourcesAreContextDependent = Tribool::Indeterminate;
1167
1168   bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
1169                            std::string& out) const;
1170
1171   ManagedType CheckManagedType(std::string const& propval) const;
1172
1173   bool GetRPATH(const std::string& config, const std::string& prop,
1174                 std::string& rpath) const;
1175
1176   mutable std::map<std::string, BTs<std::string>> LanguageStandardMap;
1177
1178   cmValue GetPropertyWithPairedLanguageSupport(std::string const& lang,
1179                                                const char* suffix) const;
1180
1181   void ComputeLinkImplementationRuntimeLibraries(
1182     const std::string& config, cmOptionalLinkImplementation& impl) const;
1183
1184   void ComputeLinkInterfaceRuntimeLibraries(
1185     const std::string& config, cmOptionalLinkInterface& iface) const;
1186
1187 public:
1188   const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
1189     const std::string& config) const;
1190
1191   mutable std::map<std::string, std::string> MaxLanguageStandards;
1192   std::map<std::string, std::string> const& GetMaxLanguageStandards() const
1193   {
1194     return this->MaxLanguageStandards;
1195   }
1196
1197   struct StrictTargetComparison
1198   {
1199     bool operator()(cmGeneratorTarget const* t1,
1200                     cmGeneratorTarget const* t2) const;
1201   };
1202
1203   // C++20 module support queries.
1204
1205   /**
1206    * Query whether the target expects C++20 module support.
1207    *
1208    * This will inspect the target itself to see if C++20 module
1209    * support is expected to work based on its sources.
1210    */
1211   bool HaveCxx20ModuleSources() const;
1212
1213   enum class Cxx20SupportLevel
1214   {
1215     // C++ is not available.
1216     MissingCxx,
1217     // The experimental feature is not available.
1218     MissingExperimentalFlag,
1219     // The target does not require at least C++20.
1220     NoCxx20,
1221     // C++20 modules are available and working.
1222     Supported,
1223   };
1224   /**
1225    * Query whether the target has C++20 module support available (regardless of
1226    * whether it is required or not).
1227    */
1228   Cxx20SupportLevel HaveCxxModuleSupport(std::string const& config) const;
1229
1230   // Check C++ module status for the target.
1231   void CheckCxxModuleStatus(std::string const& config) const;
1232 };