[cfe-commits] r140981 - in /cfe/trunk: lib/Driver/ToolChains.cpp test/Driver/linux-ld.c

Chandler Carruth chandlerc at gmail.com
Sun Oct 2 22:28:31 PDT 2011


Author: chandlerc
Date: Mon Oct  3 00:28:29 2011
New Revision: 140981

URL: http://llvm.org/viewvc/llvm-project?rev=140981&view=rev
Log:
Rework the selection of builtin library search paths on Linux to
precisely match the pattern and logic used by the GCC driver on Linux as
of a recent SVN checkout.

This happens to follow a *much* more principled approach. There is
a strict hierarchy of paths examined, first with multilib-suffixing,
second without such suffixing. Any and all of these directories which
exist will be added to the library search path when using GCC.

There were many places where Clang followed different paths, omitted
critical entries, and worst of all (in terms of challenges to debugging)
got the entries in a subtly wrong order.

If this breaks Clang on a distro you use, please let me know, and I'll
work with you to figure out what is needed to work on that distro. I've
checked the behavior of the latest release of Ubuntu, OpenSUSE, Fedora,
and Gentoo. I'll be testing it on those as well as Debian stable and
unstable and ArchLinux. I may even dig out a Slackware install.

No real regression tests yet, those will follow once I add enough
support for sysroot to simulate various distro layouts in the testsuite.

Modified:
    cfe/trunk/lib/Driver/ToolChains.cpp
    cfe/trunk/test/Driver/linux-ld.c

Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=140981&r1=140980&r2=140981&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Mon Oct  3 00:28:29 2011
@@ -1549,6 +1549,13 @@
   return "";
 }
 
+static void addPathIfExists(const std::string &Path,
+                            ToolChain::path_list &Paths) {
+  bool Exists;
+  if (!llvm::sys::fs::exists(Path, Exists) && Exists)
+    Paths.push_back(Path);
+}
+
 Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
   : Generic_ELF(Host, Triple) {
   llvm::Triple::ArchType Arch =
@@ -1626,25 +1633,6 @@
   }
 
   std::string Base = findGCCBaseLibDir(getDriver(), GccTriple);
-  path_list &Paths = getFilePaths();
-  bool Is32Bits = (getArch() == llvm::Triple::x86 ||
-                   getArch() == llvm::Triple::ppc);
-
-  const std::string Suffix32 = Arch == llvm::Triple::x86_64 ? "/32" : "";
-  const std::string Suffix64 = Is32Bits ? "/64" : "";
-  const std::string Suffix = Is32Bits ? Suffix32 : Suffix64;
-
-  std::string Lib32 = "lib";
-  if (!llvm::sys::fs::exists("/lib32", Exists) && Exists)
-    Lib32 = "lib32";
-
-  std::string Lib64 = "lib";
-  bool Symlink;
-  if (!llvm::sys::fs::exists("/lib64", Exists) && Exists &&
-      (llvm::sys::fs::is_symlink("/lib64", Symlink) || !Symlink))
-    Lib64 = "lib64";
-
-  std::string Lib = Is32Bits ? Lib32 : Lib64;
 
   // OpenSuse stores the linker with the compiler, add that to the search
   // path.
@@ -1685,27 +1673,50 @@
   if (IsOpenSuse(Distro))
     ExtraOpts.push_back("--enable-new-dtags");
 
-  if (Distro == ArchLinux)
-    Lib = "lib";
+  // The selection of paths to try here is designed to match the patterns which
+  // the GCC driver itself uses, as this is part of the GCC-compatible driver.
+  // This was determined by running GCC in a fake filesystem, creating all
+  // possible permutations of these directories, and seeing which ones it added
+  // to the link paths.
+  path_list &Paths = getFilePaths();
+  const bool Is32Bits = (getArch() == llvm::Triple::x86 ||
+                         getArch() == llvm::Triple::ppc);
+
+  const std::string Suffix32 = Arch == llvm::Triple::x86_64 ? "/32" : "";
+  const std::string Suffix64 = Is32Bits ? "/64" : "";
+  const std::string Suffix = Is32Bits ? Suffix32 : Suffix64;
+  const std::string Multilib = Is32Bits ? "lib32" : "lib64";
 
