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="" \ _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits