forked from OSchip/llvm-project
[Gnu toolchain] Look at standard GCC paths for libstdcxx by default
Linux' current addLibCxxIncludePaths and addLibStdCxxIncludePaths are actually almost non-Linux-specific at all, and can be reused almost as such for all gcc toolchains. Only keep Android/Freescale/Cray hacks in Linux's version. Patch by sthibaul (Samuel Thibault) Differential Revision: https://reviews.llvm.org/D69758
This commit is contained in:
parent
586acd8490
commit
b18cb9c471
|
@ -2686,19 +2686,49 @@ void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static std::string DetectLibcxxIncludePath(llvm::vfs::FileSystem &vfs,
|
||||||
Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
StringRef base) {
|
||||||
llvm::opt::ArgStringList &CC1Args) const {
|
std::error_code EC;
|
||||||
// FIXME: The Linux behavior would probaby be a better approach here.
|
int MaxVersion = 0;
|
||||||
addSystemInclude(DriverArgs, CC1Args,
|
std::string MaxVersionString;
|
||||||
getDriver().SysRoot + "/usr/include/c++/v1");
|
for (llvm::vfs::directory_iterator LI = vfs.dir_begin(base, EC), LE;
|
||||||
|
!EC && LI != LE; LI = LI.increment(EC)) {
|
||||||
|
StringRef VersionText = llvm::sys::path::filename(LI->path());
|
||||||
|
int Version;
|
||||||
|
if (VersionText[0] == 'v' &&
|
||||||
|
!VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
|
||||||
|
if (Version > MaxVersion) {
|
||||||
|
MaxVersion = Version;
|
||||||
|
MaxVersionString = VersionText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args) const {
|
llvm::opt::ArgStringList &CC1Args) const {
|
||||||
// By default, we don't assume we know where libstdc++ might be installed.
|
const std::string& SysRoot = getDriver().SysRoot;
|
||||||
// FIXME: If we have a valid GCCInstallation, use it.
|
auto AddIncludePath = [&](std::string Path) {
|
||||||
|
std::string IncludePath = DetectLibcxxIncludePath(getVFS(), Path);
|
||||||
|
if (IncludePath.empty() || !getVFS().exists(IncludePath))
|
||||||
|
return false;
|
||||||
|
addSystemInclude(DriverArgs, CC1Args, IncludePath);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
// Android never uses the libc++ headers installed alongside the toolchain,
|
||||||
|
// which are generally incompatible with the NDK libraries anyway.
|
||||||
|
if (!getTriple().isAndroid())
|
||||||
|
if (AddIncludePath(getDriver().Dir + "/../include/c++"))
|
||||||
|
return;
|
||||||
|
// If this is a development, non-installed, clang, libcxx will
|
||||||
|
// not be found at ../include/c++ but it likely to be found at
|
||||||
|
// one of the following two locations:
|
||||||
|
if (AddIncludePath(SysRoot + "/usr/local/include/c++"))
|
||||||
|
return;
|
||||||
|
if (AddIncludePath(SysRoot + "/usr/include/c++"))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to add the variant paths of a libstdc++ installation.
|
/// Helper to add the variant paths of a libstdc++ installation.
|
||||||
|
@ -2734,6 +2764,60 @@ bool Generic_GCC::addLibStdCXXIncludePaths(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Generic_GCC::addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
||||||
|
llvm::opt::ArgStringList &CC1Args) const {
|
||||||
|
// Use GCCInstallation to know where libstdc++ headers are installed.
|
||||||
|
if (!GCCInstallation.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// By default, look for the C++ headers in an include directory adjacent to
|
||||||
|
// the lib directory of the GCC installation. Note that this is expect to be
|
||||||
|
// equivalent to '/usr/include/c++/X.Y' in almost all cases.
|
||||||
|
StringRef LibDir = GCCInstallation.getParentLibPath();
|
||||||
|
StringRef InstallDir = GCCInstallation.getInstallPath();
|
||||||
|
StringRef TripleStr = GCCInstallation.getTriple().str();
|
||||||
|
const Multilib &Multilib = GCCInstallation.getMultilib();
|
||||||
|
const std::string GCCMultiarchTriple = getMultiarchTriple(
|
||||||
|
getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);
|
||||||
|
const std::string TargetMultiarchTriple =
|
||||||
|
getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
|
||||||
|
const GCCVersion &Version = GCCInstallation.getVersion();
|
||||||
|
|
||||||
|
// The primary search for libstdc++ supports multiarch variants.
|
||||||
|
if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
|
||||||
|
"/c++/" + Version.Text, TripleStr,
|
||||||
|
GCCMultiarchTriple, TargetMultiarchTriple,
|
||||||
|
Multilib.includeSuffix(), DriverArgs, CC1Args))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Otherwise, fall back on a bunch of options which don't use multiarch
|
||||||
|
// layouts for simplicity.
|
||||||
|
const std::string LibStdCXXIncludePathCandidates[] = {
|
||||||
|
// Gentoo is weird and places its headers inside the GCC install,
|
||||||
|
// so if the first attempt to find the headers fails, try these patterns.
|
||||||
|
InstallDir.str() + "/include/g++-v" + Version.Text,
|
||||||
|
InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
|
||||||
|
Version.MinorStr,
|
||||||
|
InstallDir.str() + "/include/g++-v" + Version.MajorStr,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
|
||||||
|
if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
|
||||||
|
/*GCCMultiarchTriple*/ "",
|
||||||
|
/*TargetMultiarchTriple*/ "",
|
||||||
|
Multilib.includeSuffix(), DriverArgs, CC1Args))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
||||||
|
llvm::opt::ArgStringList &CC1Args) const {
|
||||||
|
addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args);
|
||||||
|
}
|
||||||
|
|
||||||
llvm::opt::DerivedArgList *
|
llvm::opt::DerivedArgList *
|
||||||
Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef,
|
Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef,
|
||||||
Action::OffloadKind DeviceOffloadKind) const {
|
Action::OffloadKind DeviceOffloadKind) const {
|
||||||
|
|
|
@ -300,6 +300,11 @@ protected:
|
||||||
Tool *buildAssembler() const override;
|
Tool *buildAssembler() const override;
|
||||||
Tool *buildLinker() const override;
|
Tool *buildLinker() const override;
|
||||||
|
|
||||||
|
virtual std::string getMultiarchTriple(const Driver &D,
|
||||||
|
const llvm::Triple &TargetTriple,
|
||||||
|
StringRef SysRoot) const
|
||||||
|
{ return TargetTriple.str(); }
|
||||||
|
|
||||||
/// \name ToolChain Implementation Helper Functions
|
/// \name ToolChain Implementation Helper Functions
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
@ -322,6 +327,10 @@ protected:
|
||||||
addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args) const;
|
llvm::opt::ArgStringList &CC1Args) const;
|
||||||
|
|
||||||
|
bool
|
||||||
|
addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
||||||
|
llvm::opt::ArgStringList &CC1Args) const;
|
||||||
|
|
||||||
bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple,
|
bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple,
|
||||||
StringRef GCCMultiarchTriple,
|
StringRef GCCMultiarchTriple,
|
||||||
StringRef TargetMultiarchTriple,
|
StringRef TargetMultiarchTriple,
|
||||||
|
|
|
@ -27,9 +27,9 @@ using tools::addPathIfExists;
|
||||||
/// a target-triple directory in the library and header search paths.
|
/// a target-triple directory in the library and header search paths.
|
||||||
/// Unfortunately, this triple does not align with the vanilla target triple,
|
/// Unfortunately, this triple does not align with the vanilla target triple,
|
||||||
/// so we provide a rough mapping here.
|
/// so we provide a rough mapping here.
|
||||||
static std::string getMultiarchTriple(const Driver &D,
|
std::string Hurd::getMultiarchTriple(const Driver &D,
|
||||||
const llvm::Triple &TargetTriple,
|
const llvm::Triple &TargetTriple,
|
||||||
StringRef SysRoot) {
|
StringRef SysRoot) const {
|
||||||
if (TargetTriple.getArch() == llvm::Triple::x86) {
|
if (TargetTriple.getArch() == llvm::Triple::x86) {
|
||||||
// We use the existence of '/lib/<triple>' as a directory to detect some
|
// We use the existence of '/lib/<triple>' as a directory to detect some
|
||||||
// common hurd triples that don't quite match the Clang triple for both
|
// common hurd triples that don't quite match the Clang triple for both
|
||||||
|
|
|
@ -36,6 +36,10 @@ public:
|
||||||
protected:
|
protected:
|
||||||
Tool *buildAssembler() const override;
|
Tool *buildAssembler() const override;
|
||||||
Tool *buildLinker() const override;
|
Tool *buildLinker() const override;
|
||||||
|
|
||||||
|
std::string getMultiarchTriple(const Driver &D,
|
||||||
|
const llvm::Triple &TargetTriple,
|
||||||
|
StringRef SysRoot) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace toolchains
|
} // end namespace toolchains
|
||||||
|
|
|
@ -37,9 +37,9 @@ using tools::addPathIfExists;
|
||||||
/// a target-triple directory in the library and header search paths.
|
/// a target-triple directory in the library and header search paths.
|
||||||
/// Unfortunately, this triple does not align with the vanilla target triple,
|
/// Unfortunately, this triple does not align with the vanilla target triple,
|
||||||
/// so we provide a rough mapping here.
|
/// so we provide a rough mapping here.
|
||||||
static std::string getMultiarchTriple(const Driver &D,
|
std::string Linux::getMultiarchTriple(const Driver &D,
|
||||||
const llvm::Triple &TargetTriple,
|
const llvm::Triple &TargetTriple,
|
||||||
StringRef SysRoot) {
|
StringRef SysRoot) const {
|
||||||
llvm::Triple::EnvironmentType TargetEnvironment =
|
llvm::Triple::EnvironmentType TargetEnvironment =
|
||||||
TargetTriple.getEnvironment();
|
TargetTriple.getEnvironment();
|
||||||
bool IsAndroid = TargetTriple.isAndroid();
|
bool IsAndroid = TargetTriple.isAndroid();
|
||||||
|
@ -865,86 +865,23 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||||
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
|
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string DetectLibcxxIncludePath(llvm::vfs::FileSystem &vfs,
|
|
||||||
StringRef base) {
|
|
||||||
std::error_code EC;
|
|
||||||
int MaxVersion = 0;
|
|
||||||
std::string MaxVersionString = "";
|
|
||||||
for (llvm::vfs::directory_iterator LI = vfs.dir_begin(base, EC), LE;
|
|
||||||
!EC && LI != LE; LI = LI.increment(EC)) {
|
|
||||||
StringRef VersionText = llvm::sys::path::filename(LI->path());
|
|
||||||
int Version;
|
|
||||||
if (VersionText[0] == 'v' &&
|
|
||||||
!VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
|
|
||||||
if (Version > MaxVersion) {
|
|
||||||
MaxVersion = Version;
|
|
||||||
MaxVersionString = VersionText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void Linux::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
|
||||||
llvm::opt::ArgStringList &CC1Args) const {
|
|
||||||
const std::string& SysRoot = computeSysRoot();
|
|
||||||
auto AddIncludePath = [&](std::string Path) {
|
|
||||||
std::string IncludePath = DetectLibcxxIncludePath(getVFS(), Path);
|
|
||||||
if (IncludePath.empty() || !getVFS().exists(IncludePath))
|
|
||||||
return false;
|
|
||||||
addSystemInclude(DriverArgs, CC1Args, IncludePath);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
// Android never uses the libc++ headers installed alongside the toolchain,
|
|
||||||
// which are generally incompatible with the NDK libraries anyway.
|
|
||||||
if (!getTriple().isAndroid())
|
|
||||||
if (AddIncludePath(getDriver().Dir + "/../include/c++"))
|
|
||||||
return;
|
|
||||||
// If this is a development, non-installed, clang, libcxx will
|
|
||||||
// not be found at ../include/c++ but it likely to be found at
|
|
||||||
// one of the following two locations:
|
|
||||||
if (AddIncludePath(SysRoot + "/usr/local/include/c++"))
|
|
||||||
return;
|
|
||||||
if (AddIncludePath(SysRoot + "/usr/include/c++"))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args) const {
|
llvm::opt::ArgStringList &CC1Args) const {
|
||||||
|
// Try generic GCC detection first.
|
||||||
|
if (Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args))
|
||||||
|
return;
|
||||||
|
|
||||||
// We need a detected GCC installation on Linux to provide libstdc++'s
|
// We need a detected GCC installation on Linux to provide libstdc++'s
|
||||||
// headers.
|
// headers in odd Linuxish places.
|
||||||
if (!GCCInstallation.isValid())
|
if (!GCCInstallation.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// By default, look for the C++ headers in an include directory adjacent to
|
|
||||||
// the lib directory of the GCC installation. Note that this is expect to be
|
|
||||||
// equivalent to '/usr/include/c++/X.Y' in almost all cases.
|
|
||||||
StringRef LibDir = GCCInstallation.getParentLibPath();
|
StringRef LibDir = GCCInstallation.getParentLibPath();
|
||||||
StringRef InstallDir = GCCInstallation.getInstallPath();
|
|
||||||
StringRef TripleStr = GCCInstallation.getTriple().str();
|
StringRef TripleStr = GCCInstallation.getTriple().str();
|
||||||
const Multilib &Multilib = GCCInstallation.getMultilib();
|
const Multilib &Multilib = GCCInstallation.getMultilib();
|
||||||
const std::string GCCMultiarchTriple = getMultiarchTriple(
|
|
||||||
getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);
|
|
||||||
const std::string TargetMultiarchTriple =
|
|
||||||
getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
|
|
||||||
const GCCVersion &Version = GCCInstallation.getVersion();
|
const GCCVersion &Version = GCCInstallation.getVersion();
|
||||||
|
|
||||||
// The primary search for libstdc++ supports multiarch variants.
|
|
||||||
if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
|
|
||||||
"/c++/" + Version.Text, TripleStr,
|
|
||||||
GCCMultiarchTriple, TargetMultiarchTriple,
|
|
||||||
Multilib.includeSuffix(), DriverArgs, CC1Args))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Otherwise, fall back on a bunch of options which don't use multiarch
|
|
||||||
// layouts for simplicity.
|
|
||||||
const std::string LibStdCXXIncludePathCandidates[] = {
|
const std::string LibStdCXXIncludePathCandidates[] = {
|
||||||
// Gentoo is weird and places its headers inside the GCC install,
|
|
||||||
// so if the first attempt to find the headers fails, try these patterns.
|
|
||||||
InstallDir.str() + "/include/g++-v" + Version.Text,
|
|
||||||
InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
|
|
||||||
Version.MinorStr,
|
|
||||||
InstallDir.str() + "/include/g++-v" + Version.MajorStr,
|
|
||||||
// Android standalone toolchain has C++ headers in yet another place.
|
// Android standalone toolchain has C++ headers in yet another place.
|
||||||
LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
|
LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
|
||||||
// Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
|
// Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
|
||||||
|
|
|
@ -26,9 +26,6 @@ public:
|
||||||
void
|
void
|
||||||
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args) const override;
|
llvm::opt::ArgStringList &CC1Args) const override;
|
||||||
void addLibCxxIncludePaths(
|
|
||||||
const llvm::opt::ArgList &DriverArgs,
|
|
||||||
llvm::opt::ArgStringList &CC1Args) const override;
|
|
||||||
void addLibStdCxxIncludePaths(
|
void addLibStdCxxIncludePaths(
|
||||||
const llvm::opt::ArgList &DriverArgs,
|
const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args) const override;
|
llvm::opt::ArgStringList &CC1Args) const override;
|
||||||
|
@ -52,6 +49,10 @@ public:
|
||||||
protected:
|
protected:
|
||||||
Tool *buildAssembler() const override;
|
Tool *buildAssembler() const override;
|
||||||
Tool *buildLinker() const override;
|
Tool *buildLinker() const override;
|
||||||
|
|
||||||
|
std::string getMultiarchTriple(const Driver &D,
|
||||||
|
const llvm::Triple &TargetTriple,
|
||||||
|
StringRef SysRoot) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace toolchains
|
} // end namespace toolchains
|
||||||
|
|
Loading…
Reference in New Issue