[clang] 28d58d8 - [Driver] Stop searching other prefixes once a GCC installation is found in one prefix

Fangrui Song via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 19 20:36:07 PDT 2021


Author: Fangrui Song
Date: 2021-03-19T20:35:59-07:00
New Revision: 28d58d8fe2094af6902dee7b4d68ec30a3e9d737

URL: https://github.com/llvm/llvm-project/commit/28d58d8fe2094af6902dee7b4d68ec30a3e9d737
DIFF: https://github.com/llvm/llvm-project/commit/28d58d8fe2094af6902dee7b4d68ec30a3e9d737.diff

LOG: [Driver] Stop searching other prefixes once a GCC installation is found in one prefix

so that when --sysroot is specified, the detected GCC installation will not be
overridden by another from /usr which happens to have a larger version.

This behavior is particularly inconvenient when the system has a larger version
GCC while the user wants to try out an older sysroot.

Delete some tests from linux-ld.c which overlap with cross-linux.c

Added: 
    

Modified: 
    clang/lib/Driver/ToolChains/Gnu.cpp
    clang/test/Driver/linux-ld.c
    clang/unittests/Driver/ToolChainTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 38971288e38f..eb32f4b920b5 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -1955,7 +1955,8 @@ void Generic_GCC::GCCInstallationDetector::init(
 
   // Loop over the various components which exist and select the best GCC
   // installation available. GCC installs are ranked by version number.
-  Version = GCCVersion::Parse("0.0.0");
+  const GCCVersion VersionZero = GCCVersion::Parse("0.0.0");
+  Version = VersionZero;
   for (const std::string &Prefix : Prefixes) {
     auto &VFS = D.getVFS();
     if (!VFS.exists(Prefix))
@@ -1988,6 +1989,10 @@ void Generic_GCC::GCCInstallationDetector::init(
         ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, true,
                                GCCDirExists, GCCCrossDirExists);
     }
+
+    // Skip other prefixes once a GCC installation is found.
+    if (Version > VersionZero)
+      break;
   }
 }
 

diff  --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c
index eba09d2970cc..1aa955737438 100644
--- a/clang/test/Driver/linux-ld.c
+++ b/clang/test/Driver/linux-ld.c
@@ -507,28 +507,6 @@
 // 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 -rtlib=platform -m32 \
-// RUN:     -ccc-install-dir %S/Inputs/fake_install_tree/bin \
-// RUN:     --gcc-toolchain="" \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-INSTALL-DIR-32 %s
-// CHECK-INSTALL-DIR-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// CHECK-INSTALL-DIR-32: "{{.*}}/Inputs/fake_install_tree/bin/../lib/gcc/i386-unknown-linux/4.7.0{{/|\\\\}}crtbegin.o"
-// CHECK-INSTALL-DIR-32: "-L{{.*}}/Inputs/fake_install_tree/bin/../lib/gcc/i386-unknown-linux/4.7.0"
-//
-// Check that with 64-bit builds, we don't actually use the install directory
-// as its version of GCC is lower than our sysrooted version.
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=x86_64-unknown-linux -rtlib=platform -m64 \
-// RUN:     -ccc-install-dir %S/Inputs/fake_install_tree/bin \
-// RUN:     --gcc-toolchain="" \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-INSTALL-DIR-64 %s
-// CHECK-INSTALL-DIR-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// CHECK-INSTALL-DIR-64: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o"
-// CHECK-INSTALL-DIR-64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0"
-//
 // Check that we support unusual patch version formats, including missing that
 // component.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
@@ -538,45 +516,8 @@
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-GCC-VERSION1 %s
 // CHECK-GCC-VERSION1: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// CHECK-GCC-VERSION1: "{{.*}}/Inputs/gcc_version_parsing1/bin/../lib/gcc/i386-unknown-linux/4.7{{/|\\\\}}crtbegin.o"
