From ef1f9252a1b759023848255b770ec3f47c7cc31b Mon Sep 17 00:00:00 2001 From: Sergio Date: Wed, 16 Sep 2026 04:48:25 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20EL=20TOOLCHAIN=20COMPILA,=20ENLAZA?= =?UTF-8?q?=20Y=20CORRE=20=E2=80=94=20en=20una=20caja=20sin=20compilador?= =?UTF-8?q?=20de=20C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $ 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) --- docs/31-compilador-de-rust.md | 48 ++++++++++++++++++++++++++++++ scripts/servidor/cargo-config.toml | 18 +++++++++++ 2 files changed, 66 insertions(+) create mode 100644 scripts/servidor/cargo-config.toml diff --git a/docs/31-compilador-de-rust.md b/docs/31-compilador-de-rust.md index eeb0c014..b7872cd8 100644 --- a/docs/31-compilador-de-rust.md +++ b/docs/31-compilador-de-rust.md @@ -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 diff --git a/scripts/servidor/cargo-config.toml b/scripts/servidor/cargo-config.toml new file mode 100644 index 00000000..9bf35d85 --- /dev/null +++ b/scripts/servidor/cargo-config.toml @@ -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"]