Skip to content

Commit 359aaa8

Browse files
authored
fix: patchelf LLVM runtime libs to fix stale RUNPATH after install (#67)
libc++.so.1 depends on libatomic.so.1 (NEEDED). After mcpp copies the LLVM xpkg from xlings, the shared libraries retain xlings-era RUNPATH entries that point to non-existent paths. Since ELF RUNPATH is non-transitive, the loader uses libc++.so.1's own stale RUNPATH when searching for libatomic.so.1, causing runtime failure on systems without a system-installed gcc runtime. Fix: run patchelf_walk() on the LLVM lib/ directory (not bin/) after install, rewriting RUNPATH to point to the mcpp registry paths. This mirrors the existing GCC post-install fixup. The bin/ directory is excluded because clang++ has its own xlings-managed RUNPATH that must be preserved.
1 parent bb3d667 commit 359aaa8

1 file changed

Lines changed: 25 additions & 3 deletions

File tree

src/cli.cppm

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3802,9 +3802,9 @@ int cmd_toolchain(const mcpplibs::cmdline::ParsedArgs& parsed) {
38023802
}
38033803
}
38043804

3805-
// For LLVM/Clang: post-install cfg fixup so the clang++.cfg paths
3806-
// point to the payload's actual location instead of the xlings
3807-
// install-time paths (which become stale after copy).
3805+
// For LLVM/Clang: post-install fixup so the shared libraries and
3806+
// clang++.cfg paths point to the payload's actual location instead
3807+
// of the xlings install-time paths (which become stale after copy).
38083808
if (pkg.ximName == "llvm") {
38093809
auto glibcRoot = mcpp::xlings::paths::xim_tool_root(xlEnv, "glibc");
38103810
std::filesystem::path glibcLibDir;
@@ -3822,6 +3822,28 @@ int cmd_toolchain(const mcpplibs::cmdline::ParsedArgs& parsed) {
38223822
}
38233823
}
38243824
}
3825+
3826+
// patchelf: rewrite RUNPATH for LLVM runtime shared libraries
3827+
// (libc++.so, libunwind.so, etc.) so transitive deps like
3828+
// libatomic.so.1 are found at runtime. Without this,
3829+
// libc++.so.1 keeps stale xlings-era RUNPATH and cannot locate
3830+
// libatomic.so.1 which lives in the same xpkg.
3831+
//
3832+
// Only walk lib/ dirs — NOT bin/. The clang++ binary has its
3833+
// own RUNPATH set by xlings (pointing to zlib, libxml2, etc.)
3834+
// that must be preserved.
3835+
auto patchelfBin = mcpp::xlings::paths::xim_tool(xlEnv, "patchelf",
3836+
mcpp::xlings::pinned::kPatchelfVersion) / "bin" / "patchelf";
3837+
if (!glibcLibDir.empty() && std::filesystem::exists(patchelfBin)) {
3838+
auto loader = glibcLibDir / "ld-linux-x86-64.so.2";
3839+
auto llvmTargetLib = payload->root / "lib" / "x86_64-unknown-linux-gnu";
3840+
auto llvmLib = payload->root / "lib";
3841+
std::string rpath = llvmTargetLib.string()
3842+
+ ":" + llvmLib.string()
3843+
+ ":" + glibcLibDir.string();
3844+
patchelf_walk(llvmLib, loader, rpath, patchelfBin);
3845+
}
3846+
38253847
fixup_clang_cfg(payload->root, glibcLibDir);
38263848
}
38273849

0 commit comments

Comments
 (0)