-// CHECK-GCC-VERSION1: "-L{{.*}}/Inputs/gcc_version_parsing1/bin/../lib/gcc/i386-unknown-linux/4.7"
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=i386-unknown-linux -rtlib=platform -m32 \
-// RUN:     -ccc-install-dir %S/Inputs/gcc_version_parsing2/bin \
-// RUN:     --gcc-toolchain="" \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-GCC-VERSION2 %s
-// CHECK-GCC-VERSION2: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// CHECK-GCC-VERSION2: "{{.*}}/Inputs/gcc_version_parsing2/bin/../lib/gcc/i386-unknown-linux/4.7.x{{/|\\\\}}crtbegin.o"
-// CHECK-GCC-VERSION2: "-L{{.*}}/Inputs/gcc_version_parsing2/bin/../lib/gcc/i386-unknown-linux/4.7.x"
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=i386-unknown-linux -rtlib=platform -m32 \
-// RUN:     -ccc-install-dir %S/Inputs/gcc_version_parsing3/bin \
-// RUN:     --gcc-toolchain="" \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-GCC-VERSION3 %s
-// CHECK-GCC-VERSION3: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// CHECK-GCC-VERSION3: "{{.*}}/Inputs/gcc_version_parsing3/bin/../lib/gcc/i386-unknown-linux/4.7.99-rc5{{/|\\\\}}crtbegin.o"
-// CHECK-GCC-VERSION3: "-L{{.*}}/Inputs/gcc_version_parsing3/bin/../lib/gcc/i386-unknown-linux/4.7.99-rc5"
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=i386-unknown-linux -rtlib=platform -m32 \
-// RUN:     -ccc-install-dir %S/Inputs/gcc_version_parsing4/bin \
-// RUN:     --gcc-toolchain="" \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-GCC-VERSION4 %s
-// CHECK-GCC-VERSION4: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// CHECK-GCC-VERSION4: "{{.*}}/Inputs/gcc_version_parsing4/bin/../lib/gcc/i386-unknown-linux/4.7.99{{/|\\\\}}crtbegin.o"
-// CHECK-GCC-VERSION4: "-L{{.*}}/Inputs/gcc_version_parsing4/bin/../lib/gcc/i386-unknown-linux/4.7.99"
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=i386-unknown-linux -rtlib=platform -m32 \
-// RUN:     -ccc-install-dir %S/Inputs/gcc_version_parsing5/bin \
-// RUN:     --gcc-toolchain="" \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-GCC-VERSION5 %s
-// CHECK-GCC-VERSION5: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// CHECK-GCC-VERSION5: "{{.*}}/Inputs/gcc_version_parsing5/bin/../lib/gcc/i386-unknown-linux/5{{/|\\\\}}crtbegin.o"
-// CHECK-GCC-VERSION5: "-L{{.*}}/Inputs/gcc_version_parsing5/bin/../lib/gcc/i386-unknown-linux/5"
-//
+// CHECK-GCC-VERSION1: "{{.*}}/Inputs/basic_linux_tree/usr/lib/gcc/i386-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o"
+
 // Test a simulated installation of libc++ on Linux, both through sysroot and
 // the installation path of Clang.
 // RUN: %clangxx -no-canonical-prefixes -x c++ %s -### -o %t.o 2>&1 \

