tstellar created this revision. 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. Repository: rC Clang https://reviews.llvm.org/D52861 Files: lib/Driver/ToolChains/Gnu.cpp lib/Driver/ToolChains/Gnu.h test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-redhat-linux/7/crtbegin.o test/Driver/Inputs/fedora_28_tree/usr/lib/gcc/x86_64-redhat-linux/7/libgcc_s.so test/Driver/linux-ld.c Index: test/Driver/linux-ld.c =================================================================== --- test/Driver/linux-ld.c +++ test/Driver/linux-ld.c @@ -717,6 +717,18 @@ // CHECK-FEDORA-21-AARCH64: "{{.*}}/usr/lib/gcc/aarch64-redhat-linux/4.9.0{{/|\\\\}}crtend.o" // CHECK-FEDORA-21-AARCH64: "{{.*}}/usr/lib/gcc/aarch64-redhat-linux/4.9.0/../../../../lib64{{/|\\\\}}crtn.o" // +// Check that clang does not select the cross compiler by default on Fedora 28. +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 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 -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=arm-unknown-linux-gnueabi \ // RUN: --gcc-toolchain="" \ Index: lib/Driver/ToolChains/Gnu.h =================================================================== --- lib/Driver/ToolChains/Gnu.h +++ lib/Driver/ToolChains/Gnu.h @@ -186,6 +186,7 @@ /// Driver, and has logic for fuzzing that where appropriate. class GCCInstallationDetector { bool IsValid; + bool HasLibGccShared; llvm::Triple GCCTriple; const Driver &D; @@ -209,7 +210,8 @@ MultilibSet Multilibs; 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); Index: lib/Driver/ToolChains/Gnu.cpp =================================================================== --- lib/Driver/ToolChains/Gnu.cpp +++ lib/Driver/ToolChains/Gnu.cpp @@ -2199,6 +2199,8 @@ (TargetArch == llvm::Triple::x86 && TargetTriple.getOS() != llvm::Triple::Solaris)}}; + bool NeedLibgccShared = !Args.hasArg(options::OPT_static_libgcc) && + !Args.hasArg(options::OPT_static); for (auto &Suffix : Suffixes) { if (!Suffix.Active) continue; @@ -2216,8 +2218,17 @@ 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)) @@ -2231,6 +2242,7 @@ GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str(); GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str(); IsValid = true; + HasLibGccShared = CandidateHasLibGccShared; } } }
Index: test/Driver/linux-ld.c =================================================================== --- test/Driver/linux-ld.c +++ test/Driver/linux-ld.c @@ -717,6 +717,18 @@ // CHECK-FEDORA-21-AARCH64: "{{.*}}/usr/lib/gcc/aarch64-redhat-linux/4.9.0{{/|\\\\}}crtend.o" // CHECK-FEDORA-21-AARCH64: "{{.*}}/usr/lib/gcc/aarch64-redhat-linux/4.9.0/../../../../lib64{{/|\\\\}}crtn.o" // +// Check that clang does not select the cross compiler by default on Fedora 28. +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 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 -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=arm-unknown-linux-gnueabi \ // RUN: --gcc-toolchain="" \ Index: lib/Driver/ToolChains/Gnu.h =================================================================== --- lib/Driver/ToolChains/Gnu.h +++ lib/Driver/ToolChains/Gnu.h @@ -186,6 +186,7 @@ /// Driver, and has logic for fuzzing that where appropriate. class GCCInstallationDetector { bool IsValid; + bool HasLibGccShared; llvm::Triple GCCTriple; const Driver &D; @@ -209,7 +210,8 @@ MultilibSet Multilibs; 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); Index: lib/Driver/ToolChains/Gnu.cpp =================================================================== --- lib/Driver/ToolChains/Gnu.cpp +++ lib/Driver/ToolChains/Gnu.cpp @@ -2199,6 +2199,8 @@ (TargetArch == llvm::Triple::x86 && TargetTriple.getOS() != llvm::Triple::Solaris)}}; + bool NeedLibgccShared = !Args.hasArg(options::OPT_static_libgcc) && + !Args.hasArg(options::OPT_static); for (auto &Suffix : Suffixes) { if (!Suffix.Active) continue; @@ -2216,8 +2218,17 @@ 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)) @@ -2231,6 +2242,7 @@ GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str(); GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str(); IsValid = true; + HasLibGccShared = CandidateHasLibGccShared; } } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits