blob: 2a06530037332694b7cc4a565efc6264966f377b [file] [log] [blame]
/* 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);
};