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