tstellar created this revision. tstellar added reviewers: serge-sans-paille, MaskRay, mgorny. Herald added a subscriber: pengfei. tstellar requested review of this revision. Herald added a project: clang.
The GCCInstallationDetector has a list of gcc triples to search for when trying to find a valid gcc install on the system. When all else is equal, clang selects the first triple that appears in the list. This causes a problem on Red Hat operating systems, since there is a cross-compiler gcc package that uses the triple x86_64-linux-gnu and since this is listed in the triple list before the system gcc install (x86_64-redhat-linux), the cross-compiler is always selected by clang. To solve this, we make it possible for a distro to provide a list of preferred triples that will be selected before any triples in the generic triple list. Another solution to this problem would be to reorder the generic triple lists so that distro supplied triples come first. However, I don't have confidence that I would be able to order the list so that it is correct for every distro. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D109694 Files: clang/include/clang/Driver/Distro.h clang/lib/Driver/Distro.cpp clang/lib/Driver/ToolChains/Linux.cpp Index: clang/lib/Driver/ToolChains/Linux.cpp =================================================================== --- clang/lib/Driver/ToolChains/Linux.cpp +++ clang/lib/Driver/ToolChains/Linux.cpp @@ -177,7 +177,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { - GCCInstallation.init(Triple, Args); + + Distro Distro(D.getVFS(), Triple); + GCCInstallation.init(Triple, Args, Distro.getDefaultGCCTriples(Triple.getArch())); Multilibs = GCCInstallation.getMultilibs(); SelectedMultilib = GCCInstallation.getMultilib(); llvm::Triple::ArchType Arch = Triple.getArch(); @@ -186,7 +188,6 @@ Generic_GCC::PushPPaths(PPaths); - Distro Distro(D.getVFS(), Triple); if (Distro.IsAlpineLinux() || Triple.isAndroid()) { ExtraOpts.push_back("-z"); Index: clang/lib/Driver/Distro.cpp =================================================================== --- clang/lib/Driver/Distro.cpp +++ clang/lib/Driver/Distro.cpp @@ -225,3 +225,53 @@ Distro::Distro(llvm::vfs::FileSystem &VFS, const llvm::Triple &TargetOrHost) : DistroVal(GetDistro(VFS, TargetOrHost)) {} + +/// @return An array of triples that should be used first when searching for +/// a candidate gcc install on the system. +llvm::ArrayRef<std::string> Distro::getDefaultGCCTriples(llvm::Triple::ArchType Arch) { + if (!IsRedhat()) + return None; + + static const std::array<std::string, 1> RedHatAArch64Triples = {{ + "aarch64-redhat-linux" + }}; + + static const std::array<std::string, 1> RedHatArmTriples = {{ + "armv7hl-redhat-linux-gnueabi" + }}; + + static const std::array<std::string, 1> RedHatPPC64LETriples = {{ + "ppc64le-redhat-linux" + }}; + + static const std::array<std::string, 1> RedHatSystemZTriples = {{ + "s390x-redhat-linux" + }}; + + static const std::array<std::string, 1> RedHatX86Triples = {{ + "i686-redhat-linux" + }}; + + static const std::array<std::string, 1> RedHatX86_64Triples = {{ + "x86_64-redhat-linux" + }}; + + switch (Arch) { + default: + break; + case llvm::Triple::aarch64: + return RedHatAArch64Triples; + case llvm::Triple::arm: + return RedHatArmTriples; + case llvm::Triple::ppc64le: + return RedHatPPC64LETriples; + case llvm::Triple::systemz: + return RedHatSystemZTriples; + case llvm::Triple::x86: + return RedHatX86Triples; + case llvm::Triple::x86_64: + return RedHatX86_64Triples; + } + + return None; +} Index: clang/include/clang/Driver/Distro.h =================================================================== --- clang/include/clang/Driver/Distro.h +++ clang/include/clang/Driver/Distro.h @@ -91,6 +91,8 @@ /// Detects the distribution using specified VFS. explicit Distro(llvm::vfs::FileSystem &VFS, const llvm::Triple &TargetOrHost); + llvm::ArrayRef<std::string> getDefaultGCCTriples(llvm::Triple::ArchType Arch); + bool operator==(const Distro &Other) const { return DistroVal == Other.DistroVal; }
Index: clang/lib/Driver/ToolChains/Linux.cpp =================================================================== --- clang/lib/Driver/ToolChains/Linux.cpp +++ clang/lib/Driver/ToolChains/Linux.cpp @@ -177,7 +177,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { - GCCInstallation.init(Triple, Args); + + Distro Distro(D.getVFS(), Triple); + GCCInstallation.init(Triple, Args, Distro.getDefaultGCCTriples(Triple.getArch())); Multilibs = GCCInstallation.getMultilibs(); SelectedMultilib = GCCInstallation.getMultilib(); llvm::Triple::ArchType Arch = Triple.getArch(); @@ -186,7 +188,6 @@ Generic_GCC::PushPPaths(PPaths); - Distro Distro(D.getVFS(), Triple); if (Distro.IsAlpineLinux() || Triple.isAndroid()) { ExtraOpts.push_back("-z"); Index: clang/lib/Driver/Distro.cpp =================================================================== --- clang/lib/Driver/Distro.cpp +++ clang/lib/Driver/Distro.cpp @@ -225,3 +225,53 @@ Distro::Distro(llvm::vfs::FileSystem &VFS, const llvm::Triple &TargetOrHost) : DistroVal(GetDistro(VFS, TargetOrHost)) {} + +/// @return An array of triples that should be used first when searching for +/// a candidate gcc install on the system. +llvm::ArrayRef<std::string> Distro::getDefaultGCCTriples(llvm::Triple::ArchType Arch) { + if (!IsRedhat()) + return None; + + static const std::array<std::string, 1> RedHatAArch64Triples = {{ + "aarch64-redhat-linux" + }}; + + static const std::array<std::string, 1> RedHatArmTriples = {{ + "armv7hl-redhat-linux-gnueabi" + }}; + + static const std::array<std::string, 1> RedHatPPC64LETriples = {{ + "ppc64le-redhat-linux" + }}; + + static const std::array<std::string, 1> RedHatSystemZTriples = {{ + "s390x-redhat-linux" + }}; + + static const std::array<std::string, 1> RedHatX86Triples = {{ + "i686-redhat-linux" + }}; + + static const std::array<std::string, 1> RedHatX86_64Triples = {{ + "x86_64-redhat-linux" + }}; + + switch (Arch) { + default: + break; + case llvm::Triple::aarch64: + return RedHatAArch64Triples; + case llvm::Triple::arm: + return RedHatArmTriples; + case llvm::Triple::ppc64le: + return RedHatPPC64LETriples; + case llvm::Triple::systemz: + return RedHatSystemZTriples; + case llvm::Triple::x86: + return RedHatX86Triples; + case llvm::Triple::x86_64: + return RedHatX86_64Triples; + } + + return None; +} Index: clang/include/clang/Driver/Distro.h =================================================================== --- clang/include/clang/Driver/Distro.h +++ clang/include/clang/Driver/Distro.h @@ -91,6 +91,8 @@ /// Detects the distribution using specified VFS. explicit Distro(llvm::vfs::FileSystem &VFS, const llvm::Triple &TargetOrHost); + llvm::ArrayRef<std::string> getDefaultGCCTriples(llvm::Triple::ArchType Arch); + bool operator==(const Distro &Other) const { return DistroVal == Other.DistroVal; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits