|
2 | 2 | // |
3 | 3 | // Layout (per docs/14-data-layout.md): |
4 | 4 | // $MCPP_HOME/ default ~/.mcpp/ |
5 | | -// bin/xlings vendored xlings binary |
| 5 | +// bin/mcpp mcpp binary (self-contained mode) |
6 | 6 | // registry/ XLINGS_HOME for mcpp's xlings |
| 7 | +// bin/xlings vendored xlings binary (= <XLINGS_HOME>/bin/xlings) |
7 | 8 | // .xlings.json seeded with index_repos = [mcpp-index] |
8 | 9 | // bmi/<fp>/ BMI cache (existing) |
9 | 10 | // cache/ metadata caches |
@@ -34,7 +35,7 @@ struct GlobalConfig { |
34 | 35 | // Resolved paths |
35 | 36 | std::filesystem::path mcppHome; // ~/.mcpp/ |
36 | 37 | std::filesystem::path binDir; // mcppHome/bin |
37 | | - std::filesystem::path xlingsBinary; // mcppHome/bin/xlings |
| 38 | + std::filesystem::path xlingsBinary; // mcppHome/registry/bin/xlings |
38 | 39 | std::filesystem::path registryDir; // mcppHome/registry |
39 | 40 | std::filesystem::path bmiCacheDir; // mcppHome/bmi |
40 | 41 | std::filesystem::path metaCacheDir; // mcppHome/cache |
@@ -194,7 +195,7 @@ bool write_default_config_toml(const std::filesystem::path& path) { |
194 | 195 | constexpr auto tmpl = R"(# mcpp global config — auto-generated; safe to edit. |
195 | 196 |
|
196 | 197 | [xlings] |
197 | | -# binary: "bundled" (use $MCPP_HOME/bin/xlings) | "system" | absolute path |
| 198 | +# binary: "bundled" (use $MCPP_HOME/registry/bin/xlings) | "system" | absolute path |
198 | 199 | binary = "bundled" |
199 | 200 | # home: empty = use $MCPP_HOME/registry; can override |
200 | 201 | home = "" |
@@ -324,47 +325,12 @@ void ensure_sandbox_init(const GlobalConfig& cfg, bool quiet) noexcept { |
324 | 325 | } |
325 | 326 | } |
326 | 327 |
|
327 | | -// Place a copy of the xlings binary at <XLINGS_HOME>/bin/xlings so that |
328 | | -// xlings 0.4.10's `process_xvm_operations_` shim creation guard |
329 | | -// (installer.cppm:480 — `if (fs::exists(paths.homeDir / "bin" / "xlings"))`) |
330 | | -// passes. Without this, xim install hooks register version pins in |
331 | | -// <subos>/.xlings.json but never create the per-tool shims in |
332 | | -// <subos>/bin/, leaving `as`/`ld`/etc. unreachable in the sandbox. |
333 | | -// |
334 | | -// We use a hardlink so disk cost is zero and the binary stays in lockstep |
335 | | -// with whatever mcpp's bin/xlings is. |
336 | | -// |
337 | | -// TODO(xlings-upstream): When xlings learns to self-bootstrap on first |
338 | | -// `XLINGS_HOME=<empty-dir> xlings install ...` (auto-hardlink from |
339 | | -// /proc/self/exe), this function becomes unnecessary. |
340 | | -void ensure_sandbox_xlings_binary(const GlobalConfig& cfg, bool quiet) noexcept { |
341 | | - auto src = cfg.xlingsBinary; |
342 | | - auto dst = cfg.xlingsHome() / "bin" / "xlings"; |
343 | | - if (std::filesystem::exists(dst)) return; |
344 | | - if (!std::filesystem::exists(src)) return; // upstream issue, surface elsewhere |
345 | | - |
346 | | - std::error_code ec; |
347 | | - std::filesystem::create_directories(dst.parent_path(), ec); |
348 | | - |
349 | | - // Try hardlink first (cheap); fall back to copy if cross-device. |
350 | | - std::filesystem::create_hard_link(src, dst, ec); |
351 | | - if (ec) { |
352 | | - ec.clear(); |
353 | | - std::filesystem::copy_file(src, dst, |
354 | | - std::filesystem::copy_options::overwrite_existing, ec); |
355 | | - } |
356 | | - if (!ec) { |
357 | | - std::filesystem::permissions(dst, |
358 | | - std::filesystem::perms::owner_exec |
359 | | - | std::filesystem::perms::group_exec |
360 | | - | std::filesystem::perms::others_exec, |
361 | | - std::filesystem::perm_options::add, ec); |
362 | | - } |
363 | | - if (ec && !quiet) { |
364 | | - std::println(stderr, |
365 | | - "warning: failed to mirror xlings binary into sandbox bin: {}", |
366 | | - ec.message()); |
367 | | - } |
| 328 | +// With the 0.0.4 layout change (xlings binary at <MCPP_HOME>/registry/bin/ |
| 329 | +// = <XLINGS_HOME>/bin/), the bundled xlings IS already at the path xlings's |
| 330 | +// shim-creation guard checks (`paths.homeDir / "bin" / "xlings"`). |
| 331 | +// No mirroring / hardlinking needed — this function is now a no-op. |
| 332 | +void ensure_sandbox_xlings_binary(const GlobalConfig& /*cfg*/, bool /*quiet*/) noexcept { |
| 333 | + // Intentional no-op: xlingsBinary == xlingsHome()/bin/xlings. |
368 | 334 | } |
369 | 335 |
|
370 | 336 | // ─── Bootstrap install: shared event-stream parser + driver ──────────── |
@@ -596,8 +562,13 @@ std::expected<GlobalConfig, ConfigError> load_or_init( |
596 | 562 | // 1. Resolve paths |
597 | 563 | cfg.mcppHome = home_dir(); |
598 | 564 | cfg.binDir = cfg.mcppHome / "bin"; |
599 | | - cfg.xlingsBinary = cfg.binDir / "xlings"; |
600 | 565 | cfg.registryDir = cfg.mcppHome / "registry"; |
| 566 | + // xlings lives under registry/, not bin/ — it's a registry tool, |
| 567 | + // not a user-facing binary. This also places it exactly at |
| 568 | + // <XLINGS_HOME>/bin/xlings, which satisfies xlings's own shim- |
| 569 | + // creation guard (`if fs::exists(homeDir/"bin"/"xlings")`), |
| 570 | + // making ensure_sandbox_xlings_binary() a no-op. |
| 571 | + cfg.xlingsBinary = cfg.registryDir / "bin" / "xlings"; |
601 | 572 | cfg.bmiCacheDir = cfg.mcppHome / "bmi"; |
602 | 573 | cfg.metaCacheDir = cfg.mcppHome / "cache"; |
603 | 574 | cfg.logDir = cfg.mcppHome / "log"; |
|
0 commit comments