@@ -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