selfhost-verify: swap rust hammer-built 1.91.1 en /toolchain (SWAP_RUST, auto-consistencia)

Pieza rust del auto-alojamiento "variante b" (la última del frente). A DIFERENCIA de
make/busybox/bwrap/coreutils/linux-headers (herramientas que orquestan/copian ⇒ bytes
idénticos ⇒ of_tree 9adefb82 por construcción), **rustc EMITE los binarios del 4/4**
(arje-zero, hammerd) ⇒ un rustc distinto diverge of_tree. Criterio elegido: AUTO-
CONSISTENCIA (REF recomputado con hammer-rust = nuevo EXPECT_REF; la VM reproduce ESE),
no igualdad byte-a-byte con el baseline Alpine.

- swap-rust-into-toolchain.sh: overlay aditivo y reversible de .scratch/rust-1.91.1-prefix
  sobre /toolchain. El rustlib x86_64-unknown-linux-musl de hammer y sus .so con hash propio
  NO chocan con el x86_64-alpine-linux-musl de Alpine ⇒ sólo se reemplazan /usr/bin/{rustc,
  cargo} (Alpine guardado en *.alpine; --restore deshace). Los 4/4 compilan NATIVO (target
  x86_64-linux-musl == SANDBOX_NATIVE_TARGET, sin --target) ⇒ hammer-rustc emite para su
  triple nativo x86_64-unknown-linux-musl.
- selfhost-verify.sh: SWAP_RUST=1 aplica el swap en $TOOLCHAIN antes del build de stage1
  (así el REF host se computa con hammer-rust) y restaura al salir (trap). Sirve TANTO al
  REF host COMO al toolchain in-VM (--toolchain $TOOLCHAIN). EXPECT_REF pasa a RUST_EXPECT_REF
  (no el 9adefb82 de Alpine). Vars: RUST_PREFIX, RUST_EXPECT_REF.

