Files
takana/recipes/rust-toolchain-bin.toml
SergioandClaude Opus 5 41ab76c8a0 RUST COMPILA EN LA CAJA — paso 1 cerrado, y tres paquetes que estaban en el perfil equivocado
`rustc 1.97.0` y `cargo 1.97.0` responden en `2.29.29.217`, y un `fn main(){println!("ok");}`
compila y **corre**. El toolchain oficial de rust-lang, verificado por su sha256 y sellado tal cual
con `foreign = true` (son bytes ajenos, no un build nuestro: clase `ajeno`, fuera del recuento del
corpus).

Lo que costó hacerlo correr, y ninguna de las dos cosas se ve en el grafo porque las dos estaban
`sealed` y en el perfil equivocado:

1. **El cargador musl.** `rustc` es PIE dinámico (`NEEDED librustc_driver-*.so`, `NEEDED libc.so`).
   En el worker ni arranca —`cannot execute: required file not found`, que es como se ve la falta
   del intérprete—; en la caja sí, porque ahí está `musl-shared`.
2. **`libgcc_s.so.1`**: `Error loading shared library … _Unwind_Resume: symbol not found`. Lo
   publica `gcc-libs`, sellado y declarado **sólo en los cuatro perfiles de escritorio**. Una línea
   en `base`. Es la tercera vez HOY que aparece la misma figura —`tar`, `os-release`, `gcc-libs`—:
   el paquete existe, está sellado, y no viaja en la imagen que lo necesita.

Y una propiedad que vale anotar: **no hace falta un `cc`**. El primer `rustc` falla con
`linker \`cc\` not found` y no hay que traer un compilador de C — el toolchain **trae su propio
lld** (`rustlib/<target>/bin/rust-lld`), y con `-C linker-flavor=ld.lld -C link-self-contained=yes`
enlaza y el binario corre. Una distro sin compilador de C puede compilar Rust igual.

Va en `perfil.servidor` y no en `base`: son 799 M y una imagen de escritorio no compila nada.

Pendiente, que es config del SITIO y no de la receta: que esas flags sean el default
(`/etc/cargo/config.toml`), para que `cargo build` funcione sin recordarlas.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Tf9T4vGzsMoT7eS8YzMFn
2026-09-14 22:07:50 +00:00

83 lines
5.3 KiB
TOML

