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

Chandler Carruth chandlerc at gmail.com
Fri Apr 6 09:32:06 PDT 2012


Author: chandlerc
Date: Fri Apr  6 11:32:06 2012
New Revision: 154176

URL: http://llvm.org/viewvc/llvm-project?rev=154176&view=rev
Log:
Fix using Clang as a cross compiler installed on a host machine and not
inside of a sysroot targeting a system+sysroot which is "similar" or
"compatible" with the host system. This shows up when trying to build
system images on largely compatible hardware as-if fully cross compiled.

The problem is that previously we *perfectly* mimiced GCC here, and it
turns out GCC has a bug that no one has really stumbled across. GCC will
try to look in thy system prefix ('/usr/local' f.ex.) into which it is
instaled to find libraries installed along side GCC that should be
preferred to the base system libraries ('/usr' f.ex.). This seems not
unreasonable, but it has a very unfortunate consequence when combined
with a '--sysroot' which does *not* contain the GCC installation we're
using to complete the toolchain. That results in some of the host
system's library directories being searched during the link.

Now, it so happens that most folks doing stuff like this use
'--with-sysroot' and '--disable-multilib' when configuring GCC. Even
better, they're usually not cross-compiling to a target that is similar
to the host. As a result, searching the host for libraries doesn't
really matter -- most of the time weird directories get appended that
don't exist (no arm triple lib directory, etc). Even if you're
cross-compiling from 32-bit to 64-bit x86 or vice-versa, disabling
multilib makes it less likely that you'll actually find viable libraries
on the host. But that's just luck. We shouldn't rely on this, and this
patch disables looking in the system prefix containing the GCC
installation if that system prefix is *outside* of the sysroot. For
empty sysroots, this has no effect. Similarly, when using the GCC
*inside* of the sysroot, we still track wherever it is installed within
the sysroot and look there for libraries. But now we can use a cross
compiler GCC installation outside the system root, and only look for the
crtbegin.o in the GCC installation, and look for all the other libraries
inside the system root.

This should fix PR12478, allowing Clang to be used when building
a ChromiumOS image without polluting the image with libraries from the
host system.

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=154176&r1=154175&r2=154176&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Fri Apr  6 11:32:06 2012
@@ -2059,10 +2059,20 @@
     addPathIfExists((GCCInstallation.getInstallPath() +
                      GCCInstallation.getMultiarchSuffix()),
                     Paths);
-    addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib,
-                    Paths);
-    addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
-    addPathIfExists(LibPath + "/../" + Multilib, Paths);
+
+    // If the GCC installation we found is inside of the sysroot, we want to
+    // prefer libraries installed in the parent prefix of the GCC installation.
+    // It is important to *not* use these paths when the GCC installation is
+    // outside of the system root as that can pick up un-intented libraries.
+    // This usually happens when there is an external cross compiler on the
+    // host system, and a more minimal sysroot available that is the target of
+    // the cross.
+    if (StringRef(LibPath).startswith(SysRoot)) {
+      addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib,
+                      Paths);
+      addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
+      addPathIfExists(LibPath + "/../" + Multilib, Paths);
+    }
   }
   addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
   addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);
@@ -2081,8 +2091,11 @@
     const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
     if (!GCCInstallation.getMultiarchSuffix().empty())
       addPathIfExists(GCCInstallation.getInstallPath(), Paths);
-    addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib", Paths);
-    addPathIfExists(LibPath, Paths);
+
+    if (StringRef(LibPath).startswith(SysRoot)) {
+      addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib", Paths);
+      addPathIfExists(LibPath, Paths);
+    }
   }
   addPathIfExists(SysRoot + "/lib", Paths);
   addPathIfExists(SysRoot + "/usr/lib", Paths);

Modified: cfe/trunk/test/Driver/linux-ld.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/linux-ld.c?rev=154176&r1=154175&r2=154176&view=diff
==============================================================================
--- cfe/trunk/test/Driver/linux-ld.c (original)
+++ cfe/trunk/test/Driver/linux-ld.c Fri Apr  6 11:32:06 2012
@@ -92,6 +92,20 @@
 // CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux -m32 \
+// RUN:     -gcc-toolchain %S/Inputs/multilib_64bit_linux_tree/usr \
+// RUN:     --sysroot=%S/Inputs/multilib_32bit_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-64-TO-32-SYSROOT %s
+// CHECK-64-TO-32-SYSROOT: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-64-TO-32-SYSROOT: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32/crtbegin.o"
+// CHECK-64-TO-32-SYSROOT: "-L{{[^"]*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/32"
+// CHECK-64-TO-32-SYSROOT: "-L[[SYSROOT]]/lib/../lib32"
+// CHECK-64-TO-32-SYSROOT: "-L[[SYSROOT]]/usr/lib/../lib32"
+// CHECK-64-TO-32-SYSROOT: "-L{{[^"]*}}/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0"
+// CHECK-64-TO-32-SYSROOT: "-L[[SYSROOT]]/lib"
+// CHECK-64-TO-32-SYSROOT: "-L[[SYSROOT]]/usr/lib"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux -m32 \
 // RUN:     -ccc-install-dir %S/Inputs/fake_install_tree/bin \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \





More information about the cfe-commits mailing list