Index: clang/lib/Driver/ToolChains/Arch/RISCV.h =================================================================== --- clang/lib/Driver/ToolChains/Arch/RISCV.h +++ clang/lib/Driver/ToolChains/Arch/RISCV.h @@ -26,6 +26,17 @@ const llvm::Triple &Triple); StringRef getRISCVArch(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); +void findRISCVBareMetalMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef Path, const llvm::opt::ArgList &Args, + MultilibSet &Multilibs, + Multilib &SelectedMultilib, + bool ShouldFilterNonExistent); +void findRISCVMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, StringRef Path, + const llvm::opt::ArgList &Args, + MultilibSet &Multilibs, Multilib &SelectedMultilib, + bool ShouldFilterNonExistent); } // end namespace riscv } // namespace tools } // end namespace driver Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -14,6 +14,7 @@ #include "llvm/Option/ArgList.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/TargetParser.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include "ToolChains/CommonArgs.h" @@ -28,6 +29,19 @@ StringRef Major; StringRef Minor; }; + +// Filter to remove Multilibs that don't exist as a suffix to Path +class FilterNonExistent { + StringRef Base, File; + llvm::vfs::FileSystem &VFS; + +public: + FilterNonExistent(StringRef Base, StringRef File, llvm::vfs::FileSystem &VFS) + : Base(Base), File(File), VFS(VFS) {} + bool operator()(const Multilib &M) { + return !VFS.exists(Base + M.gccSuffix() + File); + } +}; } // end anonymous namespace static StringRef getExtensionTypeDesc(StringRef Ext) { @@ -655,3 +669,113 @@ return "rv64imafdc"; } } + +static Multilib makeMultilib(StringRef commonSuffix) { + return Multilib(commonSuffix, commonSuffix, commonSuffix); +} + +void riscv::findRISCVBareMetalMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef Path, + const llvm::opt::ArgList &Args, + MultilibSet &Multilibs, + Multilib &SelectedMultilib, + bool ShouldFilterNonExistent) { + FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); + struct RiscvMultilib { + StringRef march; + StringRef mabi; + }; + // currently only support the set of multilibs like riscv-gnu-toolchain does. + // TODO: support MULTILIB_REUSE + constexpr RiscvMultilib RISCVMultilibSet[] = { + {"rv32i", "ilp32"}, {"rv32im", "ilp32"}, {"rv32iac", "ilp32"}, + {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"}, + {"rv64imafdc", "lp64d"}}; + + std::vector Ms; + for (auto Element : RISCVMultilibSet) { + // multilib path rule is ${march}/${mabi} + Ms.emplace_back( + makeMultilib((Twine(Element.march) + "/" + Twine(Element.mabi)).str()) + .flag(Twine("+march=", Element.march).str()) + .flag(Twine("+mabi=", Element.mabi).str())); + } + MultilibSet RISCVMultilibs = + MultilibSet() + .Either(ArrayRef(Ms)); + + if (ShouldFilterNonExistent) + RISCVMultilibs.FilterOut(NonExistent); + + RISCVMultilibs.setFilePathsCallback([](const Multilib &M) { + return std::vector( + {M.gccSuffix(), + "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(), + "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix(), + // For clang + "/../../../riscv64-unknown-elf/lib" + M.gccSuffix(), + "/../../../riscv32-unknown-elf/lib" + M.gccSuffix()}); + }); + + Multilib::flags_list Flags; + llvm::StringSet<> Added_ABIs; + StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); + StringRef MArch = tools::riscv::getRISCVArch(Args, TargetTriple); + for (auto Element : RISCVMultilibSet) { + addMultilibFlag(MArch == Element.march, + Twine("march=", Element.march).str().c_str(), Flags); + if (!Added_ABIs.count(Element.mabi)) { + Added_ABIs.insert(Element.mabi); + addMultilibFlag(ABIName == Element.mabi, + Twine("mabi=", Element.mabi).str().c_str(), Flags); + } + } + + if (RISCVMultilibs.select(Flags, SelectedMultilib)) + Multilibs = RISCVMultilibs; +} + +void riscv::findRISCVMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, StringRef Path, + const llvm::opt::ArgList &Args, + MultilibSet &Multilibs, + Multilib &SelectedMultilib, + bool ShouldFilterNonExistent) { + if (TargetTriple.getOS() == llvm::Triple::UnknownOS) + return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Multilibs, + SelectedMultilib, + ShouldFilterNonExistent); + + FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); + Multilib Ilp32 = makeMultilib("lib32/ilp32").flag("+m32").flag("+mabi=ilp32"); + Multilib Ilp32f = + makeMultilib("lib32/ilp32f").flag("+m32").flag("+mabi=ilp32f"); + Multilib Ilp32d = + makeMultilib("lib32/ilp32d").flag("+m32").flag("+mabi=ilp32d"); + Multilib Lp64 = makeMultilib("lib64/lp64").flag("+m64").flag("+mabi=lp64"); + Multilib Lp64f = makeMultilib("lib64/lp64f").flag("+m64").flag("+mabi=lp64f"); + Multilib Lp64d = makeMultilib("lib64/lp64d").flag("+m64").flag("+mabi=lp64d"); + MultilibSet RISCVMultilibs = + MultilibSet() + .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d}); + + if (ShouldFilterNonExistent) + RISCVMultilibs.FilterOut(NonExistent); + + Multilib::flags_list Flags; + bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64; + StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); + + addMultilibFlag(!IsRV64, "m32", Flags); + addMultilibFlag(IsRV64, "m64", Flags); + addMultilibFlag(ABIName == "ilp32", "mabi=ilp32", Flags); + addMultilibFlag(ABIName == "ilp32f", "mabi=ilp32f", Flags); + addMultilibFlag(ABIName == "ilp32d", "mabi=ilp32d", Flags); + addMultilibFlag(ABIName == "lp64", "mabi=lp64", Flags); + addMultilibFlag(ABIName == "lp64f", "mabi=lp64f", Flags); + addMultilibFlag(ABIName == "lp64d", "mabi=lp64d", Flags); + + if (RISCVMultilibs.select(Flags, SelectedMultilib)) + Multilibs = RISCVMultilibs; +} Index: clang/lib/Driver/ToolChains/Gnu.cpp =================================================================== --- clang/lib/Driver/ToolChains/Gnu.cpp +++ clang/lib/Driver/ToolChains/Gnu.cpp @@ -1521,97 +1521,6 @@ return false; } -static void findRISCVBareMetalMultilibs(const Driver &D, - const llvm::Triple &TargetTriple, - StringRef Path, const ArgList &Args, - DetectedMultilibs &Result) { - FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); - struct RiscvMultilib { - StringRef march; - StringRef mabi; - }; - // currently only support the set of multilibs like riscv-gnu-toolchain does. - // TODO: support MULTILIB_REUSE - constexpr RiscvMultilib RISCVMultilibSet[] = { - {"rv32i", "ilp32"}, {"rv32im", "ilp32"}, {"rv32iac", "ilp32"}, - {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"}, - {"rv64imafdc", "lp64d"}}; - - std::vector Ms; - for (auto Element : RISCVMultilibSet) { - // multilib path rule is ${march}/${mabi} - Ms.emplace_back( - makeMultilib((Twine(Element.march) + "/" + Twine(Element.mabi)).str()) - .flag(Twine("+march=", Element.march).str()) - .flag(Twine("+mabi=", Element.mabi).str())); - } - MultilibSet RISCVMultilibs = - MultilibSet() - .Either(ArrayRef(Ms)) - .FilterOut(NonExistent) - .setFilePathsCallback([](const Multilib &M) { - return std::vector( - {M.gccSuffix(), - "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(), - "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix()}); - }); - - - Multilib::flags_list Flags; - llvm::StringSet<> Added_ABIs; - StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); - StringRef MArch = tools::riscv::getRISCVArch(Args, TargetTriple); - for (auto Element : RISCVMultilibSet) { - addMultilibFlag(MArch == Element.march, - Twine("march=", Element.march).str().c_str(), Flags); - if (!Added_ABIs.count(Element.mabi)) { - Added_ABIs.insert(Element.mabi); - addMultilibFlag(ABIName == Element.mabi, - Twine("mabi=", Element.mabi).str().c_str(), Flags); - } - } - - if (RISCVMultilibs.select(Flags, Result.SelectedMultilib)) - Result.Multilibs = RISCVMultilibs; -} - -static void findRISCVMultilibs(const Driver &D, - const llvm::Triple &TargetTriple, StringRef Path, - const ArgList &Args, DetectedMultilibs &Result) { - if (TargetTriple.getOS() == llvm::Triple::UnknownOS) - return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result); - - FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); - Multilib Ilp32 = makeMultilib("lib32/ilp32").flag("+m32").flag("+mabi=ilp32"); - Multilib Ilp32f = - makeMultilib("lib32/ilp32f").flag("+m32").flag("+mabi=ilp32f"); - Multilib Ilp32d = - makeMultilib("lib32/ilp32d").flag("+m32").flag("+mabi=ilp32d"); - Multilib Lp64 = makeMultilib("lib64/lp64").flag("+m64").flag("+mabi=lp64"); - Multilib Lp64f = makeMultilib("lib64/lp64f").flag("+m64").flag("+mabi=lp64f"); - Multilib Lp64d = makeMultilib("lib64/lp64d").flag("+m64").flag("+mabi=lp64d"); - MultilibSet RISCVMultilibs = - MultilibSet() - .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d}) - .FilterOut(NonExistent); - - Multilib::flags_list Flags; - bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64; - StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); - - addMultilibFlag(!IsRV64, "m32", Flags); - addMultilibFlag(IsRV64, "m64", Flags); - addMultilibFlag(ABIName == "ilp32", "mabi=ilp32", Flags); - addMultilibFlag(ABIName == "ilp32f", "mabi=ilp32f", Flags); - addMultilibFlag(ABIName == "ilp32d", "mabi=ilp32d", Flags); - addMultilibFlag(ABIName == "lp64", "mabi=lp64", Flags); - addMultilibFlag(ABIName == "lp64f", "mabi=lp64f", Flags); - addMultilibFlag(ABIName == "lp64d", "mabi=lp64d", Flags); - - if (RISCVMultilibs.select(Flags, Result.SelectedMultilib)) - Result.Multilibs = RISCVMultilibs; -} - static bool findBiarchMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, @@ -2389,7 +2298,10 @@ if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected)) return false; } else if (TargetTriple.isRISCV()) { - findRISCVMultilibs(D, TargetTriple, Path, Args, Detected); + tools::riscv::findRISCVMultilibs(D, TargetTriple, Path, Args, + Detected.Multilibs, + Detected.SelectedMultilib, + /*ShouldFilterNonExistent*/true); } else if (isMSP430(TargetArch)) { findMSP430Multilibs(D, TargetTriple, Path, Args, Detected); } else if (TargetArch == llvm::Triple::avr) { Index: clang/lib/Driver/ToolChains/RISCVToolchain.h =================================================================== --- clang/lib/Driver/ToolChains/RISCVToolchain.h +++ clang/lib/Driver/ToolChains/RISCVToolchain.h @@ -35,6 +35,10 @@ addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + std::string getCompilerRT(const llvm::opt::ArgList &Args, + StringRef Component, + FileType Type) const override; + protected: Tool *buildLinker() const override; Index: clang/lib/Driver/ToolChains/RISCVToolchain.cpp =================================================================== --- clang/lib/Driver/ToolChains/RISCVToolchain.cpp +++ clang/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -9,11 +9,13 @@ #include "RISCVToolchain.h" #include "CommonArgs.h" #include "InputInfo.h" +#include "Arch/RISCV.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Options.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" using namespace clang::driver; @@ -52,6 +54,20 @@ .str()); PPaths.push_back((GCCInstallation.getParentLibPath() + "/../bin").str()); } else { + riscv::findRISCVMultilibs(D, Triple, D.Dir, Args, Multilibs, + SelectedMultilib, + /*ShouldFilterNonExistent*/false); + + // Add toolchain/multilib specific file paths. + path_list &FilePaths = getFilePaths(); + addMultilibsFilePaths(D, Multilibs, SelectedMultilib, D.ResourceDir, + FilePaths); + // Also add to the library path. This is necessary as the library paths + // are used when searching for compiler-rt and crtbegin/crtend. + path_list &LibPaths = getLibraryPaths(); + addMultilibsFilePaths(D, Multilibs, SelectedMultilib, D.ResourceDir, + LibPaths); + getProgramPaths().push_back(D.Dir); } getFilePaths().push_back(computeSysRoot() + "/lib"); @@ -112,8 +128,31 @@ } else { // Use the triple as provided to the driver. Unlike the parsed triple // this has not been normalized to always contain every field. - llvm::sys::path::append(SysRootDir, getDriver().Dir, "..", - getDriver().getTargetTriple()); + std::string TargetTriple = getDriver().getTargetTriple(); + + SmallString<32> BiarchVariantTriple; + SmallVector TripleParts; + StringRef(TargetTriple).split(TripleParts, '-', 1); + if (TripleParts[0] == "riscv32") { + BiarchVariantTriple = "riscv64"; + } else { + assert (TripleParts[0] == "riscv64"); + BiarchVariantTriple = "riscv32"; + } + if (TripleParts.size() > 1) { + BiarchVariantTriple += '-'; + BiarchVariantTriple += TripleParts[1]; + } + + // First try the triple, if that doesn't exist then try the + // biarch variant - this matches the behaviour of the GCC install + // detector. + llvm::sys::path::append(SysRootDir, getDriver().Dir, "..", TargetTriple); + if (!llvm::sys::fs::exists(SysRootDir)) { + SysRootDir.clear(); + llvm::sys::path::append(SysRootDir, getDriver().Dir, "..", + BiarchVariantTriple); + } } if (!llvm::sys::fs::exists(SysRootDir)) @@ -122,6 +161,23 @@ return std::string(SysRootDir.str()); } +std::string RISCVToolChain::getCompilerRT(const ArgList &Args, + StringRef Component, + FileType Type) const { + std::string CRTBasename = + getCompilerRTBasename(Args, Component, Type, /*AddArch=*/true); + for (const auto &LibPath : getLibraryPaths()) { + SmallString<128> P(LibPath); + llvm::sys::path::append(P, CRTBasename); + if (getVFS().exists(P)) + return std::string(P.str()); + } + + SmallString<128> Path(getCompilerRTPath()); + llvm::sys::path::append(Path, CRTBasename); + return std::string(Path.str()); +} + void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -150,8 +206,8 @@ const char *crtbegin, *crtend; auto RuntimeLib = ToolChain.GetRuntimeLibType(Args); if (RuntimeLib == ToolChain::RLT_Libgcc) { - crtbegin = "crtbegin.o"; - crtend = "crtend.o"; + crtbegin = Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o")); + crtend = Args.MakeArgString(ToolChain.GetFilePath("crtend.o")); } else { assert (RuntimeLib == ToolChain::RLT_CompilerRT); crtbegin = ToolChain.getCompilerRTArgString(Args, "crtbegin", @@ -162,7 +218,7 @@ if (WantCRTs) { CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); - CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); + CmdArgs.push_back(crtbegin); } Args.AddAllArgs(CmdArgs, options::OPT_L); @@ -187,7 +243,7 @@ } if (WantCRTs) - CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); + CmdArgs.push_back(crtend); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); Index: clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv32-unknown-elf-ld =================================================================== --- /dev/null +++ clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv32-unknown-elf-ld @@ -0,0 +1 @@ +#!/bin/true Index: clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv64-unknown-elf-ld =================================================================== --- /dev/null +++ clang/test/Driver/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv64-unknown-elf-ld @@ -0,0 +1 @@ +#!/bin/true Index: clang/test/Driver/riscv32-toolchain-extra.c =================================================================== --- clang/test/Driver/riscv32-toolchain-extra.c +++ clang/test/Driver/riscv32-toolchain-extra.c @@ -30,3 +30,101 @@ // C-RV32-BAREMETAL-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" // C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}Output/testroot-riscv32-baremetal-nogcc/{{.*}}/lib/libclang_rt.builtins-riscv32.a" // C-RV32-BAREMETAL-ILP32-NOGCC: "{{.*}}Output/testroot-riscv32-baremetal-nogcc/{{.*}}/lib/clang_rt.crtend-riscv32.o" + +// Setup the directory tree for baremetal multilib with no detected GCC install +// RUN: rm -rf %T/testroot-multilib-riscv32-elf-nogcc +// RUN: mkdir -p %T/testroot-multilib-riscv32-elf-nogcc/bin +// RUN: ln -s %clang %T/testroot-multilib-riscv32-elf-nogcc/bin/clang +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv32-unknown-elf-ld %T/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf %T/testroot-multilib-riscv32-elf-nogcc/riscv64-unknown-elf +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/lib %T/testroot-multilib-riscv32-elf-nogcc/lib + +// RUN: %T/testroot-multilib-riscv32-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv32-unknown-elf --rtlib=platform \ +// RUN: -march=rv32i -mabi=ilp32 \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv32-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC %s + +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "-m" "elf32lriscv" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32i/ilp32{{/|\\\\}}crt0.o" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32i/ilp32{{/|\\\\}}clang_rt.crtbegin-riscv32.o" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32i/ilp32" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32i/ilp32" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32i/ilp32{{/|\\\\}}libclang_rt.builtins-riscv32.a" +// C-RV32I-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32i/ilp32{{/|\\\\}}clang_rt.crtend-riscv32.o" + +// RUN: %T/testroot-multilib-riscv32-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv32-unknown-elf --rtlib=platform \ +// RUN: -march=rv32iac -mabi=ilp32 \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv32-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC %s + +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "-m" "elf32lriscv" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32iac/ilp32{{/|\\\\}}crt0.o" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32iac/ilp32{{/|\\\\}}clang_rt.crtbegin-riscv32.o" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32iac/ilp32" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32iac/ilp32" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32iac/ilp32{{/|\\\\}}libclang_rt.builtins-riscv32.a" +// C-RV32IAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32iac/ilp32{{/|\\\\}}clang_rt.crtend-riscv32.o" + +// RUN: %T/testroot-multilib-riscv32-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv32-unknown-elf --rtlib=platform \ +// RUN: -march=rv32im -mabi=ilp32 \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv32-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC %s + +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "-m" "elf32lriscv" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32im/ilp32{{/|\\\\}}crt0.o" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32im/ilp32{{/|\\\\}}clang_rt.crtbegin-riscv32.o" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32im/ilp32" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32im/ilp32" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32im/ilp32{{/|\\\\}}libclang_rt.builtins-riscv32.a" +// C-RV32IM-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32im/ilp32{{/|\\\\}}clang_rt.crtend-riscv32.o" + +// RUN: %T/testroot-multilib-riscv32-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv32-unknown-elf --rtlib=platform \ +// RUN: -march=rv32imac -mabi=ilp32 \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv32-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC %s + +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "-m" "elf32lriscv" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32imac/ilp32{{/|\\\\}}crt0.o" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imac/ilp32{{/|\\\\}}clang_rt.crtbegin-riscv32.o" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imac/ilp32" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32imac/ilp32" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imac/ilp32{{/|\\\\}}libclang_rt.builtins-riscv32.a" +// C-RV32IMAC-BAREMETAL-MULTI-ILP32-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imac/ilp32{{/|\\\\}}clang_rt.crtend-riscv32.o" + +// RUN: %T/testroot-multilib-riscv32-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv32-unknown-elf --rtlib=platform \ +// RUN: -march=rv32imafc -mabi=ilp32f \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv32-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC %s + +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/riscv32-unknown-elf-ld" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "-m" "elf32lriscv" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32imafc/ilp32f{{/|\\\\}}crt0.o" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imafc/ilp32f{{/|\\\\}}clang_rt.crtbegin-riscv32.o" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imafc/ilp32f" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv32imafc/ilp32f" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imafc/ilp32f{{/|\\\\}}libclang_rt.builtins-riscv32.a" +// C-RV32IMAFC-BAREMETAL-MULTI-ILP32F-NOGCC: "{{.*}}/Output/testroot-multilib-riscv32-elf-nogcc/lib/clang/11.0.0/rv32imafc/ilp32f{{/|\\\\}}clang_rt.crtend-riscv32.o" Index: clang/test/Driver/riscv64-toolchain-extra.c =================================================================== --- clang/test/Driver/riscv64-toolchain-extra.c +++ clang/test/Driver/riscv64-toolchain-extra.c @@ -30,3 +30,47 @@ // C-RV64-BAREMETAL-LP64-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" // C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}Output/testroot-riscv64-baremetal-nogcc/{{.*}}/lib/libclang_rt.builtins-riscv64.a" // C-RV64-BAREMETAL-LP64-NOGCC: "{{.*}}Output/testroot-riscv64-baremetal-nogcc/{{.*}}/lib/clang_rt.crtend-riscv64.o" + +// Setup the directory tree for baremetal multilib with no detected GCC install +// RUN: rm -rf %T/testroot-multilib-riscv64-elf-nogcc +// RUN: mkdir -p %T/testroot-multilib-riscv64-elf-nogcc/bin +// RUN: ln -s %clang %T/testroot-multilib-riscv64-elf-nogcc/bin/clang +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/bin/riscv64-unknown-elf-ld %T/testroot-multilib-riscv64-elf-nogcc/bin/riscv64-unknown-elf-ld +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/riscv64-unknown-elf %T/testroot-multilib-riscv64-elf-nogcc/riscv64-unknown-elf +// RUN: ln -s %S/Inputs/multilib_riscv_elf_nogcc_tree/lib %T/testroot-multilib-riscv64-elf-nogcc/lib + +// RUN: %T/testroot-multilib-riscv64-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv64-unknown-elf --rtlib=platform \ +// RUN: -march=rv64imac -mabi=lp64 \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv64-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC %s + +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv64-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/bin/riscv64-unknown-elf-ld" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "-m" "elf64lriscv" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv64imac/lp64{{/|\\\\}}crt0.o" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imac/lp64{{/|\\\\}}clang_rt.crtbegin-riscv64.o" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imac/lp64" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv64imac/lp64" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imac/lp64{{/|\\\\}}libclang_rt.builtins-riscv64.a" +// C-RV64IMAC-BAREMETAL-MULTI-LP64-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imac/lp64{{/|\\\\}}clang_rt.crtend-riscv64.o" + +// RUN: %T/testroot-multilib-riscv64-elf-nogcc/bin/clang %s -### -no-canonical-prefixes \ +// RUN: -target riscv64-unknown-elf --rtlib=platform \ +// RUN: -march=rv64imafdc -mabi=lp64d \ +// RUN: --gcc-toolchain=%T/testroot-multilib-riscv64-elf-nogcc/invalid 2>&1 \ +// RUN: | FileCheck -check-prefix=C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC %s + +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "-internal-isystem" "{{.*}}Output/testroot-multilib-riscv64-elf-nogcc/bin/../riscv64-unknown-elf/include" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/bin/riscv64-unknown-elf-ld" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "-m" "elf64lriscv" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv64imafdc/lp64d{{/|\\\\}}crt0.o" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imafdc/lp64d{{/|\\\\}}clang_rt.crtbegin-riscv64.o" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imafdc/lp64d" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-elf/lib/rv64imafdc/lp64d" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "-L{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/bin/../riscv64-unknown-elf/lib" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "--start-group" "-lc" "-lgloss" "--end-group" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imafdc/lp64d{{/|\\\\}}libclang_rt.builtins-riscv64.a" +// C-RV64IMAFDC-BAREMETAL-MULTI-LP64D-NOGCC: "{{.*}}/Output/testroot-multilib-riscv64-elf-nogcc/lib/clang/11.0.0/rv64imafdc/lp64d{{/|\\\\}}clang_rt.crtend-riscv64.o"