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