================ @@ -110,56 +144,99 @@ static std::string computeBaseSysRoot(const Driver &D, bool IncludeTriple) { return std::string(SysRootDir); } -BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args) - : ToolChain(D, Triple, Args), - SysRoot(computeBaseSysRoot(D, /*IncludeTriple=*/true)) { - getProgramPaths().push_back(getDriver().Dir); - - findMultilibs(D, Triple, Args); - SmallString<128> SysRoot(computeSysRoot()); - if (!SysRoot.empty()) { - for (const Multilib &M : getOrderedMultilibs()) { - SmallString<128> Dir(SysRoot); - llvm::sys::path::append(Dir, M.osSuffix(), "lib"); - getFilePaths().push_back(std::string(Dir)); - getLibraryPaths().push_back(std::string(Dir)); - } - } +static bool hasGCCToolChainAlongSideClang(const Driver &D) { + SmallString<128> GCCDir; + llvm::sys::path::append(GCCDir, D.Dir, "..", D.getTargetTriple(), + "lib/crt0.o"); + return llvm::sys::fs::exists(GCCDir); } -/// Is the triple {aarch64.aarch64_be}-none-elf? -static bool isAArch64BareMetal(const llvm::Triple &Triple) { - if (Triple.getArch() != llvm::Triple::aarch64 && - Triple.getArch() != llvm::Triple::aarch64_be) - return false; +// Users can specify their GCC toolchain using `-gcc-install-dir` or +// `--gcc-toolchain`. If no sysroot is explicitly provided, the driver will +// attempt to infer it from the values of the above flags. +// +// If neither flag is used, the sysroot defaults to either: +// - `bin/../<target-triple>` +// - `bin/../lib/clang-runtimes/<target-triple>` +// +// To use the `clang-runtimes` path, ensure that `../<target-triple>/lib/crt0.o` +// does not exist relative to the driver. +std::string BareMetal::computeSysRoot() const { + if (!SysRoot.empty()) + return SysRoot; - if (Triple.getVendor() != llvm::Triple::UnknownVendor) - return false; + const Driver &D = getDriver(); + if (!D.SysRoot.empty()) + return D.SysRoot; - if (Triple.getOS() != llvm::Triple::UnknownOS) - return false; + // Verify the GCC installation from -gcc-install-dir, --gcc-toolchain, or + // alongside clang. If valid, form the sysroot. Otherwise, check + // lib/clang-runtimes above the driver. + SmallString<128> SysRootDir; + if (GCCInstallation.isValid()) { + StringRef LibDir = GCCInstallation.getParentLibPath(); + StringRef TripleStr = GCCInstallation.getTriple().str(); + llvm::sys::path::append(SysRootDir, LibDir, "..", TripleStr); + } else if (hasGCCToolChainAlongSideClang(D)) { + // 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, D.Dir, "..", D.getTargetTriple()); + } - return Triple.getEnvironmentName() == "elf"; + if (llvm::sys::fs::exists(SysRootDir)) + return std::string(SysRootDir); + return computeBaseSysRoot(D, /*IncludeTriple*/ true); } -static bool isRISCVBareMetal(const llvm::Triple &Triple) { - if (!Triple.isRISCV()) - return false; - - if (Triple.getVendor() != llvm::Triple::UnknownVendor) - return false; - - if (Triple.getOS() != llvm::Triple::UnknownOS) - return false; - - return Triple.getEnvironmentName() == "elf"; +static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs, + const Multilib &Multilib, + StringRef InstallPath, + ToolChain::path_list &Paths) { + if (const auto &PathsCallback = Multilibs.filePathsCallback()) + for (const auto &Path : PathsCallback(Multilib)) + addPathIfExists(D, InstallPath + Path, Paths); } -/// Is the triple powerpc[64][le]-*-none-eabi? -static bool isPPCBareMetal(const llvm::Triple &Triple) { - return Triple.isPPC() && Triple.getOS() == llvm::Triple::UnknownOS && - Triple.getEnvironment() == llvm::Triple::EABI; +// GCC mutltilibs will only work for those targets that have their multlib +// structure encoded into GCCInstallation. Baremetal toolchain support ARM, +// AArch64, RISCV and PPC and of them only RISCV have GCC multilibs hardcoded +// in GCCInstallation. +BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { + GCCInstallation.init(Triple, Args); + SysRoot = computeSysRoot(); + if (GCCInstallation.isValid()) { + if (!isRISCVBareMetal(Triple)) + D.Diag(clang::diag::warn_drv_multilib_not_available_for_target); + Multilibs = GCCInstallation.getMultilibs(); + SelectedMultilibs.assign({GCCInstallation.getMultilib()}); + path_list &Paths = getFilePaths(); + // Add toolchain/multilib specific file paths. + addMultilibsFilePaths(D, Multilibs, SelectedMultilibs.back(), + GCCInstallation.getInstallPath(), Paths); + getFilePaths().push_back(GCCInstallation.getInstallPath().str()); + ToolChain::path_list &PPaths = getProgramPaths(); + // Multilib cross-compiler GCC installations put ld in a triple-prefixed + // directory off of the parent of the GCC installation. + PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + + GCCInstallation.getTriple().str() + "/bin") + .str()); + PPaths.push_back((GCCInstallation.getParentLibPath() + "/../bin").str()); + getFilePaths().push_back(SysRoot + "/lib"); + } else { + getProgramPaths().push_back(getDriver().Dir); + findMultilibs(D, Triple, Args); + const SmallString<128> SysRootDir(computeSysRoot()); ---------------- smithp35 wrote:
Assuming it is still the ToolChain::SysRoot that is set on line 208 can you still use it rather than recompute. All computeSysRoot will do is return ToolChain::SysRoot as it has been set either on line 208 or by findMultilibs? https://github.com/llvm/llvm-project/pull/121829 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits