rust 1.97.0 desde fuente: paso 2 — con llvm21 externo y el prebuilt como stage0

El segundo escalón de los tres: rustc construido acá, con el `llvm21` del corpus y con
`rust-toolchain-bin` (el tarball oficial sellado ayer) como **stage0**. Un prebuilt ajeno sirve
exactamente para esto: ser el escalón que permite dejar de necesitarlo.

Tres cosas que no son detalles y que van escritas en la receta:

· **`local-rebuild = true`**: el bootstrap espera que el stage0 sea el compilador ANTERIOR (o el
  beta de esta versión), y acá es 1.97.0 construyendo 1.97.0. Sin esa opción x.py aborta por
  «stage0 compiler version mismatch». Es el modo con el que las distros reconstruyen la misma
  versión con la misma versión.
· **LLVM externo ≥21**, medido en el propio bootstrap (`bad LLVM version … need >=21`). Por eso
  existe `llvm21`: `llvm18` está sellado pero lo usa mesa, que no soporta 21.
· **Sin red**: el tarball `-src` trae `vendor/` con todas las deps de cargo. Es la única forma de
  construir dentro del sandbox, que no tiene red después del fetch.

Y una guarda en el `configure`: la versión del stage0 se COMPRUEBA (`rustc --version | grep 1.97.0`)
en vez de asumirse. `local-rebuild` sólo es correcto si el compilador de arranque es exactamente
esta versión; si alguien mueve el pin de `rust-toolchain-bin`, esto tiene que fallar ahí y no tres
horas después.

`llvm21` ya selló: 1,6 G, `llvm-config --version` → 21.1.2.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Tf9T4vGzsMoT7eS8YzMFn
This commit is contained in:
Sergio
2026-09-15 00:19:37 +00:00
co-authored by Claude Opus 5
parent f4a78e8b03
commit 026eb44677
+83
View File
@@ -0,0 +1,83 @@
# rust 1.97.0 DESDE FUENTE — el paso 2 de los tres, y el que hace que el compilador sea nuestro.
#
# ══ LA CADENA, Y POR QUÉ ESTE ES EL SEGUNDO ESCALÓN ════════════════════════════════════════════
# 1. `rust-toolchain-bin` — el tarball oficial, `foreign`, sellado tal cual. Desbloqueó que una
# caja takana compile Rust (probado: `rustc 1.97.0` y un binario que corre). Es el escalón.
# 2. **esto** — rustc construido acá, con `llvm21` del corpus y con el (1) como **stage0**. Un
# prebuilt ajeno sirve exactamente para esto: ser el escalón que permite dejar de necesitarlo.
# 3. La cadena `mrustc → 1.90 → 1.91.0 → 1.91.1` del selfhost, que quita hasta ese escalón.
#
# ⚠ **`local-rebuild = true` NO es un detalle.** El bootstrap de rustc espera que el stage0 sea el
# compilador ANTERIOR (o el beta de esta versión); acá el stage0 es **1.97.0 construyendo 1.97.0**, y
# sin esa opción x.py aborta por «stage0 compiler version mismatch». Es el modo que usan las distros
# para reconstruir la misma versión con la misma versión.
#
# ⚠ **El LLVM es EXTERNO y tiene que ser ≥21**, medido en el propio bootstrap:
# `panic!("bad LLVM version: {version}, need >=21")`. Por eso existe `llvm21` y por eso `llvm18` —que
# ya estaba sellado— no servía: lo usa mesa, que no soporta 21. Ver `recipes/llvm21.toml`.
#
# ⚠ Sin red: el tarball `-src` trae `vendor/` con todas las deps de cargo. Es la única forma de que
# esto construya dentro del sandbox, que no tiene red después del fetch.
name = "rust"
version = "1.97.0"
license = "MIT OR Apache-2.0"
[source]
tarball = "https://static.rust-lang.org/dist/rustc-1.97.0-src.tar.xz"
sha256 = "de002ee301c1b7422b0a7b09d7c4cb4924cd3224e6cfb24f065dad786dd3ed12"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "dynamic"
flags = []
[deps]
# `rust-toolchain-bin` es el STAGE0: el compilador con el que arranca el build. `llvm21` aporta el
# `llvm-config` y las librerías. `cmake`/`samurai`/`pkgconf` los pide el propio bootstrap aunque el
# LLVM venga hecho (compila algunas cosas nativas: `compiler-rt` para los sanitizers, jemalloc…).
build = ["rust-toolchain-bin", "llvm21", "cmake", "samurai", "python3", "pkgconf", "curl"]
[build.phases]
# El fichero de configuración de x.py se llama `bootstrap.toml` desde 1.8x; se escribe también
# `config.toml` porque el nombre viejo sigue siendo el que busca media documentación, y un fichero
# de más no cuesta nada mientras el de verdad esté.
configure = '''
cat > bootstrap.toml <<'CFG'
profile = "dist"
change-id = "ignore"
[build]
docs = false
extended = true
tools = ["cargo"]
local-rebuild = true
rustc = "/usr/bin/rustc"
cargo = "/usr/bin/cargo"
target = ["x86_64-unknown-linux-musl"]
host = ["x86_64-unknown-linux-musl"]
vendor = true
[llvm]
download-ci-llvm = false
link-shared = false
[rust]
channel = "stable"
codegen-tests = false
deny-warnings = false
musl-root = "/usr"
[target.x86_64-unknown-linux-musl]
llvm-config = "/usr/bin/llvm-config"
crt-static = true
CFG
cp bootstrap.toml config.toml
# La versión del stage0 se COMPRUEBA, no se asume: `local-rebuild` sólo es correcto si el compilador
# de arranque es exactamente esta versión, y si alguien mueve el pin de `rust-toolchain-bin` esto
# tiene que fallar acá y no tres horas después.
rustc --version | grep -q '1\\.97\\.0' || { echo "stage0 NO es 1.97.0: $(rustc --version)" >&2; exit 1; }
llvm-config --version
'''
compile = "python3 x.py build --stage 2"
install = "DESTDIR=/out python3 x.py install --stage 2"