Skip to content

Commit db3b47e

Browse files
committed
fix: first-run gcc default runs the same post-install fixup pipeline
Extract gcc_post_install_fixup (patchelf PT_INTERP/RUNPATH for gcc/binutils + linker-specs wiring against sandbox glibc) out of `toolchain install` and run it from the first-run auto-install too. A fresh-sandbox glibc default previously skipped the fixup and could not find the C library (stdlib.h: No such file or directory — e2e 29/31 on CI). One shared pipeline, no duplicate.
1 parent 4dbd074 commit db3b47e

1 file changed

Lines changed: 57 additions & 41 deletions

File tree

src/cli.cppm

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,54 @@ void fixup_clang_cfg(const std::filesystem::path& payloadRoot,
10181018
}
10191019
}
10201020

1021+
// Post-install fixup for a freshly-installed GNU gcc payload: patchelf
1022+
// PT_INTERP/RUNPATH for gcc/binutils binaries + linker-specs wiring against
1023+
// the sandbox glibc. ONE pipeline shared by `mcpp toolchain install` and the
1024+
// first-run auto-install (the latter previously skipped this, leaving a
1025+
// fresh-sandbox glibc gcc unable to find the C library: stdlib.h not found).
1026+
void gcc_post_install_fixup(const mcpp::config::GlobalConfig& cfg,
1027+
const std::filesystem::path& payloadRoot) {
1028+
auto xlEnv = mcpp::config::make_xlings_env(cfg);
1029+
auto glibcRoot = mcpp::xlings::paths::xim_tool_root(xlEnv, "glibc");
1030+
std::filesystem::path glibcLibDir;
1031+
if (std::filesystem::exists(glibcRoot)) {
1032+
for (auto& v : std::filesystem::directory_iterator(glibcRoot)) {
1033+
auto candidate = v.path() / "lib64";
1034+
if (std::filesystem::exists(candidate / "ld-linux-x86-64.so.2")) {
1035+
glibcLibDir = candidate;
1036+
break;
1037+
}
1038+
}
1039+
}
1040+
auto gccLibDir = payloadRoot / "lib64";
1041+
auto patchelfBin = mcpp::xlings::paths::xim_tool(xlEnv, "patchelf",
1042+
mcpp::xlings::pinned::kPatchelfVersion) / "bin" / "patchelf";
1043+
1044+
if (!glibcLibDir.empty() && std::filesystem::exists(gccLibDir)
1045+
&& std::filesystem::exists(patchelfBin))
1046+
{
1047+
auto loader = glibcLibDir / "ld-linux-x86-64.so.2";
1048+
auto rpath = std::format("{}:{}",
1049+
glibcLibDir.string(), gccLibDir.string());
1050+
1051+
mcpp::log::verbose("toolchain", std::format(
1052+
"gcc fixup: patchelf_walk rpath='{}'", rpath));
1053+
auto binutilsRoot = mcpp::xlings::paths::xim_tool_root(xlEnv, "binutils");
1054+
if (std::filesystem::exists(binutilsRoot)) {
1055+
for (auto& v : std::filesystem::directory_iterator(binutilsRoot))
1056+
patchelf_walk(v.path(), loader, rpath, patchelfBin);
1057+
}
1058+
patchelf_walk(payloadRoot, loader, rpath, patchelfBin);
1059+
1060+
mcpp::log::verbose("toolchain", "gcc fixup: fixup_gcc_specs");
1061+
fixup_gcc_specs(payloadRoot, glibcLibDir, gccLibDir);
1062+
} else {
1063+
mcpp::ui::warning(
1064+
"could not locate sandbox glibc/gcc/patchelf paths; "
1065+
"gcc-built binaries may have unresolved PT_INTERP/RUNPATH");
1066+
}
1067+
}
1068+
10211069
// SemVer resolution: a version spec is a "constraint" (vs. exact literal) if
10221070
// it starts with one of `^~><=` or contains a comma (multi-part), or is `*`
10231071
// or empty. Bare `1.2.3` is treated as exact for back-compat with pre-SemVer
@@ -1482,6 +1530,14 @@ prepare_build(bool print_fingerprint,
14821530
defaultPkg.target(), payload->binDir.string()));
14831531
}
14841532

