Files
takana/scripts/rust-frontier/README.md
T
sergioandClaude Opus 4.8 bf3f1166ec selfhost-verify: artefactos del frente rust (parche run_rustc + runners stage0-musl)
Rastrea las correcciones del frente rust que vivían en .scratch/ (gitignored):

- run_rustc.patch (vs mrustc be69c74): minicargo/hello con --target musl;
  RUSTFLAGS + sitios de link con link-self-contained=no (CRT vía gcc Alpine,
  link dinámico contra musl); proxy host-units con crt-static off (sin inject
  de --target, host==target==musl con el stage0 musl-host).
- build-stage0-musl.sh: rebuild del stage0 rustc+cargo con host triple musl
  (CFG_COMPILER_HOST_TRIPLE vía RUSTC_TARGET, --target vía MRUSTC_TARGET),
  reusa LLVM + bin/mrustc. Gotcha OUTDIR_SUF documentado.
- run-runrustc.sh: corre targets de run_rustc en el sandbox devfs apuntando
  al stage0 musl-host.
- README: diagnóstico de los 3 snags acoplados (std-gnu mmap64/open64,
  CRT self-contained ausente, host-triple gnu + proc-macros) y el workflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 21:48:37 -04:00

81 lines
4.0 KiB
Markdown

# rust-frontier — self-hosting the builder's rust toolchain
The last frontier of `selfhost-verify` variante (b): replace the Alpine
`rustc/cargo 1.91.1` in `/toolchain` with a hammer-built rust, via the **purist
mrustc chain** (no prebuilt rustc binary). Path:
mrustc → rustc 1.90.0 (builds bundled LLVM) → 1.91.0 → 1.91.1
These scripts + patch are the working artifacts. The mrustc tree itself lives in
`.scratch/mrustc` (gitignored — it's a large third-party clone, upstream master
`be69c74`); only our deltas are tracked here.
## Files
- **`run_rustc.patch`** — patch against mrustc `be69c74` for `run_rustc/Makefile`
and `run_rustc/rustc_proxy.sh`. Apply from the mrustc root:
`git -C .scratch/mrustc apply /path/to/run_rustc.patch`
- **`build-stage0-musl.sh`** — rebuild the mrustc stage0 `rustc`+`cargo` with a
**musl host triple** (`output-1.90.0-x86_64-unknown-linux-musl/`). Run inside
the Alpine devfs sandbox (gcc, MRUSTC_TARGET_VER=1.90). Reuses the already-built
LLVM and `bin/mrustc`.
- **`run-runrustc.sh`** — run a `run_rustc` make target inside the devfs sandbox,
pointed at the musl-host stage0.
> Both runners hardcode `/home/sergio/hammer` and assume the prepared devfs at
> `.dev-fs/alpine` (256-TLS-key musl loader + g++; see the bootstrap-devfs notes).
## Why the patches exist (the snags)
The lab is **musl-only** (Alpine devfs); the 4/4 inputs (arje-zero/hammerd) are
built `--target x86_64-unknown-linux-musl`. Three coupled problems had to be fixed
to bootstrap a usable rust there:
1. **stage-1 std built for gnu** (`mmap64`/`open64` undefined at link).
`minicargo` was invoked without `--target`, so it used mrustc's default **gnu**
triple — and gnu std references glibc's LFS64 symbols that musl 1.2.5 doesn't
export. Fix: pass `--target $(RUSTC_TARGET)` to minicargo (Makefile:162) and to
the stage-1 smoke-test (Makefile:172). A correct musl std uses the **base** libc
symbols (`open`/`mmap`/…), matching Alpine's reference std.
2. **self-contained CRT absent.** musl's default link is `-static-pie` against a
`lib/rustlib/<t>/lib/self-contained/` CRT dir that the mrustc sysroot never
populates. Fix: `-C target-feature=-crt-static -C link-self-contained=no` so the
Alpine gcc supplies crt1/crti/crtn + crtbeginS/crtendS and links dynamically
against the system musl (RUSTFLAGS in Makefile:111, plus the per-link sites).
3. **host-triple = gnu on a musl system** (the deep one). cargo compiles
build-scripts and **proc-macros** for the *host*; mrustc's stage0 rustc has its
host triple baked as `x86_64-unknown-linux-gnu` (not runtime-overridable). A
proxy `--target musl` inject fixes build-script *bins*, but **proc-macros are
dlopen'd and must match the host triple structurally** — injection makes them
target artifacts that rustc rejects. Aliasing musl rlibs as gnu also fails:
rustc reads the triple from rlib *metadata* (`E0461`), not the path.
**The only fix is a stage0 rustc whose host triple is musl** — that's what
`build-stage0-musl.sh` produces (`CFG_COMPILER_HOST_TRIPLE` via `RUSTC_TARGET`,
`--target` via `MRUSTC_TARGET`). Then host==target==musl: cargo doesn't
cross-compile, proc-macros load natively, and `rustc_proxy.sh` only needs the
CRT flags (no `--target` inject).
Gotcha: do **not** pass `OUTDIR_SUF` on make's command line — a command-line var
can't be reassigned by the makefile, so the `-musl` suffix append is skipped and
the build contaminates the gnu output dir. Let it default.
## Workflow
```sh
# 1. apply the run_rustc patch into the mrustc clone
git -C .scratch/mrustc apply scripts/rust-frontier/run_rustc.patch
# 2. rebuild stage0 rustc+cargo with a musl host triple (~hours, reuses LLVM)
.scratch/build-stage0-musl.sh # -> output-1.90.0-x86_64-unknown-linux-musl/
# 3. build the optimised rustc + cargo via run_rustc (stage 1/2/3)
.scratch/run-runrustc.sh all
# 4. (next) climb 1.90.0 → 1.91.0 → 1.91.1, then swap rust into /toolchain
```
Full diagnostic history is in the `selfhost-verify-rust-frontier` memory.