tstellar / rpms / clang

Forked from rpms/clang 6 years ago
Clone
70febad
From 67013ee5feecca0c1e1dd8a149b20779a9b6c12a Mon Sep 17 00:00:00 2001
70febad
From: serge-sans-paille <sguelton@redhat.com>
70febad
Date: Wed, 23 Sep 2020 12:47:30 +0000
70febad
Subject: [PATCH] Driver: Prefer gcc toolchains with libgcc_s.so when not
70febad
 static linking libgcc
70febad
70febad
Fedora ships cross-compilers on all platforms, so a user could end up
70febad
with a gcc x86_64 cross-compiler installed on an x86_64 system. clang
70febad
maintains a list of supported triples for each target and when all
70febad
else is equal will prefer toolchains with triples that appear earlier
70febad
in the list.
70febad
70febad
The cross-compiler triple on Fedora is x86_64-linux-gnu and this comes
70febad
before the Fedora system compiler's triple: x86_64-redhat-linux in
70febad
the triples list, so the cross compiler is always preferred. This
70febad
is a problem, because the cross compiler is missing libraries, like
70febad
libgcc_s.so, that clang expects to be there so linker invocations
70febad
will fail.
70febad
70febad
This patch fixes this by checking for the existence of libgcc_s.so
70febad
when it is required and taking that into account when selecting a
70febad
toolchain.
70febad
---
70febad
 lib/Driver/ToolChains/Gnu.cpp                    | 16 ++++++++++++++--
70febad
 lib/Driver/ToolChains/Gnu.h                      |  4 +++-
70febad
 .../usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o    |  0
70febad
 .../usr/lib/gcc/x86_64-redhat-linux/7/crtbegin.o |  0
70febad
 .../lib/gcc/x86_64-redhat-linux/7/libgcc_s.so    |  0
70febad
 test/Driver/linux-ld.c                           | 12 ++++++++++++
70febad
 6 files changed, 29 insertions(+), 3 deletions(-)
70febad
 create mode 100644 test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o
70febad
 create mode 100644 test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-redhat-linux/7/crtbegin.o
70febad
 create mode 100644 test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-redhat-linux/7/libgcc_s.so
70febad
158c172
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
70febad
index c8a7fce0..f28792b7 100644
158c172
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
158c172
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
70febad
@@ -2500,6 +2500,8 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
70febad
        (TargetArch == llvm::Triple::x86 &&
70febad
         TargetTriple.getOS() != llvm::Triple::Solaris)}};
70febad
 
70febad
+  bool NeedLibgccShared = !Args.hasArg(options::OPT_static_libgcc) &&
70febad
+                          !Args.hasArg(options::OPT_static);
70febad
   for (auto &Suffix : Suffixes) {
70febad
     if (!Suffix.Active)
70febad
       continue;
70febad
@@ -2517,8 +2519,17 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
70febad
           continue; // Saw this path before; no need to look at it again.
70febad
       if (CandidateVersion.isOlderThan(4, 1, 1))
70febad
         continue;
70febad
-      if (CandidateVersion <= Version)
70febad
-        continue;
70febad
+
70febad
+      bool CandidateHasLibGccShared = false;
70febad
+      if (CandidateVersion <= Version) {
70febad
+        if (NeedLibgccShared && !HasLibGccShared) {
70febad
+          CandidateHasLibGccShared =
70febad
+                D.getVFS().exists(LI->path() + "/libgcc_s.so");
70febad
+
70febad
+        }
70febad
+        if (HasLibGccShared || !CandidateHasLibGccShared)
70febad
+          continue;
70febad
+      }
70febad
 
70febad
       if (!ScanGCCForMultilibs(TargetTriple, Args, LI->path(),
70febad
                                NeedsBiarchSuffix))
70febad
@@ -2532,6 +2543,7 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
70febad
       GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str();
70febad
       GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str();
70febad
       IsValid = true;
70febad
+      HasLibGccShared = CandidateHasLibGccShared;
70febad
     }
70febad
   }
70febad
 }
158c172
diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h
70febad
index 52690ab4..2a4452d9 100644
158c172
--- a/clang/lib/Driver/ToolChains/Gnu.h
158c172
+++ b/clang/lib/Driver/ToolChains/Gnu.h
70febad
@@ -190,6 +190,7 @@ public:
70febad
   /// Driver, and has logic for fuzzing that where appropriate.
70febad
   class GCCInstallationDetector {
70febad
     bool IsValid;
70febad
+    bool HasLibGccShared;
70febad
     llvm::Triple GCCTriple;
70febad
     const Driver &D;
70febad
 
70febad
@@ -213,7 +214,8 @@ public:
70febad
     MultilibSet Multilibs;
70febad
 
70febad
   public:
70febad
-    explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}
70febad
+    explicit GCCInstallationDetector(const Driver &D)
70febad
+        : IsValid(false), HasLibGccShared(false), D(D) {}
70febad
     void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args,
70febad
               ArrayRef<std::string> ExtraTripleAliases = None);
70febad
 
158c172
diff --git a/clang/test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o b/clang/test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o
70febad
new file mode 100644
70febad
index 00000000..e69de29b
158c172
diff --git a/clang/test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-redhat-linux/7/crtbegin.o b/clang/test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-redhat-linux/7/crtbegin.o
70febad
new file mode 100644
70febad
index 00000000..e69de29b
158c172
diff --git a/clang/test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-redhat-linux/7/libgcc_s.so b/clang/test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-redhat-linux/7/libgcc_s.so
70febad
new file mode 100644
70febad
index 00000000..e69de29b
158c172
diff --git a/clang/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
70febad
index ec539522..95725d5c 100644
158c172
--- a/clang/test/Driver/linux-ld.c
158c172
+++ b/clang/test/Driver/linux-ld.c
70febad
@@ -784,6 +784,18 @@
70febad
 // CHECK-FEDORA-31-RISCV64: "{{.*}}/usr/lib/gcc/riscv64-redhat-linux/9{{/|\\\\}}crtend.o"
70febad
 // CHECK-FEDORA-31-RISCV64: "{{.*}}/usr/lib/gcc/riscv64-redhat-linux/9{{/|\\\\}}crtn.o"
70febad
 //
70febad
+// Check that clang does not select the cross compiler by default on Fedora 28.
70febad
+//
70febad
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
70febad
+// RUN:     --target=x86_64-unknown-linux-gnu \
70febad
+// RUN:     --gcc-toolchain="" \
70febad
+// RUN:     --sysroot=%S/Inputs/fedora_28_tree \
70febad
+// RUN:   | FileCheck --check-prefix=CHECK-FEDORA-28-X86_64 %s
70febad
+//
70febad
+// CHECK-FEDORA-28-X86_64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
70febad
+// CHECK-FEDORA-28-X86_64: "[[SYSROOT]]/usr/lib/gcc/x86_64-redhat-linux/7/crtbegin.o"
70febad
+// CHECK-FEDORA-28-X86_64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-redhat-linux/7"
70febad
+//
70febad
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
70febad
 // RUN:     --target=arm-unknown-linux-gnueabi -rtlib=platform \
70febad
 // RUN:     --gcc-toolchain="" \
70febad
-- 
70febad
2.25.2
70febad