rustc desde fuente está compilando el stage1 en el worker. El documento recoge el frente entero: el hueco medido (12 crates y 42 555 líneas de Rust, 44 recetas `cargo-*`, CERO de rustc, y el `rustc` que construye todo eso saliendo del LAB — que ENTRA en el ArtifactHash), los tres escalones, y lo que costó cada uno. Los cinco muros del escalón 2, todos con un mensaje que no nombra la causa: 1. `llvm18` no sirve: `bad LLVM version, need >=21`. Mínimos medidos en el propio bootstrap (1.87→18 · 1.90→19 · 1.93/1.95→20 · 1.97→21). Bajar de rustc no es salida porque el stage0 de N es N-1 o N. De ahí `llvm21` — y `llvm18` se queda, que lo usa mesa. 2. **El toolchain musl oficial no puede producir proc-macros** (crt-static=true ⇒ sin dylibs): muere compilando el propio bootstrap de rustc, que usa `clap` con derive. Sirve para compilar programas, no para arrancar el build de rustc. El stage0 es el del lab. 3. x.py DESCARGA el stage0 si no le nombras el local: en un sandbox sin red, `RuntimeError: failed verification` en `download_toolchain()`, que no menciona ni la red ni el stage0. 4. El triple de Alpine no es el canónico: sin fijarlo, la sección `[target.…-unknown-…]` no aplica a nada y x.py se pone a construir LLVM solo; forzando el canónico, el stage0 no tiene su std. 5. cmake + zig = «compiler broken» en la prueba de ABI. CC=gcc, igual que llvm21 y cmake. Y del escalón 1, lo que no estaba en el grafo: el prebuilt no ejecuta sin `musl-shared` (cargador) y sin `gcc-libs` (`libgcc_s.so.1`) — dos paquetes sellados y en el perfil equivocado. Más una propiedad que vale: no hace falta un `cc`, el toolchain trae su propio lld. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Tf9T4vGzsMoT7eS8YzMFn
118 lines
6.2 KiB
TOML
118 lines
6.2 KiB
TOML
# 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…).
|
|
# ⚠ EL STAGE0 **NO** ES `rust-toolchain-bin`, Y ESO SE APRENDIÓ CHOCANDO. El toolchain musl oficial
|
|
# de rust-lang está compilado con `crt-static = true`, y un rustc así **no puede producir
|
|
# proc-macros** — que son dylibs. El primer intento murió en el primer minuto:
|
|
#
|
|
# error: cannot produce proc-macro for `clap_derive v4.5.18` as the target
|
|
# `x86_64-unknown-linux-musl` does not support these crate types
|
|
#
|
|
# …compilando el PROPIO bootstrap de rustc, que usa `clap` con derive. O sea: el prebuilt oficial
|
|
# sirve para compilar programas (probado: un binario que corre) y **no** para arrancar el build de
|
|
# rustc. El stage0 es el `rustc` del LAB, que Alpine construye con soporte de dylib.
|
|
#
|
|
# Y por eso abajo va `crt-static = false` para el host: sin eso, el rustc que salga de acá heredaría
|
|
# el mismo defecto y no podría compilar ni una receta del corpus que use `derive`.
|
|
build = ["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]
|
|
# ⚠⚠ EL TRIPLE ES EL DE ALPINE, `x86_64-alpine-linux-musl`, Y NO EL CANÓNICO. Cuesta dos fallos
|
|
# seguidos entenderlo:
|
|
# · Sin decir `build`, x.py detecta el del `cc` del sandbox (el de Alpine) y entonces una sección
|
|
# `[target.x86_64-alpine-linux-musl]` **no aplica a nada**: ignora el `llvm-config` externo y se
|
|
# pone a construir LLVM él solo — se vio porque entró en `/src/build/x86_64-alpine-linux-musl/`.
|
|
# · Y al forzar el canónico, el stage0 del LAB **no tiene la std de ese triple**:
|
|
# `error[E0463]: can't find crate for std`. Alpine RENOMBRA el triple, y su rustc sólo trae la
|
|
# std del suyo.
|
|
# Así que se usa el de Alpine en todas partes, que además es el triple con el que ya se compila todo
|
|
# el corpus. Es el mismo camino que toma el APKBUILD de rust de Alpine.
|
|
build = "x86_64-alpine-linux-musl"
|
|
docs = false
|
|
extended = true
|
|
tools = ["cargo"]
|
|
local-rebuild = true
|
|
# Hay que NOMBRAR el stage0 aunque ya esté en el PATH: sin estas dos líneas, x.py se salta el
|
|
# compilador local y va a DESCARGAR el toolchain de `static.rust-lang.org` — que en un sandbox sin
|
|
# red muere con un `RuntimeError: failed verification` en `download_toolchain()`, un mensaje que no
|
|
# menciona ni la red ni el stage0. Estas rutas son las del LAB, no las del prebuilt (ver arriba).
|
|
rustc = "/usr/bin/rustc"
|
|
cargo = "/usr/bin/cargo"
|
|
target = ["x86_64-alpine-linux-musl"]
|
|
host = ["x86_64-alpine-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-alpine-linux-musl]
|
|
llvm-config = "/usr/bin/llvm-config"
|
|
# `false` a propósito: habilita dylibs, y sin dylibs no hay PROC-MACROS. Un rustc con
|
|
# `crt-static = true` no puede compilar `serde_derive`, `clap_derive` ni ninguna de las 44 recetas
|
|
# `cargo-*` del corpus que usan `derive`.
|
|
crt-static = false
|
|
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
|
|
'''
|
|
# `CC`/`CXX` de GCC para los build scripts nativos (jemalloc, compiler-rt): con el wrapper de zig,
|
|
# cmake declara el compilador «broken» en su prueba de ABI. Mismo motivo por el que `llvm21` y
|
|
# `cmake` usan g++ en vez de zig.
|
|
compile = "export CC=gcc CXX=g++ AR=ar RANLIB=ranlib && python3 x.py build --stage 2"
|
|
install = "export CC=gcc CXX=g++ AR=ar RANLIB=ranlib && DESTDIR=/out python3 x.py install --stage 2"
|