https://github.com/vgvassilev created https://github.com/llvm/llvm-project/pull/175416
This should resolve a recent solaris failure reported in #175322. >From 7403b2a7dbaf965fe3fa5ce1972b0e4ceb792c4f Mon Sep 17 00:00:00 2001 From: Vassil Vassilev <[email protected]> Date: Sun, 11 Jan 2026 07:18:57 +0000 Subject: [PATCH] [clang-repl] Teach the default orc runtime finder to search in more locations. This should resolve a recent solaris failure. --- clang/lib/Interpreter/Interpreter.cpp | 117 +++++++++++++++++++------- 1 file changed, 88 insertions(+), 29 deletions(-) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 0d9f66c4ff07b..763d298b052f2 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -270,53 +270,112 @@ IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC, return std::move(Executor); } -llvm::Error -IncrementalExecutorBuilder::UpdateOrcRuntimePath(const driver::Compilation &C) { +llvm::Error IncrementalExecutorBuilder::UpdateOrcRuntimePath( + const clang::driver::Compilation &C) { if (!IsOutOfProcess) return llvm::Error::success(); - const std::array<const char *, 3> OrcRTLibNames = { - "liborc_rt.a", "liborc_rt_osx.a", "liborc_rt-x86_64.a"}; + // Candidate runtime filenames to look for (tweak as appropriate). + static constexpr std::array<const char *, 3> OrcRTLibNames = { + "liborc_rt.a", + "liborc_rt_osx.a", + "liborc_rt-x86_64.a", + }; + // Return the first file found inside 'Base' (Base may be a directory). auto findInDir = [&](llvm::StringRef Base) -> std::optional<std::string> { + if (Base.empty()) + return std::nullopt; for (const char *LibName : OrcRTLibNames) { - llvm::SmallString<256> CandidatePath(Base); - llvm::sys::path::append(CandidatePath, LibName); - if (llvm::sys::fs::exists(CandidatePath)) - return std::string(CandidatePath.str()); + llvm::SmallString<256> Candidate(Base); + llvm::sys::path::append(Candidate, LibName); + if (llvm::sys::fs::exists(Candidate)) + return std::string(Candidate.str()); } return std::nullopt; }; - const driver::ToolChain &TC = C.getDefaultToolChain(); - std::string SearchedPaths; - if (std::optional<std::string> CompilerRTPath = TC.getCompilerRTPath()) { - if (auto Found = findInDir(*CompilerRTPath)) { - OrcRuntimePath = *Found; + const clang::driver::Driver &D = C.getDriver(); + + llvm::SmallVector<std::string, 8> triedPaths; + + // Prefer Driver::ResourceDir-derived locations: + // ResourceDir is typically: <prefix>/lib/clang/<version> + if (!D.ResourceDir.empty()) { + llvm::SmallString<256> Resource(D.ResourceDir); + + // Directly searching ResourceDir is cheap and sometimes sufficient. + if (auto F = findInDir(Resource)) { + OrcRuntimePath = *F; return llvm::Error::success(); } - SearchedPaths += *CompilerRTPath; - } else { - return llvm::make_error<llvm::StringError>("CompilerRT path not found", - std::error_code()); + triedPaths.emplace_back(std::string(Resource.str())); + + // Build <prefix>/lib/clang/<version>/lib. Resource already contains + // .../clang/<version>) + llvm::SmallString<256> ClangLibDir(Resource); + // ClangLibDir currently: <prefix>/lib/clang/<version> + // We want: <prefix>/lib/clang/<version>/lib + llvm::sys::path::append(ClangLibDir, "lib"); + if (auto F = findInDir(ClangLibDir)) { + OrcRuntimePath = *F; + return llvm::Error::success(); + } + triedPaths.emplace_back(std::string(ClangLibDir.str())); + + // Walk up to <prefix>/lib and search there and common variants. + llvm::SmallString<256> PrefixLib = Resource; + llvm::sys::path::remove_filename(PrefixLib); // remove <version> + llvm::sys::path::remove_filename(PrefixLib); // remove clang + if (!PrefixLib.empty()) { + if (auto F = findInDir(PrefixLib)) { + OrcRuntimePath = *F; + return llvm::Error::success(); + } + triedPaths.emplace_back(std::string(PrefixLib.str())); + + // Also check <prefix>/<libdir_basename>/clang/<version>/lib if present in + // this environment. We extract version from the original ResourceDir + // filename (the '<version>' component). + llvm::SmallString<64> Version = + llvm::sys::path::filename(llvm::StringRef(Resource)); + llvm::SmallString<256> FormalClangLib = PrefixLib; + llvm::sys::path::append(FormalClangLib, "lib", "clang", Version, "lib"); + if (auto F = findInDir(FormalClangLib)) { + OrcRuntimePath = *F; + return llvm::Error::success(); + } + triedPaths.emplace_back(std::string(FormalClangLib.str())); + } } - if (std::optional<std::string> ResourceDir = TC.getRuntimePath()) { - if (auto Found = findInDir(*ResourceDir)) { - OrcRuntimePath = *Found; - return llvm::Error::success(); + // ToolChain runtime/compiler-rt locations (if available). + const clang::driver::ToolChain &TC = C.getDefaultToolChain(); + for (auto RuntimePath : + {TC.getRuntimePath(), std::make_optional(TC.getCompilerRTPath())}) { + if (RuntimePath && TC.getVFS().exists(*RuntimePath)) { + if (auto Found = findInDir(*RuntimePath)) { + OrcRuntimePath = *Found; + return llvm::Error::success(); + } else { + triedPaths.emplace_back(*RuntimePath); + } } - if (!SearchedPaths.empty()) - SearchedPaths += "; "; - SearchedPaths += *ResourceDir; - } else { - return llvm::make_error<llvm::StringError>("ResourceDir path not found", - std::error_code()); } + // If we reached here, nothing was found. Build a helpful error string. + std::string Joined; + for (size_t i = 0; i < triedPaths.size(); ++i) { + if (i) + Joined += ", "; + Joined += triedPaths[i]; + } + if (Joined.empty()) + Joined = "<no candidate paths available>"; + return llvm::make_error<llvm::StringError>( - llvm::Twine("OrcRuntime library not found in: ") + SearchedPaths, - std::error_code()); + llvm::formatv("OrcRuntime library not found in: {0}", Joined).str(), + llvm::inconvertibleErrorCode()); } Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance, _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
