Bill, it'd be great to get this and r142134 (which fixed a buglet) merged into the 3.0 branch if possible. Early experiments show it fixes linking for many Debian systems.<br><br><div class="gmail_quote">On Sun, Oct 16, 2011 at 3:54 AM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com">chandlerc@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Author: chandlerc<br>
Date: Sun Oct 16 05:54:30 2011<br>
New Revision: 142133<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=142133&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=142133&view=rev</a><br>
Log:<br>
Clean up some cruft in the library path searching logic by making<br>
'libdir' mean the actual library directory, not the GCC subdirectory of<br>
the library directory. That was just a confusing pattern. Instead,<br>
supply proper GCC subdirectories when scanning for various triple-based<br>
subdirectories with a GCC installation in them. This also makes it much<br>
more obvious how multiarch installations, which have a triple-based<br>
prefix as well as suffix work.<br>
<br>
Also clean up our handling of these triple-prefixed trees by using them<br>
in both a multiarch pattern and a non-multiarch pattern whenever they<br>
exist.<br>
<br>
Note that this *does not* match what GCC does on Debian, the only truly<br>
multiarch installation I've been able to get installed and test on. GCC<br>
appears to have a bug, and ends up searching paths like<br>
'/lib/../../lib32' which makes no sense what-so-ever. Instead, I've<br>
tried to encode the rational logic that seems clearly intended by GCC's<br>
pattern. GCC ends up with patterns like:<br>
<br>
  /lib/../../lib32<br>
  /usr/lib/../../lib32<br>
  /usr/lib/x86_64-linux-gnu/../..lib32<br>
<br>
Only the last one makes any sense having a '/../..' in it, so in Clang,<br>
that's the only one which gets a '/../..' in it.<br>
<br>
I *think* this will fix Debian multiarch links. I'm committing without<br>
baking this logic into our test suite so I can test on a few different<br>
systems. If all goes well (and no one screams) I'll check in some more<br>
comprehensive tests for multiarch behavior tomorrow.<br>
<br>
Modified:<br>
    cfe/trunk/lib/Driver/ToolChains.cpp<br>
