forked from OSchip/llvm-project
[Driver] Gnu.cpp: fix libstdc++ search path for multilib
With this change, on Debian x86-64 (with a MULTILIB_OSDIRNAMES local patch ../lib64 -> ../lib; this does not matter because /usr/lib64/crt{1,i,n}.o do not exist), `clang++ --target=aarch64-linux-gnu a.cc -Wl,--dynamic-linker=/usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 -Wl,-rpath,/usr/aarch64-linux-gnu/lib` built executable can run under qemu-user. Previously this failed with `/usr/lib/gcc-cross/aarch64-linux-gnu/10/../../../../include/c++/10/iostream:38:10: fatal error: 'bits/c++config.h' file not found` On Arch Linux, due to the MULTILIB_OSDIRNAMES patch and the existence of /usr/lib64/crt{1,i,n}.o, clang driver may pick /usr/lib64/crt{1,i,n}.o and cause a linker error. -B can work around the problem. `clang++ --target=aarch64-linux-gnu -B /usr/aarch64-linux-gnu/lib a.cc -Wl,--dynamic-linker=/usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 -Wl,-rpath,/usr/aarch64-linux-gnu/lib64:/usr/aarch64-linux-gnu/lib`
This commit is contained in:
parent
c53a1322f3
commit
bcaca360f8
|
@ -2945,6 +2945,23 @@ Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
|||
return;
|
||||
}
|
||||
|
||||
bool Generic_GCC::addLibStdCXXIncludePaths(
|
||||
Twine IncludeDir, StringRef Triple, Twine IncludeSuffix,
|
||||
const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const {
|
||||
if (!getVFS().exists(IncludeDir))
|
||||
return false;
|
||||
|
||||
// GPLUSPLUS_INCLUDE_DIR
|
||||
addSystemInclude(DriverArgs, CC1Args, IncludeDir);
|
||||
// GPLUSPLUS_TOOL_INCLUDE_DIR
|
||||
addSystemInclude(DriverArgs, CC1Args,
|
||||
IncludeDir + "/" + Triple + IncludeSuffix);
|
||||
// GPLUSPLUS_BACKWARD_INCLUDE_DIR
|
||||
addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward");
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Helper to add the variant paths of a libstdc++ installation.
|
||||
bool Generic_GCC::addLibStdCXXIncludePaths(
|
||||
Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple,
|
||||
|
@ -2965,13 +2982,8 @@ bool Generic_GCC::addLibStdCXXIncludePaths(
|
|||
} else {
|
||||
// Otherwise try to use multiarch naming schemes which have normalized the
|
||||
// triples and put the triple before the suffix.
|
||||
//
|
||||
// GCC surprisingly uses *both* the GCC triple with a multilib suffix and
|
||||
// the target triple, so we support that here.
|
||||
addSystemInclude(DriverArgs, CC1Args,
|
||||
Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix);
|
||||
addSystemInclude(DriverArgs, CC1Args,
|
||||
Base + "/" + TargetMultiarchTriple + Suffix);
|
||||
}
|
||||
|
||||
addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward");
|
||||
|
@ -2992,16 +3004,23 @@ Generic_GCC::addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
|||
StringRef InstallDir = GCCInstallation.getInstallPath();
|
||||
StringRef TripleStr = GCCInstallation.getTriple().str();
|
||||
const Multilib &Multilib = GCCInstallation.getMultilib();
|
||||
const std::string GCCMultiarchTriple = getMultiarchTriple(
|
||||
const std::string Triple = 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() + "/../" + Triple + "/include/c++/" + Version.Text,
|
||||
TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args))
|
||||
return true;
|
||||
|
||||
// Debian host g++ needs this for
|
||||
// /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/{c++/10,x86_64-linux-gnu/c++/10,c++/10/backward}
|
||||
// FIXME Some other toolchains incorrectly rely on this hierarchy.
|
||||
if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
|
||||
"/c++/" + Version.Text, TripleStr,
|
||||
GCCMultiarchTriple, TargetMultiarchTriple,
|
||||
"/c++/" + Version.Text, TripleStr, Triple, "",
|
||||
Multilib.includeSuffix(), DriverArgs, CC1Args))
|
||||
return true;
|
||||
|
||||
|
|
|
@ -351,6 +351,12 @@ protected:
|
|||
addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const;
|
||||
|
||||
bool addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple,
|
||||
Twine IncludeSuffix,
|
||||
const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const;
|
||||
// FIXME This is used for libstdc++ include directories used by Debian host
|
||||
// g++. It should not used by other toolchains.
|
||||
bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple,
|
||||
StringRef GCCMultiarchTriple,
|
||||
StringRef TargetMultiarchTriple,
|
||||
|
|
Loading…
Reference in New Issue