================ @@ -110,20 +110,81 @@ static std::string computeBaseSysRoot(const Driver &D, bool IncludeTriple) { return std::string(SysRootDir); } +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); +} + +std::string BareMetal::computeSysRoot() const { + if (!SysRoot.empty()) + return SysRoot; + + const Driver &D = getDriver(); + if (!D.SysRoot.empty()) + return D.SysRoot; + + // 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()); + } + + if (llvm::sys::fs::exists(SysRootDir)) + return std::string(SysRootDir); + return computeBaseSysRoot(D, /*IncludeTriple*/ true); +} + +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); +} + 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)); + : Generic_ELF(D, Triple, Args) { + GCCInstallation.init(Triple, Args); + SysRoot = computeSysRoot(); + if (GCCInstallation.isValid()) { + 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 { ---------------- quic-garvgupt wrote:
The crt0.o files are located in the `bin/../<target-triple>/lib/crt0.o` directory, so this path is explicitly added. I've refactored the code to group all file path additions together, followed by program path additions, to make the logic easier to review. Each section is now clearly commented to explain the purpose of the paths 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