<br>
Modified: cfe/trunk/lib/Driver/ToolChains.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=142133&r1=142132&r2=142133&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=142133&r1=142132&r2=142133&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)<br>
+++ cfe/trunk/lib/Driver/ToolChains.cpp Sun Oct 16 05:54:30 2011<br>
@@ -1631,14 +1631,12 @@<br>
                                        SmallVectorImpl<StringRef> &LibDirs,<br>
                                        SmallVectorImpl<StringRef> &Triples) {<br>
     if (HostArch == llvm::Triple::arm || HostArch == llvm::Triple::thumb) {<br>
-      static const char *const ARMLibDirs[] = { "/lib/gcc" };<br>
+      static const char *const ARMLibDirs[] = { "/lib" };<br>
       static const char *const ARMTriples[] = { "arm-linux-gnueabi" };<br>
       LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));<br>
       Triples.append(ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));<br>
     } else if (HostArch == llvm::Triple::x86_64) {<br>
-      static const char *const X86_64LibDirs[] = {<br>
-        "/lib64/gcc", "/lib/gcc", "/lib64", "/lib"<br>
-      };<br>
+      static const char *const X86_64LibDirs[] = { "/lib64", "/lib" };<br>
       static const char *const X86_64Triples[] = {<br>
         "x86_64-linux-gnu",<br>
         "x86_64-unknown-linux-gnu",<br>
@@ -1655,9 +1653,7 @@<br>
       Triples.append(X86_64Triples,<br>
                      X86_64Triples + llvm::array_lengthof(X86_64Triples));<br>
     } else if (HostArch == llvm::Triple::x86) {<br>
-      static const char *const X86LibDirs[] = {<br>
-        "/lib32/gcc", "/lib/gcc", "/lib32", "/lib"<br>
-      };<br>
+      static const char *const X86LibDirs[] = { "/lib32", "/lib" };<br>
       static const char *const X86Triples[] = {<br>
         "i686-linux-gnu",<br>
         "i386-linux-gnu",<br>
@@ -1671,9 +1667,7 @@<br>
       LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));<br>
       Triples.append(X86Triples, X86Triples + llvm::array_lengthof(X86Triples));<br>
     } else if (HostArch == llvm::Triple::ppc) {<br>
-      static const char *const PPCLibDirs[] = {<br>
-        "/lib32/gcc", "/lib/gcc", "/lib32", "/lib"<br>
-      };<br>
+      static const char *const PPCLibDirs[] = { "/lib32", "/lib" };<br>
       static const char *const PPCTriples[] = {<br>
         "powerpc-linux-gnu",<br>
         "powerpc-unknown-linux-gnu"<br>
@@ -1681,9 +1675,7 @@<br>
       LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs));<br>
       Triples.append(PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples));<br>
     } else if (HostArch == llvm::Triple::ppc64) {<br>
-      static const char *const PPC64LibDirs[] = {<br>
-        "/lib64/gcc", "/lib/gcc", "/lib64", "/lib"<br>
-      };<br>
+      static const char *const PPC64LibDirs[] = { "/lib64", "/lib" };<br>
       static const char *const PPC64Triples[] = {<br>
         "powerpc64-unknown-linux-gnu"<br>
       };<br>
@@ -1697,23 +1689,31 @@<br>
   void ScanLibDirForGCCTriple(const std::string &LibDir,<br>
                               StringRef CandidateTriple,<br>
                               GCCVersion &BestVersion) {<br>
-    const std::string TripleDir = LibDir + "/" + CandidateTriple.str();<br>
-    if (!PathExists(TripleDir))<br>
-      return;<br>
-<br>
-    // There are various different suffixes on the triple directory we<br>
+    // There are various different suffixes involving the triple we<br>
     // check for. We also record what is necessary to walk from each back<br>
     // up to the lib directory.<br>
-    const std::string Suffixes[] = { "", "/gcc/" + CandidateTriple.str(),<br>
-      "/gcc/i686-linux-gnu" };<br>
-    const std::string InstallSuffixes[] = { "/../../..", "/../../../..",<br>
-      "/../../../.." };<br>
+    const std::string Suffixes[] = {<br>
+      "/gcc/" + CandidateTriple.str(),<br>
+      CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),<br>
+<br>
+      // Ubuntu has a strange mis-matched pair of triples that this happens to<br>
+      // match.<br>
+      // FIXME: It may be worthwhile to generalize this and look for a second<br>
+      // triple.<br>
+      CandidateTriple.str() + "/gcc/i686-linux-gnu"<br>
+    };<br>
+    const std::string InstallSuffixes[] = {<br>
+      "/../../..",<br>
+      "/../../../..",<br>
+      "/../../../.."<br>
+    };<br>
+    // Only look at the final, weird Ubuntu suffix for i386-linux-gnu.<br>
     const unsigned NumSuffixes = (llvm::array_lengthof(Suffixes) -<br>
                                   (CandidateTriple != "i386-linux-gnu"));<br>
     for (unsigned i = 0; i < NumSuffixes; ++i) {<br>
       StringRef Suffix = Suffixes[i];<br>
       llvm::error_code EC;<br>
-      for (llvm::sys::fs::directory_iterator LI(TripleDir + Suffix, EC), LE;<br>
+      for (llvm::sys::fs::directory_iterator LI(LibDir + Suffix, EC), LE;<br>
            !EC && LI != LE; LI = LI.increment(EC)) {<br>
         StringRef VersionText = llvm::sys::path::filename(LI->path());<br>
         GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);<br>
@@ -1730,7 +1730,7 @@<br>
         // FIXME: We hack together the directory name here instead of<br>
         // using LI to ensure stable path separators across Windows and<br>
         // Linux.<br>
-        GccInstallPath = TripleDir + Suffixes[i] + "/" + VersionText.str();<br>
+        GccInstallPath = LibDir + Suffixes[i] + "/" + VersionText.str();<br>
         GccParentLibPath = GccInstallPath + InstallSuffixes[i];<br>
         IsValid = true;<br>
       }<br>
@@ -1825,9 +1825,15 @@<br>
     }<br>
     addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);<br>
     addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths);<br>
+<br>
+    // Try walking via the GCC triple path in case of multiarch GCC<br>
+    // installations with strange symlinks.<br>
+    if (GCCInstallation.isValid())<br>
+      addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple() +<br>
+                      "/../../" + Multilib, Paths);<br>
   }<br>
<br>
-  // Add the non-multiplib suffixed paths (if potentially different).<br>
+  // Add the non-multilib suffixed paths (if potentially different).<br>
   if (GCCInstallation.isValid()) {<br>
     const std::string &LibPath = GCCInstallation.getParentLibPath();<br>
     const std::string &GccTriple = GCCInstallation.getTriple();<br>
@@ -1839,8 +1845,9 @@<br>
   addPathIfExists(SysRoot + "/lib", Paths);<br>
   addPathIfExists(SysRoot + "/usr/lib", Paths);<br>
<br>
-  if (GCCInstallation.isValid() && Arch == getArch() && IsUbuntu(Distro))<br>
-    Paths.push_back(SysRoot + "/usr/lib/" + GCCInstallation.getTriple());<br>
+  // Add a multiarch lib directory whenever it exists and is plausible.<br>
+  if (GCCInstallation.isValid() && Arch == getArch())<br>
+    addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple(), Paths);<br>
 }<br>
<br>
 bool Linux::HasNativeLLVMSupport() const {<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br>