VALIDADO: el swap aplica/restaura limpio; hammer-rust 1.91.1 (host x86_64-unknown-linux-musl)
compila+corre un crate NATIVO (sin --target) en el devfs — el camino exacto de los 4/4.
NEXT: computar el nuevo RUST_EXPECT_REF (bootstrap stage1+stage2 con SWAP_RUST) y verify in-VM.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-16 21:59:38 -04:00
co-authored by Claude Opus 4.8
parent 526141a05b
commit fb71aca4be
3 changed files with 111 additions and 0 deletions
+10
View File
@@ -36,6 +36,16 @@ These scripts + patch are the working artifacts. The mrustc tree itself lives in
OpenSSL/curl/libgit2, so this makes bootstrap build cargo with the `all-static`
feature set (vendored openssl/libgit2 + static curl/libz, compiled from the
vendored C sources via gcc). Without it the cargo tool fails on `openssl-sys`.
- **`swap-rust-into-toolchain.sh`** — overlay the hammer-built rust 1.91.1
(`.scratch/rust-1.91.1-prefix`) onto a toolchain dir (default `.dev-fs/alpine`)
so `hammer build` / `bootstrap stage1` compile the 4/4 rust inputs (arje-zero,
hammerd) with hammer-rust. Additive + reversible: hammer's `x86_64-unknown-linux-musl`
rustlib and hash-suffixed `.so`s don't collide with Alpine's
`x86_64-alpine-linux-musl`, so only `/usr/bin/{rustc,cargo}` are replaced (Alpine
backed up to `*.alpine`). `--restore` undoes it. Wired into `selfhost-verify.sh`
as `SWAP_RUST=1` (applies before the stage1 build, restores on exit via trap).
**This swap changes `of_tree`** (rustc emits the binaries), so the criterion is
auto-consistency against a NEW `RUST_EXPECT_REF`, not the Alpine `9adefb82`.
- **`run-xpy.sh`** — run rust's `x.py` inside the devfs sandbox, binding the
source at `/src`, the install prefix at `/out`, and the mrustc tree at `/mrustc`
(so the stage0 + `llvm-config` paths in `bootstrap.toml` resolve). Set the
+80
View File
@@ -0,0 +1,80 @@
#!/usr/bin/env bash
# swap-rust-into-toolchain.sh — overlay the hammer-built rust 1.91.1 onto a toolchain
# dir (default .dev-fs/alpine), so `hammer build` / `bootstrap stage1` compile the
# 4/4 rust inputs (arje-zero, hammerd) with hammer-rust instead of Alpine's rustc.
#
# This is the rust tool-swap of the selfhost-verify "variante b". Unlike make/bwrap/…
# (tools that orchestrate/copy → identical bytes), **rustc emits the 4/4 binaries**, so
# a hammer-built rustc produces a DIFFERENT of_tree than Alpine's 9adefb82. Success
# criterion is therefore AUTO-CONSISTENCY: stage1' built with hammer-rust == stage1''
# rebuilt with hammer-rust (a NEW EXPECT_REF), not byte-identity with the Alpine baseline.
#
# The overlay is mostly ADDITIVE and fully reversible:
# - hammer's rustc/cargo use host triple x86_64-unknown-linux-musl and hash-suffixed
# .so names that DON'T collide with Alpine's (x86_64-alpine-linux-musl / other
# hashes), so the new rustlib triple + librustc_driver just sit alongside Alpine's.
# - only /usr/bin/{rustc,cargo} are REPLACED; the originals are backed up to
# usr/bin/<name>.alpine so `--restore` can put them back.
# The 4/4 rust recipes build NATIVE (target x86_64-linux-musl == SANDBOX_NATIVE_TARGET
# ⇒ no --target, see hammer-build/src/lib.rs:269), so hammer-rustc compiles them for
# its OWN native triple x86_64-unknown-linux-musl.
#
# Usage:
# swap-rust-into-toolchain.sh [--prefix DIR] [--toolchain DIR] # apply the swap
# swap-rust-into-toolchain.sh --restore [--toolchain DIR] # undo it
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
PREFIX="$ROOT/.scratch/rust-1.91.1-prefix"
TOOLCHAIN="$ROOT/.dev-fs/alpine"
RESTORE=0
while [ $# -gt 0 ]; do
case "$1" in
--prefix) PREFIX="$2"; shift 2 ;;
--toolchain) TOOLCHAIN="$2"; shift 2 ;;
--restore) RESTORE=1; shift ;;
*) echo "uso: $0 [--prefix DIR] [--toolchain DIR] [--restore]" >&2; exit 2 ;;
esac
done
say() { printf '\033[1;36m==> %s\033[0m\n' "$*"; }
die() { printf '\033[1;31mERROR: %s\033[0m\n' "$*" >&2; exit 1; }
[ -d "$TOOLCHAIN/usr/bin" ] || die "no veo el toolchain en $TOOLCHAIN"
if [ "$RESTORE" = 1 ]; then
say "restaurar el rust de Alpine en $TOOLCHAIN"
for b in rustc cargo; do
if [ -f "$TOOLCHAIN/usr/bin/$b.alpine" ]; then
mv -f "$TOOLCHAIN/usr/bin/$b.alpine" "$TOOLCHAIN/usr/bin/$b"
echo " restaurado usr/bin/$b"
else
echo " (sin backup de usr/bin/$b — ¿ya restaurado?)"
fi
done
echo " (los .so y el rustlib x86_64-unknown-linux-musl añadidos quedan; son inertes — el rustc de Alpine no los usa)"
exit 0
fi
[ -x "$PREFIX/bin/rustc" ] || die "no veo el prefix hammer-rust en $PREFIX (corré el climb primero)"
say "swap: overlay hammer-rust 1.91.1 ($PREFIX) → $TOOLCHAIN"
# 1) librustc_driver de hammer (hash único, no choca con el de Alpine).
cp -a "$PREFIX"/lib/librustc_driver-*.so "$TOOLCHAIN/usr/lib/"
echo " + usr/lib/$(basename "$PREFIX"/lib/librustc_driver-*.so)"
# 2) sysroot de hammer para su triple nativo (dir nuevo, no choca con x86_64-alpine-linux-musl).
rm -rf "$TOOLCHAIN/usr/lib/rustlib/x86_64-unknown-linux-musl"
cp -a "$PREFIX/lib/rustlib/x86_64-unknown-linux-musl" "$TOOLCHAIN/usr/lib/rustlib/"
echo " + usr/lib/rustlib/x86_64-unknown-linux-musl ($(du -sh "$PREFIX/lib/rustlib/x86_64-unknown-linux-musl" | cut -f1))"
# 3) reemplazar rustc y cargo (backup de los de Alpine).
for b in rustc cargo; do
[ -f "$TOOLCHAIN/usr/bin/$b.alpine" ] || cp -a "$TOOLCHAIN/usr/bin/$b" "$TOOLCHAIN/usr/bin/$b.alpine"
cp -a "$PREFIX/bin/$b" "$TOOLCHAIN/usr/bin/$b"
echo " ~ usr/bin/$b (Alpine guardado en usr/bin/$b.alpine)"
done
say "listo. verificá con: bwrap --bind $TOOLCHAIN / ... /usr/bin/rustc --version"
echo " esperado: rustc 1.91.1 (ed61e7d7e …) host x86_64-unknown-linux-musl"
echo " deshacer: $0 --restore --toolchain $TOOLCHAIN"
+21
View File
@@ -68,6 +68,27 @@ SEED_HASH="$(ls -d "$STORE"/*-seed-zig 2>/dev/null | head -1 | sed -E 's#.*/([0-
[[ "$SEED_HASH" == b3:* && ${#SEED_HASH} -eq 67 ]] || die "no encuentro la semilla sellada en $STORE"
say "semilla: $SEED_HASH"
# 0c) Auto-alojamiento del COMPILADOR (variante b, pieza rust). A DIFERENCIA de make/busybox/bwrap/…
# (herramientas que ORQUESTAN o COPIAN ⇒ bytes idénticos), **rustc EMITE los binarios del 4/4**
# (arje-zero, hammerd): un rustc distinto ⇒ of_tree DIVERGE del baseline Alpine 9adefb82. Por eso
# el criterio no es igualdad con Alpine sino AUTO-CONSISTENCIA: el REF se RECOMPUTA con hammer-rust
# (nuevo EXPECT_REF) y la VM debe reproducir ESE. El swap entra en $TOOLCHAIN, que sirve TANTO al
# build host del REF (este script, abajo) COMO al toolchain in-VM del builder (--toolchain); se
# restaura al salir (trap). hammer-rust se construye con scripts/rust-frontier (climb mrustc→1.91.1).
# SWAP_RUST=1 → overlay .scratch/rust-1.91.1-prefix sobre /toolchain/usr/{bin,lib}.
# RUST_PREFIX=DIR → prefix hammer-rust alternativo (default .scratch/rust-1.91.1-prefix).
# RUST_EXPECT_REF=… → REF conocido-bueno de hammer-rust (cross-check; vacío ⇒ sólo lo imprime).
if [[ "${SWAP_RUST:-0}" == 1 ]]; then
RUST_PREFIX="${RUST_PREFIX:-.scratch/rust-1.91.1-prefix}"
[[ -x "$RUST_PREFIX/bin/rustc" ]] || die "SWAP_RUST=1 pero no veo el prefix hammer-rust en $RUST_PREFIX (corré el climb: scripts/rust-frontier/README.md)"
say "variante b (compilador) — swapear hammer-rust 1.91.1 en $TOOLCHAIN (criterio: auto-consistencia)"
scripts/rust-frontier/swap-rust-into-toolchain.sh --prefix "$RUST_PREFIX" --toolchain "$TOOLCHAIN"
trap 'scripts/rust-frontier/swap-rust-into-toolchain.sh --restore --toolchain "$TOOLCHAIN" >/dev/null 2>&1 || true' EXIT
# Con hammer-rust el REF NO es el 9adefb82 de Alpine; comparamos contra RUST_EXPECT_REF (si se
# conoce de una corrida previa), no contra el baseline Alpine.
EXPECT_REF="${RUST_EXPECT_REF:-}"
fi
# 1) Store baseline: stage1 (idempotente; rebuildea lo que falte con -mcpu=baseline ya en fuente).
say "stage1 — construir y sellar el rootfs baseline"
"$HAMMER" --store "$STORE" bootstrap stage1 --seed-hash "$SEED_HASH" --recipes recipes