# rust-toolchain-bin — el compilador de Rust, PRECOMPILADO por upstream y sellado tal cual.
#
# ══ POR QUÉ ESTA RECETA EXISTE, Y POR QUÉ ES `foreign` ═════════════════════════════════════════
# Decisión del usuario (2026-09-14): *«sin compilador de rust, takana no tiene sentido»*. Y tiene
# razón por una vía que no es de gusto: **todo el instrumental de takana es Rust** —12 crates,
# 42 555 líneas— y hasta hoy el `rustc` que los construye sale del **LAB**, un rootfs Alpine ajeno.
# Como el lab entra en el `ArtifactHash`, la distro depende de bytes de otro para poder
# reconstruirse a sí misma: eso contradice el invariante central, y no se ve porque funciona.
#
# El corpus tenía **44 recetas `cargo-*` y CERO recetas de `rustc`/`cargo`** — 44 subcomandos sin el
# programa, [[subcomando-sin-driver]] a escala de toolchain.
#
# **`foreign = true` porque son bytes ajenos, no un build nuestro.** No reproduce desde fuente: lo
# que se sella es exactamente el tarball que publica rust-lang, verificado por su `sha256` oficial.
# La marca no cambia el build en nada y sí cambia cómo lo cuenta el grafo (clase `ajeno`, fuera del
# denominador de «cuántas recetas construimos»). Sin ella, meter un prebuilt inflaría la cifra que
# todo el mundo lee como corpus — el riesgo que el ADR 0015 puso por escrito.
#
# ══ ESTO ES EL PASO 1 DE TRES, Y LOS OTROS DOS NO SON OPCIONALES ═══════════════════════════════
# 1. **este** — desbloquea HOY que una caja takana compile Rust, y dice la verdad sobre su origen.
# 2. `rustc` desde fuente con el `llvm18` que YA está sellado en el corpus (379 M). Ahí Rust pasa
# a ser nuestro.
# 3. La cadena `mrustc → 1.90 → 1.91.0 → 1.91.1`, que ya existe documentada en el selfhost
# (`docs/10-roadmap.md`, `docs/11-bootstrap.md`) pero vive en el bootstrap, no en el corpus.
# Es la que quita la última dependencia de bytes ajenos.
#
# ⚠ El target es **musl**, no gnu: es un toolchain que CORRE sobre musl, que es lo que esta distro
# tiene. Un `x86_64-unknown-linux-gnu` traería el cargador de glibc y sería [[needed-colgante-libstdcxx]]
# otra vez — instalado, sellado y sin poder ejecutarse.
name = "rust-toolchain-bin"
version = "1.97.0"
license = "MIT OR Apache-2.0"
foreign = true
[source]
tarball = "https://static.rust-lang.org/dist/rust-1.97.0-x86_64-unknown-linux-musl.tar.xz"
sha256 = "4cebf1c593fcdccf40adb8bc5ef187c3e0dd99f465f9dab48d1a45310ba0de63"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "static"
flags = []
[build.phases]
configure = "true"
compile = "true"
# El tarball trae su propio `install.sh` con componentes (`rustc`, `cargo`, `rust-std-*`). Se usa el
# instalador de upstream en vez de copiar a mano: sabe qué componente va dónde y mantiene el
# `manifest` que `rustup` y el propio toolchain esperan encontrar.
# `--disable-ldconfig`: no hay ldconfig acá y su ausencia haría fallar el instalador por un paso que
# en una distro de binarios estáticos no significa nada.
install = "./install.sh --prefix=/out/usr --disable-ldconfig --components=rustc,cargo,rust-std-x86_64-unknown-linux-musl"
# ══ LO QUE COSTÓ HACERLO CORRER, MEDIDO EN LA CAJA ═════════════════════════════════════════════
# El artefacto sella (799 M) y **no ejecuta** hasta tener dos cosas que la distro publica por
# separado. Ninguna se ve en el grafo: las dos son `sealed` y estaban en el perfil equivocado.
#
# 1. **El cargador musl.** `rustc` es PIE DINÁMICO (`NEEDED librustc_driver-*.so`, `NEEDED libc.so`).
# En el worker ni arranca —`cannot execute: required file not found`, que es como se ve la
# ausencia del intérprete—; en la caja sí, porque ahí está `musl-shared`.
# 2. **`libgcc_s.so.1`.** Con el cargador puesto, el siguiente error fue
# `Error loading shared library libgcc_s.so.1 … _Unwind_Resume: symbol not found`. Lo publica
# `gcc-libs`, que estaba sellado y declarado **sólo en los cuatro perfiles de escritorio**. Una
# línea en `base` y listo. (Tercera vez hoy que aparece la misma figura: el paquete existe y no
# viaja en la imagen que lo necesita.)
#
# Con eso: `rustc 1.97.0` y `cargo 1.97.0` responden en la caja.
#
# ══ Y NO HACE FALTA UN `cc` ════════════════════════════════════════════════════════════════════
# El primer `rustc hola.rs` falla con `linker \`cc\` not found`: la caja no tiene compilador de C.
# No hace falta traer uno — **el toolchain trae su propio `lld`**
# (`lib/rustlib/<target>/bin/rust-lld` y su `gcc-ld/`), y con
#
# -C linker-flavor=ld.lld -C linker=<…>/rust-lld -C link-self-contained=yes
#
# enlaza y el binario CORRE. Probado en la caja: `fn main(){println!("ok");}` → `ok`. Es una
# propiedad que vale anotar: una distro sin compilador de C puede compilar Rust igual.
#
# ⚠ Pendiente (config del SITIO, no de la receta): que esas flags sean el default, con un
# `/etc/cargo/config.toml` o el `CARGO_TARGET_*_LINKER` correspondiente, para que `cargo build`
# funcione sin recordarlas.