[cfe-commits] r143344 - /cfe/trunk/lib/Driver/ToolChains.cpp

Chandler Carruth chandlerc at gmail.com
Mon Oct 31 01:42:24 PDT 2011


Author: chandlerc
Date: Mon Oct 31 03:42:24 2011
New Revision: 143344

URL: http://llvm.org/viewvc/llvm-project?rev=143344&view=rev
Log:
Fix part of PR11223 and probably a few dups as well. This teaches the
library search logic to "properly" handle multiarch installations. I've
tested this on both Debian unstable and the latest Ubuntu which both use
this setup, and this appears to work largely the same way as GCC does.
It isn't exactly the same, but it is close enough and more principled in
its behavior where it differs. This should resolve any failures to find
'crt1.o' etc on Debian-based Linux distributions. If folks find more
cases where we fail, please file bugs and CC me.

Test cases for all of the debian silliness are waiting both to simplify
the process of merging these down into the 3.0 release, and because
they're so crazy I haven't yet been able to really produce a fake tree
that represents what we need to test for. I'll eventually add them
though.

Modified:
    cfe/trunk/lib/Driver/ToolChains.cpp

Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=143344&r1=143343&r2=143344&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Mon Oct 31 03:42:24 2011
@@ -1740,6 +1740,41 @@
   if (PathExists(Path)) Paths.push_back(Path);
 }
 
+/// \brief Get our best guess at the multiarch triple for a target.
+///
+/// Debian-based systems are starting to use a multiarch setup where they use
+/// a target-triple directory in the library and header search paths.
+/// Unfortunately, this triple does not align with the vanilla target triple,
+/// so we provide a rough mapping here.
+static std::string getMultiarchTriple(const llvm::Triple TargetTriple,
+                                      StringRef SysRoot) {
+  // For most architectures, just use whatever we have rather than trying to be
+  // clever.
+  switch (TargetTriple.getArch()) {
+  default:
+    return TargetTriple.str();
+
+    // We use the existence of '/lib/<triple>' as a directory to detect some
+    // common linux triples that don't quite match the Clang triple for both
+    // 32-bit and 64-bit targets. This works around annoying discrepancies on
+    // Debian-based systems.
+  case llvm::Triple::x86:
+    if (llvm::sys::fs::exists(SysRoot + "/lib/i686-linux-gnu"))
+      return "i686-linux-gnu";
+    if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
+      return "i386-linux-gnu";
+    return TargetTriple.str();
+  case llvm::Triple::x86_64:
+    if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
+      return "x86_64-linux-gnu";
+    if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-pc-linux-gnu"))
+      return "x86_64-pc-linux-gnu";
+    if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-unknown-linux-gnu"))
+      return "x86_64-unknown-linux-gnu";
+    return TargetTriple.str();
+  }
+}
+
 Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
   : Generic_ELF(Host, Triple) {
   llvm::Triple::ArchType Arch =
@@ -1800,6 +1835,7 @@
   const std::string Suffix64 = Arch == llvm::Triple::x86_64 ? "" : "/64";
   const std::string Suffix = Is32Bits ? Suffix32 : Suffix64;
   const std::string Multilib = Is32Bits ? "lib32" : "lib64";
+  const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot);
 
   // FIXME: Because we add paths only when they exist on the system, I think we
   // should remove the concept of 'HasMultilib'. It's more likely to break the
@@ -1817,9 +1853,12 @@
       addPathIfExists(GCCInstallation.getInstallPath() + Suffix, Paths);
       addPathIfExists(LibPath + "/../" + GccTriple + "/lib/../" + Multilib,
                       Paths);
+      addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
       addPathIfExists(LibPath + "/../" + Multilib, Paths);
     }
+    addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
     addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);
+    addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
     addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths);
 
     // Try walking via the GCC triple path in case of multiarch GCC
@@ -1836,14 +1875,13 @@
     if (!Suffix.empty() || !HasMultilib(Arch, Distro))
       addPathIfExists(GCCInstallation.getInstallPath(), Paths);
     addPathIfExists(LibPath + "/../" + GccTriple + "/lib", Paths);
+    addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
     addPathIfExists(LibPath, Paths);
   }
+  addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
   addPathIfExists(SysRoot + "/lib", Paths);
+  addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
   addPathIfExists(SysRoot + "/usr/lib", Paths);
-
-  // Add a multiarch lib directory whenever it exists and is plausible.
-  if (GCCInstallation.isValid() && Arch == getArch())
-    addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple(), Paths);
 }
 
 bool Linux::HasNativeLLVMSupport() const {





More information about the cfe-commits mailing list