Commit Graph
3 Commits
Author SHA1 Message Date
SergioandClaude Opus 5 e903f486d9 el enlazador va DENTRO del compilador — /etc/cargo/config.toml es una ruta que cargo no lee
La prueba de la caja recién instalada —`cargo build` en un proyecto nuevo, sin flags ni rutas a
mano— falló con `linker `cc` not found`, y destapó que la pieza que había empaquetado era falsa:
**cargo NO LEE `/etc/cargo/config.toml`**. Sólo lee `$CARGO_HOME/config.toml`, los
`.cargo/config.toml` del proyecto y sus padres, y lo que se le pase con `--config` — que es lo que yo
venía pasando a mano en cada prueba, y por eso «funcionaba».

Y el arreglo no era mover el fichero: **el que enlaza es `rustc`, y rustc no lee la config de
cargo**. Las flags van DENTRO del compilador, en el spec del triple:

· `linker = "ld.lld"` + `linker_flavor = Gnu(Cc::No, Lld::Yes)` — sin esto rustc busca `cc`, que una
  caja takana no tiene.
· `crt_static_default = true` — sin esto enlaza dinámico y pide `-lgcc`, que no existe (la distro se
  construye con zig, que trae compiler-rt).
· `crt_static_allows_dylibs = true` — su pareja obligatoria: sin ella `crt-static` apaga los dylibs
  y con ellos los PROC-MACROS (serde_derive, clap_derive, las 44 recetas `cargo-*` con `derive`).
  El compilador en sí sigue dinámico: el `bootstrap.toml` fija `crt-static = false` para el build, y
  eso gana sobre el default del spec.

⇒ `cargo-config` (receta, árbol y copia en scripts/) se van enteros: un paquete que instala un
fichero que nadie abre es peor que no tenerlo.

Y de paso, `lld21` instala los cuatro alias como SYMLINKS y no como copias: cmake los duplicaba, 5 ×
96 M = 478 M de artefacto para 97 M de enlazador. Ahora 108 M, y `ld.lld` sigue despachando por
`argv[0]`, que es como upstream lo diseñó.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 13:07:56 +00:00
SergioandClaude Opus 5 201973b8f6 lld21: dinámico y con zlib — dos fallos que sólo se ven USÁNDOLO
El primer `lld21` selló, arrancó y se moría en cuanto hacía algo: `--version` y `--help` contestaban
bien, y CUALQUIER enlace —incluso uno que sólo debía dar un error, como un fichero de entrada
inexistente— terminaba en SIGSEGV con el banner de LLVM y un «Stack dump:» vacío.

🧨 Y no era culpa de esta receta: **las 79 herramientas que publica `llvm21` tienen el mismo defecto**
—`llc --version` también crashea, y también en el worker— porque salen `static-pie` y el enlace
estático descarta los constructores globales de los que dependen los registros de LLVM
(`cl::opt`, `TargetRegistry`). Lo que funciona es lo que no los necesita (`llvm-ar`, `llvm-config`),
y por eso nadie lo había visto: `rust` usa `llvm-config` y las `.a`, nunca una herramienta.
⇒ `link = "dynamic"` en esta receta (como `openssl-threads`, y por lo mismo: el flag global decide
cosas que la receta no dice). Control en los dos sentidos: con `static`, SIGSEGV; con `dynamic`,
`ld.lld: error: cannot open /no/existe.o: No such file or directory` — un error limpio.

Y el segundo, ya enlazando de verdad con nuestro rustc:

    lld: error: …/self-contained/crtn.o:(.debug_line) is compressed with ELFCOMPRESS_ZLIB,
         but lld is not built with zlib support

Los objetos `crt*` del sysroot de rust llevan las secciones de depuración COMPRIMIDAS. Para `llvm21`
apagar zlib era gratis; para el ENLAZADOR no lo es. ⇒ `-DLLVM_ENABLE_ZLIB` encendido y `zlib` a las
deps — copiar los flags del hermano sin preguntarse qué hace cada uno es lo que lo causó.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 04:36:38 +00:00
SergioandClaude Opus 5 a9911785e1 lld21: el enlazador de la distro — porque el bootstrap de rust se NIEGA a construirlo
La vía (a) está CERRADA, y lo dice el propio bootstrap en una línea:

    Cannot enable LLD with `rust.lld = true` when using external llvm-config.

Había leído el paso `Lld` —que compila desde el `src/llvm-project/lld` del tarball y reusa el
`llvm-config` externo— y me faltó mirar la VALIDACIÓN de config, que rechaza la combinación antes de
llegar a ese paso. La guarda tiene sentido: LLD y LLVM comparten ABI de C++, y con un llvm-config
externo el bootstrap no puede garantizar que casen. O sea: mientras usemos el `llvm21` del corpus
—que es lo que queremos— el toolchain NO se va a construir su propio `rust-lld`.

⇒ `recipes/lld21.toml` construye el MISMO `lld`, del mismo `llvm-project` (mismo tarball y mismo
sha256 que `llvm21`, byte por byte), pero SÓLO el subproyecto: `cmake -S lld` contra el LLVM ya
instalado por la dep. Minutos en vez de horas, y sin re-hashear `llvm21` —que encender
`LLVM_ENABLE_PROJECTS=lld` ahí dentro habría arrastrado a `rust` con él.

⚠ Y al revertir el flag aprendí algo que vale para todas las recetas con heredoc: el texto del
`bootstrap.toml` que la fase escribe **es parte de la fase, o sea ENTRADA DE HASH**. Mi comentario
explicando el fallo, puesto ahí adentro, cambiaba el hash del compilador entero: hora y media de
granja por un párrafo. Va fuera, como comentario de la receta, y el hash vuelve a `015a07fb…` — el
artefacto que ya está sellado.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 01:02:49 +00:00