Author: Fangrui Song Date: 2021-03-21T12:01:44-07:00 New Revision: bcaca360f8b64d267c787a5f3088e73420e78f53
URL: https://github.com/llvm/llvm-project/commit/bcaca360f8b64d267c787a5f3088e73420e78f53 DIFF: https://github.com/llvm/llvm-project/commit/bcaca360f8b64d267c787a5f3088e73420e78f53.diff LOG: [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` Added: Modified: clang/lib/Driver/ToolChains/Gnu.cpp clang/lib/Driver/ToolChains/Gnu.h Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index b5efa587f8dc..426ab8c4aad4 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -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; diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h index 90d3bafc1f00..aa03c6ed6a05 100644 --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -351,6 +351,12 @@ class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { 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, _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits