You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
327 lines
11 KiB
327 lines
11 KiB
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
|
#pragma once
|
|
|
|
#include "cmConfigure.h" // IWYU pragma: keep
|
|
|
|
#include <iosfwd>
|
|
#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,
|
|
const std::string& config);
|
|
cmComputeLinkInformation(const cmComputeLinkInformation&) = delete;
|
|
cmComputeLinkInformation& operator=(const cmComputeLinkInformation&) =
|
|
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; }
|
|
const std::string& GetFeatureName() const
|
|
{
|
|
return HasFeature() ? this->Feature->Name
|
|
: cmComputeLinkDepends::LinkEntry::DEFAULT;
|
|
}
|
|
|
|
BT<std::string> GetFormattedItem(std::string const& path) const
|
|
{
|
|
return { (this->Feature != nullptr)
|
|
? 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; }
|
|
|
|
const cmGeneratorTarget* 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, bool pathNotKnown);
|
|
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);
|
|
void HandleBadFullItem(LinkEntry const& entry, std::string const& file);
|
|
|
|
// 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;
|
|
bool FinishLinkerSearchDirectories();
|
|
void PrintLinkPolicyDiagnosis(std::ostream&);
|
|
|
|
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;
|
|
|
|
// Linker search path compatibility mode.
|
|
std::set<std::string> OldLinkDirMask;
|
|
std::vector<std::string> OldLinkDirItems;
|
|
std::vector<std::string> OldUserFlagItems;
|
|
std::set<std::string> CMP0060WarnItems;
|
|
// Dependent library path computation.
|
|
std::unique_ptr<cmOrderDirectories> OrderDependentRPath;
|
|
// Runtime path computation.
|
|
std::unique_ptr<cmOrderDirectories> OrderRuntimeSearchPath;
|
|
|
|
bool OldLinkDirMode;
|
|
bool IsOpenBSD;
|
|
bool LinkDependsNoShared;
|
|
bool RuntimeUseChrpath;
|
|
bool NoSONameUsesPath;
|
|
bool LinkWithRuntimePath;
|
|
bool LinkTypeEnabled;
|
|
bool ArchivesMayBeShared;
|
|
bool CMP0060Warn;
|
|
|
|
void AddLibraryRuntimeInfo(std::string const& fullPath,
|
|
const cmGeneratorTarget* target);
|
|
void AddLibraryRuntimeInfo(std::string const& fullPath);
|
|
|
|
class FeatureDescriptor
|
|
{
|
|
public:
|
|
FeatureDescriptor() = default;
|
|
|
|
const std::string Name;
|
|
const bool Supported = false;
|
|
const std::string Prefix;
|
|
const std::string 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);
|
|
};
|