[llvm-branch-commits] [clang] bcc526e - [PATCH] Prefer gcc toolchains with libgcc_s.so when not static linking libgcc
Nikita Popov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue May 3 01:15:51 PDT 2022
Author: serge-sans-paille
Date: 2022-05-03T10:10:07+02:00
New Revision: bcc526e516e00f5cd4427f5977f0baa2e2d393f4
URL: https://github.com/llvm/llvm-project/commit/bcc526e516e00f5cd4427f5977f0baa2e2d393f4
DIFF: https://github.com/llvm/llvm-project/commit/bcc526e516e00f5cd4427f5977f0baa2e2d393f4.diff
LOG: [PATCH] Prefer gcc toolchains with libgcc_s.so when not static linking libgcc
Fedora ships cross-compilers on all platforms, so a user could end up
with a gcc x86_64 cross-compiler installed on an x86_64 system. clang
maintains a list of supported triples for each target and when all
else is equal will prefer toolchains with triples that appear earlier
in the list.
The cross-compiler triple on Fedora is x86_64-linux-gnu and this comes
before the Fedora system compiler's triple: x86_64-redhat-linux in
the triples list, so the cross compiler is always preferred. This
is a problem, because the cross compiler is missing libraries, like
libgcc_s.so, that clang expects to be there so linker invocations
will fail.
This patch fixes this by checking for the existence of libgcc_s.so
when it is required and taking that into account when selecting a
toolchain.
Added:
clang/test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o
clang/test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-redhat-linux/7/crtbegin.o
clang/test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-redhat-linux/7/libgcc_s.so
Modified:
clang/lib/Driver/ToolChains/Gnu.cpp
clang/lib/Driver/ToolChains/Gnu.h
clang/test/Driver/linux-ld.c
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 0a0d4676ff6f2..e888ff843b8e8 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -2643,6 +2643,8 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
TargetTriple.getVendor() == llvm::Triple::Freescale ||
TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}};
+ bool NeedLibgccShared = !Args.hasArg(options::OPT_static_libgcc) &&
+ !Args.hasArg(options::OPT_static);
for (auto &Suffix : Suffixes) {
if (!Suffix.Active)
continue;
@@ -2660,8 +2662,17 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
continue; // Saw this path before; no need to look at it again.
if (CandidateVersion.isOlderThan(4, 1, 1))
continue;
- if (CandidateVersion <= Version)
- continue;
+
+ bool CandidateHasLibGccShared = false;
+ if (CandidateVersion <= Version) {
+ if (NeedLibgccShared && !HasLibGccShared) {
+ CandidateHasLibGccShared =
+ D.getVFS().exists(LI->path() + "/libgcc_s.so");
+
+ }
+ if (HasLibGccShared || !CandidateHasLibGccShared)
+ continue;
+ }
if (!ScanGCCForMultilibs(TargetTriple, Args, LI->path(),
NeedsBiarchSuffix))
@@ -2675,6 +2686,7 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str();
GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str();
IsValid = true;
+ HasLibGccShared = CandidateHasLibGccShared;
}
}
}
diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h
index 4eb7ab0215ab8..d692fb031eb8f 100644
--- a/clang/lib/Driver/ToolChains/Gnu.h
+++ b/clang/lib/Driver/ToolChains/Gnu.h
@@ -190,6 +190,7 @@ class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {
/// Driver, and has logic for fuzzing that where appropriate.
class GCCInstallationDetector {
bool IsValid;
+ bool HasLibGccShared;
llvm::Triple GCCTriple;
const Driver &D;
@@ -216,7 +217,8 @@ class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {
const std::string GentooConfigDir = "/etc/env.d/gcc";
public:
- explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}
+ explicit GCCInstallationDetector(const Driver &D)
+ : IsValid(false), HasLibGccShared(false), D(D) {}
void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args,
ArrayRef<std::string> ExtraTripleAliases = None);
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
new file mode 100644
index 0000000000000..e69de29bb2d1d
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
new file mode 100644
index 0000000000000..e69de29bb2d1d
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
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c
index d7c58431fa76f..cc44452decddd 100644
--- a/clang/test/Driver/linux-ld.c
+++ b/clang/test/Driver/linux-ld.c
@@ -685,6 +685,18 @@
// CHECK-FEDORA-31-RISCV64: "{{.*}}/usr/lib/gcc/riscv64-redhat-linux/9{{/|\\\\}}crtend.o"
// CHECK-FEDORA-31-RISCV64: "{{.*}}/usr/lib/gcc/riscv64-redhat-linux/9{{/|\\\\}}crtn.o"
//
+// Check that clang does not select the cross compiler by default on Fedora 28.
+//
+// RUN: %clang -### %s -no-pie 2>&1 \
+// RUN: --target=x86_64-unknown-linux-gnu \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/fedora_28_tree \
+// RUN: | FileCheck --check-prefix=CHECK-FEDORA-28-X86_64 %s
+//
+// CHECK-FEDORA-28-X86_64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-FEDORA-28-X86_64: "[[SYSROOT]]/usr/lib/gcc/x86_64-redhat-linux/7/crtbegin.o"
+// CHECK-FEDORA-28-X86_64: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-redhat-linux/7"
+//
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: --target=arm-unknown-linux-gnueabi -rtlib=platform \
// RUN: --gcc-toolchain="" \
More information about the llvm-branch-commits
mailing list