1533+
// The freshly-installed glibc gcc needs the SAME post-install fixup
1534+
// (patchelf + specs wiring against the sandbox glibc) that
1535+
// `mcpp toolchain install` performs — without it a fresh sandbox
1536+
// cannot find the C library (stdlib.h: No such file or directory).
1537+
if (defaultPkg.needsGccPostInstallFixup) {
1538+
gcc_post_install_fixup(**cfg, payload->root);
1539+
}
1540+
14851541
// Persist the default so we don't ask again next time.
14861542
if (auto wr = mcpp::config::write_default_toolchain(**cfg, defaultSpec); wr) {
14871543
(*cfg)->defaultToolchain = defaultSpec;
@@ -4913,47 +4969,7 @@ int cmd_toolchain(const mcpplibs::cmdline::ParsedArgs& parsed) {
49134969
// `<root>/x86_64-linux-musl/{include,lib}` and doesn't link against
49144970
// xim:glibc, so this fixup is both unnecessary and harmful for it.
49154971
if (pkg.needsGccPostInstallFixup) {
4916-
auto glibcRoot = mcpp::xlings::paths::xim_tool_root(xlEnv, "glibc");
4917-
std::filesystem::path glibcLibDir;
4918-
if (std::filesystem::exists(glibcRoot)) {
4919-
for (auto& v : std::filesystem::directory_iterator(glibcRoot)) {
4920-
auto candidate = v.path() / "lib64";
4921-
if (std::filesystem::exists(candidate / "ld-linux-x86-64.so.2")) {
4922-
glibcLibDir = candidate;
4923-
break;
4924-
}
4925-
}
4926-
}
4927-
auto gccLibDir = payload->root / "lib64";
4928-
auto patchelfBin = mcpp::xlings::paths::xim_tool(xlEnv, "patchelf",
4929-
mcpp::xlings::pinned::kPatchelfVersion) / "bin" / "patchelf";
4930-
4931-
if (!glibcLibDir.empty() && std::filesystem::exists(gccLibDir)
4932-
&& std::filesystem::exists(patchelfBin))
4933-
{
4934-
auto loader = glibcLibDir / "ld-linux-x86-64.so.2";
4935-
auto rpath = std::format("{}:{}",
4936-
glibcLibDir.string(), gccLibDir.string());
4937-
4938-
// (1) patchelf walk: rewrite PT_INTERP + RUNPATH for binutils
4939-
// and gcc xpkgs so they're self-contained in sandbox.
4940-
mcpp::log::verbose("toolchain", std::format(
4941-
"gcc fixup: patchelf_walk rpath='{}'", rpath));
4942-
auto binutilsRoot = mcpp::xlings::paths::xim_tool_root(xlEnv, "binutils");
4943-
if (std::filesystem::exists(binutilsRoot)) {
4944-
for (auto& v : std::filesystem::directory_iterator(binutilsRoot))
4945-
patchelf_walk(v.path(), loader, rpath, patchelfBin);
4946-
}
4947-
patchelf_walk(payload->root, loader, rpath, patchelfBin);
4948-
4949-
// (2) specs fixup.
4950-
mcpp::log::verbose("toolchain", "gcc fixup: fixup_gcc_specs");
4951-
fixup_gcc_specs(payload->root, glibcLibDir, gccLibDir);
4952-
} else {
4953-
mcpp::ui::warning(
4954-
"could not locate sandbox glibc/gcc/patchelf paths; "
4955-
"gcc-built binaries may have unresolved PT_INTERP/RUNPATH");
4956-
}
4972+
gcc_post_install_fixup(*cfg, payload->root);
49574973
}
49584974

49594975
// For LLVM/Clang: post-install fixup so the shared libraries and

0 commit comments

Comments
 (0)