EL TOOLCHAIN COMPILA, ENLAZA Y CORRE — en una caja sin compilador de C

$ cargo build --offline
       Compiling prueba v0.1.0 … Finished in 0.44s
    $ ./target/debug/prueba
    cargo, rustc y ld: los tres nuestros

`cargo` y `rustc` son los que construyó la granja; el enlazador es el `ld` de nuestro `binutils`.

EL MURO 8 SE CERRÓ SIN `lld`. La cadena, que es lo que vale: `-C linker-flavor=ld.lld` → «linker
`lld` not found» (el build con LLVM externo no genera rust-lld); `rust.lld = true` → el bootstrap lo
RECHAZA; `lld21` propio → crasheaba con cualquier entrada; `lld21` con zlib → **no se puede encender
desde ahí**, porque `LLVMConfig.cmake` dice `LLVM_ENABLE_ZLIB 0` y el build standalone lo hereda.

Lo que faltaba NO era un enlazador: era decirle a rustc que enlace en ESTÁTICO. Con `+crt-static`,
rustc usa su propio libunwind/compiler_builtins y deja de pedir `-lgcc` — que es lo que rompía el
intento con `ld`, porque la distro se construye con zig (compiler-rt) y libgcc no existe. Y estático
es el modo natural de musl.

⇒ `scripts/servidor/cargo-config.toml` (instalado en `/etc/cargo/config.toml`) cierra el pendiente
«config del sitio» del §5, con las tres flags y el porqué de cada una.

🧨 Y `lld21` destapó algo que nadie había visto: **las 79 herramientas de `llvm21` están ROTAS**.
`llc --version` crashea igual —también en el worker— porque salen `static-pie` y el enlace estático
descarta los constructores globales de los que dependen `cl::opt` y `TargetRegistry`. Funciona lo
que no los necesita (`llvm-ar`, `llvm-config`) y revienta lo que sí; nadie lo notó porque `rust` usa
`llvm-config` y las `.a`, nunca una herramienta. Queda como deuda DECLARADA: arreglarlo (o encender
zlib) re-hashea `llvm21` y con él `rust`. Hoy no bloquea nada.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-09-16 04:48:25 +00:00
co-authored by Claude Opus 5
parent 201973b8f6
commit ef1f9252a1
2 changed files with 66 additions and 0 deletions
+48
View File
@@ -159,6 +159,54 @@ lo que parece.
[[subcomando-sin-driver]] en el corazón del toolchain — un compilador que compila y no produce un
ejecutable. Un `build ok` no es la prueba; la prueba es el objeto en el disco y el binario corriendo.
## 4.quater ✅ EL TOOLCHAIN COMPILA, ENLAZA Y CORRE *(2026-09-16)*
$ cargo build --offline
Compiling prueba v0.1.0
Finished `dev` profile in 0.44s
$ ./target/debug/prueba
cargo, rustc y ld: los tres nuestros
**En una caja sin compilador de C.** `cargo` y `rustc` son los que construyó la granja; el enlazador
es el `ld` de nuestro `binutils`. El binario sale estático (880 K el de `rustc` a secas) y corre.
### El enlazador no era `lld`: era el `ld` que ya teníamos
El muro 8 se cerró **sin** `rust-lld` y sin `lld21`. La cadena de intentos, que es la parte útil:
| intento | resultado |
|---|---|
| `-C linker-flavor=ld.lld` | `linker \`lld\` not found` — el build con LLVM externo **no genera** `rust-lld` |
| `rust.lld = true` | el bootstrap lo RECHAZA: «Cannot enable LLD … when using external llvm-config» |
| `lld21` (receta nueva) | selló, y **crasheaba con cualquier entrada** (ver abajo) |
| `lld21` dinámico + zlib | el zlib **no se puede encender desde acá**: `LLVMConfig.cmake` dice `LLVM_ENABLE_ZLIB 0` y el build standalone lo hereda |
| **`-C linker-flavor=ld` + `+crt-static`** | **funciona** |
Lo que faltaba no era un enlazador: era **decirle a rustc que enlace en estático**. Con
`crt-static`, rustc usa su propio `libunwind`/`compiler_builtins` y **deja de pedir `-lgcc`** — que
es lo que rompía el intento con `ld`, porque la distro se construye con zig (compiler-rt) y libgcc
no existe. Estático es además el modo natural de musl.
⇒ La config del sitio (el pendiente del §5) ya está escrita: `scripts/servidor/cargo-config.toml`,
instalada en `/etc/cargo/config.toml`, con las tres flags y el porqué de cada una.
### 🧨 Lo que `lld21` destapó de paso: las 79 herramientas de `llvm21` están ROTAS
`lld21` selló y se moría en cuanto hacía algo: `--version` y `--help` bien, y **cualquier** enlace
—incluso uno que sólo debía dar un error— en SIGSEGV con un «Stack dump:» vacío. No era la receta:
$ llc --version (del artefacto llvm21, sellado hace días)
PLEASE submit a bug report … Stack dump: ← también crashea, y también en el worker
Salen **`static-pie`**, y el enlace estático descarta los constructores globales de los que dependen
los registros de LLVM (`cl::opt`, `TargetRegistry`): funciona lo que no los necesita (`llvm-ar`,
`llvm-config`) y revienta lo que sí. **Nadie lo había visto porque `rust` usa `llvm-config` y las
`.a`, nunca una herramienta.** Con `link = "dynamic"`, `lld21` pasa a dar errores limpios.
⚠ **Queda como deuda DECLARADA, no arreglada**: encender zlib en `llvm21` —lo que haría a `lld21`
usable— **re-hashea `llvm21` y con él `rust`**, o sea dos builds largos. Y arreglar las 79
herramientas es la misma operación. Hoy no bloquea nada: el toolchain enlaza con `ld`.
## 5. Lo que falta decidir
- **Dónde vive el toolchain.** Hoy `rust-toolchain-bin` está en `perfil.servidor` (799 M; un
+18
View File
@@ -0,0 +1,18 @@
# Config del SITIO para cargo/rustc — SDD 31.
#
# ⚠ Sin esto, `cargo build` en una caja takana falla con `linker `cc` not found`: la distro NO TIENE
# compilador de C, y no hace falta que lo tenga. Lo que hace falta es decirle a rustc que el
# enlazador es el `ld` de binutils y que el modo es estático, que es el natural de musl.
#
# Por qué CADA flag, todos medidos el 2026-09-16 contra el rustc que construimos:
# · `linker-flavor=ld` + `linker=/usr/bin/ld` — el `ld` del corpus. (`lld` sería más rápido, pero
# el nuestro hereda `LLVM_ENABLE_ZLIB=0` de `llvm21` y no puede leer las secciones de depuración
# COMPRIMIDAS que trae la libc del lab: «is compressed with ELFCOMPRESS_ZLIB, but lld is not
# built with zlib support».)
# · `target-feature=+crt-static` — sin esto rustc pide `-lgcc`/`-lgcc_s` para el desenrollado y el
# enlace muere en `cannot find -lgcc`: la distro se construye con zig, que trae compiler-rt y no
# libgcc. Estático es además el modo natural de musl.
# · `link-self-contained=yes` — usa los `crt*.o` y la `libc.a` que el propio toolchain trae.
[target.x86_64-alpine-linux-musl]
linker = "/usr/bin/ld"
rustflags = ["-C", "linker-flavor=ld", "-C", "target-feature=+crt-static", "-C", "link-self-contained=yes"]