|  | /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying | 
|  | file LICENSE.rst or https://cmake.org/licensing for details.  */ | 
|  | #pragma once | 
|  |  | 
|  | #include "cmConfigure.h" // IWYU pragma: keep | 
|  |  | 
|  | #include <map> | 
|  | #include <memory> | 
|  | #include <set> | 
|  | #include <string> | 
|  | #include <utility> | 
|  | #include <vector> | 
|  |  | 
|  | #include "cmsys/RegularExpression.hxx" | 
|  |  | 
|  | #include "cmComputeLinkDepends.h" | 
|  | #include "cmListFileCache.h" | 
|  | #include "cmValue.h" | 
|  |  | 
|  | class cmGeneratorTarget; | 
|  | class cmGlobalGenerator; | 
|  | class cmMakefile; | 
|  | class cmOrderDirectories; | 
|  | class cmSourceFile; | 
|  | class cmake; | 
|  |  | 
|  | /** \class cmComputeLinkInformation | 
|  | * \brief Compute link information for a target in one configuration. | 
|  | */ | 
|  | class cmComputeLinkInformation | 
|  | { | 
|  | private: | 
|  | class FeatureDescriptor; | 
|  |  | 
|  | public: | 
|  | cmComputeLinkInformation(cmGeneratorTarget const* target, | 
|  | std::string const& config); | 
|  | cmComputeLinkInformation(cmComputeLinkInformation const&) = delete; | 
|  | cmComputeLinkInformation& operator=(cmComputeLinkInformation const&) = | 
|  | delete; | 
|  | ~cmComputeLinkInformation(); | 
|  | bool Compute(); | 
|  |  | 
|  | enum class ItemIsPath | 
|  | { | 
|  | No, | 
|  | Yes, | 
|  | }; | 
|  |  | 
|  | struct Item | 
|  | { | 
|  | Item(BT<std::string> v, ItemIsPath isPath, | 
|  | cmGeneratorTarget const* target = nullptr, | 
|  | cmSourceFile const* objectSource = nullptr, | 
|  | FeatureDescriptor const* feature = nullptr) | 
|  | : Value(std::move(v)) | 
|  | , IsPath(isPath) | 
|  | , Target(target) | 
|  | , ObjectSource(objectSource) | 
|  | , Feature(feature) | 
|  | { | 
|  | } | 
|  | BT<std::string> Value; | 
|  | ItemIsPath IsPath = ItemIsPath::No; | 
|  | cmGeneratorTarget const* Target = nullptr; | 
|  | // The source file representing the external object (used when linking | 
|  | // `$<TARGET_OBJECTS>`) | 
|  | cmSourceFile const* ObjectSource = nullptr; | 
|  |  | 
|  | bool HasFeature() const { return this->Feature != nullptr; } | 
|  | std::string const& GetFeatureName() const | 
|  | { | 
|  | return HasFeature() ? this->Feature->Name | 
|  | : cmComputeLinkDepends::LinkEntry::DEFAULT; | 
|  | } | 
|  |  | 
|  | BT<std::string> GetFormattedItem(std::string const& path) const | 
|  | { | 
|  | return { this->Feature | 
|  | ? this->Feature->GetDecoratedItem(path, this->IsPath) | 
|  | : path, | 
|  | Value.Backtrace }; | 
|  | } | 
|  |  | 
|  | private: | 
|  | FeatureDescriptor const* Feature = nullptr; | 
|  | }; | 
|  | using ItemVector = std::vector<Item>; | 
|  | void AppendValues(std::string& result, std::vector<BT<std::string>>& values); | 
|  | ItemVector const& GetItems() const; | 
|  | std::vector<std::string> const& GetDirectories() const; | 
|  | std::vector<BT<std::string>> GetDirectoriesWithBacktraces(); | 
|  | std::vector<std::string> const& GetDepends() const; | 
|  | std::vector<std::string> const& GetFrameworkPaths() const; | 
|  | std::set<std::string> const& GetFrameworkPathsEmitted() const; | 
|  | std::vector<std::string> const& GetXcFrameworkHeaderPaths() const; | 
|  | std::string GetLinkLanguage() const { return this->LinkLanguage; } | 
|  | std::vector<std::string> const& GetRuntimeSearchPath() const; | 
|  | std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; } | 
|  | std::string const& GetRuntimeSep() const { return this->RuntimeSep; } | 
|  | void GetRPath(std::vector<std::string>& runtimeDirs, bool for_install) const; | 
|  | std::string GetRPathString(bool for_install) const; | 
|  | std::string GetChrpathString() const; | 
|  | std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const; | 
|  | std::vector<cmGeneratorTarget const*> const& GetExternalObjectTargets() | 
|  | const; | 
|  | std::vector<cmGeneratorTarget const*> const& GetRuntimeDLLs() const | 
|  | { | 
|  | return this->RuntimeDLLs; | 
|  | } | 
|  |  | 
|  | std::string const& GetLibLinkFileFlag() const | 
|  | { | 
|  | return this->LibLinkFileFlag; | 
|  | } | 
|  |  | 
|  | std::string const& GetObjLinkFileFlag() const | 
|  | { | 
|  | return this->ObjLinkFileFlag; | 
|  | } | 
|  |  | 
|  | std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; } | 
|  | std::string GetRPathLinkString() const; | 
|  |  | 
|  | std::string GetConfig() const { return this->Config; } | 
|  |  | 
|  | cmGeneratorTarget const* GetTarget() { return this->Target; } | 
|  |  | 
|  | private: | 
|  | using LinkEntry = cmComputeLinkDepends::LinkEntry; | 
|  |  | 
|  | void AddItem(LinkEntry const& entry); | 
|  | void AddSharedDepItem(LinkEntry const& entry); | 
|  | void AddRuntimeDLL(cmGeneratorTarget const* tgt); | 
|  |  | 
|  | // Output information. | 
|  | ItemVector Items; | 
|  | std::vector<std::string> Directories; | 
|  | std::vector<std::string> Depends; | 
|  | std::vector<std::string> FrameworkPaths; | 
|  | std::vector<std::string> XcFrameworkHeaderPaths; | 
|  | std::vector<std::string> RuntimeSearchPath; | 
|  | std::set<cmGeneratorTarget const*> SharedLibrariesLinked; | 
|  | std::vector<cmGeneratorTarget const*> ExternalObjectTargets; | 
|  | std::vector<cmGeneratorTarget const*> RuntimeDLLs; | 
|  |  | 
|  | // Context information. | 
|  | cmGeneratorTarget const* const Target; | 
|  | cmMakefile* const Makefile; | 
|  | cmGlobalGenerator* const GlobalGenerator; | 
|  | cmake* const CMakeInstance; | 
|  |  | 
|  | // Configuration information. | 
|  | std::string const Config; | 
|  | std::string LinkLanguage; | 
|  |  | 
|  | // Modes for dealing with dependent shared libraries. | 
|  | enum SharedDepMode | 
|  | { | 
|  | SharedDepModeNone,   // Drop | 
|  | SharedDepModeDir,    // List dir in -rpath-link flag | 
|  | SharedDepModeLibDir, // List dir in linker search path | 
|  | SharedDepModeLink    // List file on link line | 
|  | }; | 
|  |  | 
|  | cmValue LoaderFlag; | 
|  | std::string LibLinkFlag; | 
|  | std::string LibLinkFileFlag; | 
|  | std::string ObjLinkFileFlag; | 
|  | std::string LibLinkSuffix; | 
|  | std::string RuntimeFlag; | 
|  | std::string RuntimeSep; | 
|  | std::string RuntimeAlways; | 
|  | std::string RPathLinkFlag; | 
|  | SharedDepMode SharedDependencyMode; | 
|  |  | 
|  | enum LinkType | 
|  | { | 
|  | LinkUnknown, | 
|  | LinkStatic, | 
|  | LinkShared | 
|  | }; | 
|  | void SetCurrentLinkType(LinkType lt); | 
|  |  | 
|  | // Link type adjustment. | 
|  | void ComputeLinkTypeInfo(); | 
|  | LinkType StartLinkType; | 
|  | LinkType CurrentLinkType; | 
|  | std::string StaticLinkTypeFlag; | 
|  | std::string SharedLinkTypeFlag; | 
|  |  | 
|  | // Link item parsing. | 
|  | void ComputeItemParserInfo(); | 
|  | std::vector<std::string> StaticLinkExtensions; | 
|  | std::vector<std::string> SharedLinkExtensions; | 
|  | std::vector<std::string> LinkExtensions; | 
|  | std::set<std::string> LinkPrefixes; | 
|  | cmsys::RegularExpression ExtractStaticLibraryName; | 
|  | cmsys::RegularExpression ExtractSharedLibraryName; | 
|  | cmsys::RegularExpression ExtractAnyLibraryName; | 
|  | std::string SharedRegexString; | 
|  | void AddLinkPrefix(std::string const& p); | 
|  | void AddLinkExtension(std::string const& e, LinkType type); | 
|  | std::string CreateExtensionRegex(std::vector<std::string> const& exts, | 
|  | LinkType type); | 
|  | std::string NoCaseExpression(std::string const& str); | 
|  |  | 
|  | // Handling of link items. | 
|  | void AddTargetItem(LinkEntry const& entry); | 
|  | void AddFullItem(LinkEntry const& entry); | 
|  | bool CheckImplicitDirItem(LinkEntry const& entry); | 
|  | void AddUserItem(LinkEntry const& entry); | 
|  | void AddFrameworkItem(LinkEntry const& entry); | 
|  | void AddXcFrameworkItem(LinkEntry const& entry); | 
|  | void DropDirectoryItem(BT<std::string> const& item); | 
|  | bool CheckSharedLibNoSOName(LinkEntry const& entry); | 
|  | void AddSharedLibNoSOName(LinkEntry const& entry); | 
|  |  | 
|  | // Framework info. | 
|  | void ComputeFrameworkInfo(); | 
|  | void AddFrameworkPath(std::string const& p); | 
|  | std::set<std::string> FrameworkPathsEmitted; | 
|  |  | 
|  | void AddXcFrameworkHeaderPath(std::string const& p); | 
|  |  | 
|  | // Linker search path computation. | 
|  | std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath; | 
|  |  | 
|  | void AddExternalObjectTargets(); | 
|  |  | 
|  | // Implicit link libraries and directories for linker language. | 
|  | void LoadImplicitLinkInfo(); | 
|  | void AddImplicitLinkInfo(); | 
|  | void AddImplicitLinkInfo(std::string const& lang); | 
|  | void AddRuntimeLinkLibrary(std::string const& lang); | 
|  | std::set<std::string> ImplicitLinkDirs; | 
|  | std::set<std::string> ImplicitLinkLibs; | 
|  |  | 
|  | // Additional paths configured by the runtime linker | 
|  | std::vector<std::string> RuntimeLinkDirs; | 
|  |  | 
|  | // Dependent library path computation. | 
|  | std::unique_ptr<cmOrderDirectories> OrderDependentRPath; | 
|  | // Runtime path computation. | 
|  | std::unique_ptr<cmOrderDirectories> OrderRuntimeSearchPath; | 
|  |  | 
|  | bool IsOpenBSD; | 
|  | bool LinkDependsNoShared; | 
|  | bool RuntimeUseChrpath; | 
|  | bool NoSONameUsesPath; | 
|  | bool LinkWithRuntimePath; | 
|  | bool LinkTypeEnabled; | 
|  | bool ArchivesMayBeShared; | 
|  |  | 
|  | void AddLibraryRuntimeInfo(std::string const& fullPath, | 
|  | cmGeneratorTarget const* target); | 
|  | void AddLibraryRuntimeInfo(std::string const& fullPath); | 
|  |  | 
|  | class FeatureDescriptor | 
|  | { | 
|  | public: | 
|  | FeatureDescriptor() = default; | 
|  |  | 
|  | std::string const Name; | 
|  | bool const Supported = false; | 
|  | std::string const Prefix; | 
|  | std::string const Suffix; | 
|  | std::string GetDecoratedItem(std::string const& library, | 
|  | ItemIsPath isPath) const; | 
|  | std::string GetDecoratedItem(std::string const& library, | 
|  | std::string const& linkItem, | 
|  | std::string const& defaultValue, | 
|  | ItemIsPath isPath) const; | 
|  |  | 
|  | protected: | 
|  | FeatureDescriptor(std::string name, std::string itemFormat); | 
|  | FeatureDescriptor(std::string name, std::string itemPathFormat, | 
|  | std::string itemNameFormat); | 
|  | FeatureDescriptor(std::string name, std::string prefix, | 
|  | std::string itemPathFormat, std::string itemNameFormat, | 
|  | std::string suffix); | 
|  |  | 
|  | FeatureDescriptor(std::string name, std::string prefix, std::string suffix, | 
|  | bool isGroup); | 
|  |  | 
|  | private: | 
|  | std::string ItemPathFormat; | 
|  | std::string ItemNameFormat; | 
|  | }; | 
|  |  | 
|  | class LibraryFeatureDescriptor : public FeatureDescriptor | 
|  | { | 
|  | public: | 
|  | LibraryFeatureDescriptor(std::string name, std::string itemFormat); | 
|  | LibraryFeatureDescriptor(std::string name, std::string itemPathFormat, | 
|  | std::string itemNameFormat); | 
|  | LibraryFeatureDescriptor(std::string name, std::string prefix, | 
|  | std::string itemPathFormat, | 
|  | std::string itemNameFormat, std::string suffix); | 
|  | }; | 
|  | std::map<std::string, FeatureDescriptor> LibraryFeatureDescriptors; | 
|  | bool AddLibraryFeature(std::string const& feature); | 
|  | FeatureDescriptor const& GetLibraryFeature(std::string const& feature) const; | 
|  | FeatureDescriptor const* FindLibraryFeature( | 
|  | std::string const& feature) const; | 
|  |  | 
|  | class GroupFeatureDescriptor : public FeatureDescriptor | 
|  | { | 
|  | public: | 
|  | GroupFeatureDescriptor(std::string name, std::string prefix, | 
|  | std::string suffix); | 
|  | }; | 
|  | std::map<std::string, FeatureDescriptor> GroupFeatureDescriptors; | 
|  | FeatureDescriptor const& GetGroupFeature(std::string const& feature); | 
|  | }; |