diff options
author | Bill Wendling <isanbard@gmail.com> | 2014-08-27 20:07:13 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2014-08-27 20:07:13 +0000 |
commit | d2cd7c5902a610d49941db2594c2e017f5d0d6d2 (patch) | |
tree | b8785ff7ddcfba3bf6e6430d5c1f7a13f5a32951 | |
parent | 76d25814502bea0f14f7e57c29fdd990819a7b3f (diff) |
Merging r216531:
------------------------------------------------------------------------
r216531 | chandlerc | 2014-08-27 01:41:41 -0700 (Wed, 27 Aug 2014) | 22 lines
Significantly fix Clang's header search for Ubuntu (and possibly other
modern Debian-based distributions) due to on-going multiarch madness.
It appears that when the multiarch heeader search support went into the
clang driver, it went in in a quite bad state. The order of includes
completely failed to match the order exhibited by GCC, and in a specific
case -- when the GCC triple and the multiarch triple don't match as with
i686-linux-gnu and i386-linux-gnu -- we would absolutely fail to find
the libstdc++ target-specific header files.
I assume that folks who have been using Clang on Ubuntu 32-bit systems
have been applying weird patches to hack around this. I can't imagine
how else it could have worked. This was originally reported by a 64-bit
operating system user who had a 32-bit crosscompiler installed. We tried
to use that rather than the bi-arch support of the 64-bit compiler, but
failed due to the triple differences.
I've corrected all the wrong orderings in the existing tests and added
a specific test for the multiarch triple strings that are different in
a significant way. This should significantly improve the usability of
Clang when checked out vanilla from upstream onto Ubuntu machines with
an i686 GCC installation for whatever reason.
------------------------------------------------------------------------
llvm-svn: 216587
13 files changed, 64 insertions, 38 deletions
diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index 4deaaae0bbac..9b79c9a3d763 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -3386,32 +3386,39 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); } -/// \brief Helper to add the three variant paths for a libstdc++ installation. -/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, - const ArgList &DriverArgs, - ArgStringList &CC1Args) { - if (!llvm::sys::fs::exists(Base)) - return false; - addSystemInclude(DriverArgs, CC1Args, Base); - addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir); - addSystemInclude(DriverArgs, CC1Args, Base + "/backward"); - return true; -} - -/// \brief Helper to add an extra variant path for an (Ubuntu) multilib -/// libstdc++ installation. +/// \brief Helper to add the variant paths of a libstdc++ installation. /*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix, - Twine TargetArchDir, + StringRef GCCTriple, + StringRef GCCMultiarchTriple, + StringRef TargetMultiarchTriple, Twine IncludeSuffix, const ArgList &DriverArgs, ArgStringList &CC1Args) { - if (!addLibStdCXXIncludePaths(Base + Suffix, - TargetArchDir + IncludeSuffix, - DriverArgs, CC1Args)) + if (!llvm::sys::fs::exists(Base)) return false; - addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix - + IncludeSuffix); + addSystemInclude(DriverArgs, CC1Args, Base + Suffix); + + // The vanilla GCC layout of libstdc++ headers uses a triple subdirectory. If + // that path exists or we have neither a GCC nor target multiarch triple, use + // this vanilla search path. + if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) || + llvm::sys::fs::exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) { + addSystemInclude(DriverArgs, CC1Args, + Base + Suffix + "/" + GCCTriple + IncludeSuffix); + } 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"); return true; } @@ -3455,13 +3462,21 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, StringRef InstallDir = GCCInstallation.getInstallPath(); StringRef TripleStr = GCCInstallation.getTriple().str(); const Multilib &Multilib = GCCInstallation.getMultilib(); + const std::string GCCMultiarchTriple = + getMultiarchTriple(GCCInstallation.getTriple(), getDriver().SysRoot); + const std::string TargetMultiarchTriple = + getMultiarchTriple(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, + "/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[] = { // Gentoo is weird and places its headers inside the GCC install, so if the // first attempt to find the headers fails, try these patterns. @@ -3476,9 +3491,10 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, }; for (const auto &IncludePath : LibStdCXXIncludePathCandidates) { - if (addLibStdCXXIncludePaths(IncludePath, - TripleStr + Multilib.includeSuffix(), - DriverArgs, CC1Args)) + if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr, + /*GCCMultiarchTriple*/ "", + /*TargetMultiarchTriple*/ "", + Multilib.includeSuffix(), DriverArgs, CC1Args)) break; } } diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h index b6c2cb81e408..b5df8668d69e 100644 --- a/clang/lib/Driver/ToolChains.h +++ b/clang/lib/Driver/ToolChains.h @@ -678,10 +678,10 @@ protected: private: static bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, - Twine TargetArchDir, Twine IncludeSuffix, - const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args); - static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir, + StringRef GCCTriple, + StringRef GCCMultiarchTriple, + StringRef TargetMultiarchTriple, + Twine IncludeSuffix, const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args); diff --git a/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/lib/i386-linux-gnu/.keep b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/lib/i386-linux-gnu/.keep new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/lib/i386-linux-gnu/.keep diff --git a/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/lib/x86_64-linux-gnu/.keep b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/lib/x86_64-linux-gnu/.keep new file mode 100755 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/lib/x86_64-linux-gnu/.keep diff --git a/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/c++/4.8/backward/.keep b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/c++/4.8/backward/.keep new file mode 100755 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/c++/4.8/backward/.keep diff --git a/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/i386-linux-gnu/c++/4.8/.keep b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/i386-linux-gnu/c++/4.8/.keep new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/i386-linux-gnu/c++/4.8/.keep diff --git a/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep new file mode 100755 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep diff --git a/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/i686-linux-gnu/4.8/crtbegin.o b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/i686-linux-gnu/4.8/crtbegin.o new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/i686-linux-gnu/4.8/crtbegin.o diff --git a/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o new file mode 100755 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o diff --git a/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o new file mode 100755 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o diff --git a/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/i386-linux-gnu/.keep b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/i386-linux-gnu/.keep new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/i386-linux-gnu/.keep diff --git a/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/x86_64-linux-gnu/.keep b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/x86_64-linux-gnu/.keep new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/clang/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/x86_64-linux-gnu/.keep diff --git a/clang/test/Driver/linux-header-search.cpp b/clang/test/Driver/linux-header-search.cpp index 9635519ad0cb..309ece28db77 100644 --- a/clang/test/Driver/linux-header-search.cpp +++ b/clang/test/Driver/linux-header-search.cpp @@ -46,8 +46,8 @@ // CHECK-UBUNTU-13-04: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CHECK-UBUNTU-13-04: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7" -// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward" // CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/x86_64-linux-gnu/c++/4.7" +// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward" // CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-UBUNTU-13-04: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include" // CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu" @@ -61,9 +61,8 @@ // CHECK-UBUNTU-14-04: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CHECK-UBUNTU-14-04: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8" -// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu/x32" -// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" // CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/x32" +// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" // CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-UBUNTU-14-04: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|x32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include" // CHECK-UBUNTU-14-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu" @@ -77,8 +76,8 @@ // CHECK-UBUNTU-13-04-CROSS: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CHECK-UBUNTU-13-04-CROSS: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/c++/4.7" -// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/c++/4.7/backward" // CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/arm-linux-gnueabihf/c++/4.7" +// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/c++/4.7/backward" // CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include" // CHECK-UBUNTU-13-04-CROSS: "-internal-externc-isystem" "[[SYSROOT]]/include" @@ -93,9 +92,8 @@ // CHECK-UBUNTU-13-04-M32: "-triple" "i386-unknown-linux-gnu" // CHECK-UBUNTU-13-04-M32: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7" -// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/x86_64-linux-gnu/32" -// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward" // CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/x86_64-linux-gnu/c++/4.7/32" +// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward" // // Test Ubuntu/Debian's Ubuntu 14.04 config variant, with -m32 // and an empty 4.9 directory. @@ -107,9 +105,22 @@ // CHECK-UBUNTU-14-04-M32: "-triple" "i386-unknown-linux-gnu" // CHECK-UBUNTU-14-04-M32: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8" -// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu/32" -// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" // CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/32" +// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" +// +// Test Ubuntu/Debian's Ubuntu 14.04 with -m32 and an i686 cross compiler +// installed rather than relying on multilib. Also happens to look like an +// actual i686 Ubuntu system. +// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ +// RUN: -target x86_64-unknown-linux-gnu -m32 \ +// RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree2 \ +// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-I686 %s +// CHECK-UBUNTU-14-04-I686: "{{[^"]*}}clang{{[^"]*}}" "-cc1" +// CHECK-UBUNTU-14-04-I686: "-triple" "i386-unknown-linux-gnu" +// CHECK-UBUNTU-14-04-I686: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-UBUNTU-14-04-I686: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.8/../../../../include/c++/4.8" +// CHECK-UBUNTU-14-04-I686: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.8/../../../../include/i386-linux-gnu/c++/4.8" +// CHECK-UBUNTU-14-04-I686: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.8/../../../../include/c++/4.8/backward" // // Test Ubuntu/Debian's Ubuntu 14.04 for powerpc64le // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ @@ -120,9 +131,8 @@ // CHECK-UBUNTU-14-04-PPC64LE: "-triple" "powerpc64le-unknown-linux-gnu" // CHECK-UBUNTU-14-04-PPC64LE: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8" -// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8/powerpc64le-linux-gnu" -// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8/backward" // CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/powerpc64le-linux-gnu/c++/4.8" +// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8/backward" // CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/powerpc64le-linux-gnu" // CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/include" // CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" |