diff  --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp
index 35060563ab97..87f476c98dc9 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -31,11 +31,8 @@ TEST(ToolChainTest, VFSGCCInstallation) {
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
-  Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags,
-                   "clang LLVM compiler", InMemoryFileSystem);
 
   const char *EmptyFiles[] = {
       "foo.cpp",
@@ -53,31 +50,78 @@ TEST(ToolChainTest, VFSGCCInstallation) {
       "/usr/include/arm-linux-gnueabi/.keep",
       "/usr/include/arm-linux-gnueabihf/.keep",
       "/lib/arm-linux-gnueabi/.keep",
-      "/lib/arm-linux-gnueabihf/.keep"};
+      "/lib/arm-linux-gnueabihf/.keep",
+
+      "/sysroot/usr/lib/gcc/arm-linux-gnueabi/4.5.1/crtbegin.o",
+      "/sysroot/usr/lib/gcc/arm-linux-gnueabi/4.5.1/crtend.o",
+      "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3/crtbegin.o",
+      "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3/crtend.o",
+      "/sysroot/usr/lib/arm-linux-gnueabi/crt1.o",
+      "/sysroot/usr/lib/arm-linux-gnueabi/crti.o",
+      "/sysroot/usr/lib/arm-linux-gnueabi/crtn.o",
+      "/sysroot/usr/lib/arm-linux-gnueabihf/crt1.o",
+      "/sysroot/usr/lib/arm-linux-gnueabihf/crti.o",
+      "/sysroot/usr/lib/arm-linux-gnueabihf/crtn.o",
+      "/sysroot/usr/include/arm-linux-gnueabi/.keep",
+      "/sysroot/usr/include/arm-linux-gnueabihf/.keep",
+      "/sysroot/lib/arm-linux-gnueabi/.keep",
+      "/sysroot/lib/arm-linux-gnueabihf/.keep",
+  };
 
   for (const char *Path : EmptyFiles)
     InMemoryFileSystem->addFile(Path, 0,
                                 llvm::MemoryBuffer::getMemBuffer("\n"));
 
-  std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
-      {"-fsyntax-only", "--gcc-toolchain=", "--sysroot=", "foo.cpp"}));
-  EXPECT_TRUE(C);
-
-  std::string S;
   {
-    llvm::raw_string_ostream OS(S);
-    C->getDefaultToolChain().printVerboseInfo(OS);
+    DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+    Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags,
+                     "clang LLVM compiler", InMemoryFileSystem);
+    std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
+        {"-fsyntax-only", "--gcc-toolchain=", "--sysroot=", "foo.cpp"}));
+    ASSERT_TRUE(C);
+    std::string S;
+    {
+      llvm::raw_string_ostream OS(S);
+      C->getDefaultToolChain().printVerboseInfo(OS);
+    }
+#if _WIN32
+    std::replace(S.begin(), S.end(), '\\', '/');
+#endif
+    EXPECT_EQ(
+        "Found candidate GCC installation: "
+        "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n"
+        "Selected GCC installation: /usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n"
+        "Candidate multilib: .;@m32\n"
+        "Selected multilib: .;@m32\n",
+        S);
   }
+
+  {
+    DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+    Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags,
+                     "clang LLVM compiler", InMemoryFileSystem);
+    std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
+        {"-fsyntax-only", "--gcc-toolchain=", "--sysroot=/sysroot",
+         "foo.cpp"}));
+    ASSERT_TRUE(C);
+    std::string S;
+    {
+      llvm::raw_string_ostream OS(S);
+      C->getDefaultToolChain().printVerboseInfo(OS);
+    }
 #if _WIN32
-  std::replace(S.begin(), S.end(), '\\', '/');
+    std::replace(S.begin(), S.end(), '\\', '/');
 #endif
-  EXPECT_EQ(
-      "Found candidate GCC installation: "
-      "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n"
-      "Selected GCC installation: /usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n"
-      "Candidate multilib: .;@m32\n"
-      "Selected multilib: .;@m32\n",
-      S);
+    // Test that 4.5.3 from --sysroot is not overridden by 4.6.3 (larger
+    // version) from /usr.
+    EXPECT_EQ("Found candidate GCC installation: "
+              "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3\n"
+              "Selected GCC installation: "
+              "/sysroot/usr/lib/gcc/arm-linux-gnueabihf/4.5.3\n"
+              "Candidate multilib: .;@m32\n"
+              "Selected multilib: .;@m32\n",
+              S);
+  }
 }
 
 TEST(ToolChainTest, VFSGCCInstallationRelativeDir) {


        


More information about the cfe-commits mailing list