-  Paths.push_back(Base + Suffix);
+  // 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
+  // behavior than to preserve any useful invariant on the system.
   if (HasMultilib(Arch, Distro)) {
+    // FIXME: This OpenSuse-specific path shouldn't be needed any more, but
+    // I don't want to remove it without finding someone to test.
     if (IsOpenSuse(Distro) && Is32Bits)
       Paths.push_back(Base + "/../../../../" + GccTriple + "/lib/../lib");
-    Paths.push_back(Base + "/../../../../" + Lib);
+
+    // Add the multilib suffixed paths.
+    if (!Base.empty() && !GccTriple.empty()) {
+      addPathIfExists(Base + Suffix, Paths);
+      addPathIfExists(Base + "/../../../../" + GccTriple + "/lib/../" +
+                      Multilib, Paths);
+      addPathIfExists(Base + "/../../../../" + Multilib, Paths);
+    }
+    addPathIfExists("/lib/../" + Multilib, Paths);
+    addPathIfExists("/usr/lib/../" + Multilib, Paths);
   }
 
-  // FIXME: This is in here to find crt1.o. It is provided by libc, and
-  // libc (like gcc), can be installed in any directory. Once we are
-  // fetching this from a config file, we should have a libc prefix.
-  Paths.push_back("/lib/../" + Lib);
-  Paths.push_back("/usr/lib/../" + Lib);
+  // Add the non-multiplib suffixed paths (if potentially different).
+  if (!Base.empty() && !GccTriple.empty()) {
+    if (!Suffix.empty())
+      addPathIfExists(Base, Paths);
+    addPathIfExists(Base + "/../../../../" + GccTriple + "/lib", Paths);
+    addPathIfExists(Base + "/../../..", Paths);
+  }
+  addPathIfExists("/lib", Paths);
+  addPathIfExists("/usr/lib", Paths);
 
-  if (!Suffix.empty())
-    Paths.push_back(Base);
-  if (IsOpenSuse(Distro))
-    Paths.push_back(Base + "/../../../../" + GccTriple + "/lib");
-  Paths.push_back(Base + "/../../..");
   if (Arch == getArch() && IsUbuntu(Distro))
     Paths.push_back("/usr/lib/" + GccTriple);
 }

Modified: cfe/trunk/test/Driver/linux-ld.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/linux-ld.c?rev=140981&r1=140980&r2=140981&view=diff
==============================================================================
--- cfe/trunk/test/Driver/linux-ld.c (original)
+++ cfe/trunk/test/Driver/linux-ld.c Mon Oct  3 00:28:29 2011
@@ -2,8 +2,8 @@
 //
 // RUN: %clang -no-canonical-prefixes -ccc-host-triple i386-unknown-linux %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-LD-32 %s
-// CHECK-LD-32: "{{.*}}ld{{(.exe)?}}" {{.*}} "-L/lib/../lib{{(32)?}}" "-L/usr/lib/../lib{{(32)?}}"
+// CHECK-LD-32: "{{.*}}ld{{(.exe)?}}" {{.*}} "-L/lib" "-L/usr/lib"
 //
 // RUN: %clang -no-canonical-prefixes -ccc-host-triple x86_64-unknown-linux %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-LD-64 %s
-// CHECK-LD-64: "{{.*}}ld{{(.exe)?}}" {{.*}} "-L/lib/../lib{{(64)?}}" "-L/usr/lib/../lib{{(64)?}}"
+// CHECK-LD-64: "{{.*}}ld{{(.exe)?}}" {{.*}} "-L/lib" "-L/usr/lib"





More information about the cfe-commits mailing list