diff --git a/recipes/incoming/lld21.toml b/recipes/incoming/lld21.toml new file mode 120000 index 00000000..f4b28e68 --- /dev/null +++ b/recipes/incoming/lld21.toml @@ -0,0 +1 @@ +../lld21.toml \ No newline at end of file diff --git a/recipes/lld21.toml b/recipes/lld21.toml new file mode 100644 index 00000000..b377d01d --- /dev/null +++ b/recipes/lld21.toml @@ -0,0 +1,61 @@ +# LLD 21.1.2 — el ENLAZADOR de la distro. Mismo `llvm-project` que `llvm21`, construido aparte. +# +# ══ POR QUÉ EXISTE (SDD 31, muro 8) ════════════════════════════════════════════════════════════ +# `rust` desde fuente selló, corre y **no puede enlazar**: en una caja sin `cc` —cualquier takana que +# no sea un hub— `rustc hola.rs` muere con `linker \`lld\` not found`, y con el `ld` de binutils con +# `cannot find -lgcc`. La causa está en una línea del log del propio build que parece informativa: +# +# skipping llvm-tools (x86_64-alpine-linux-musl): external LLVM +# +# Al usar un LLVM externo —que es lo que queremos, porque `llvm21` es del corpus— x.py se salta las +# herramientas de LLVM, y `rust-lld` es una de ellas. +# +# ⚠ Y la vía obvia está CERRADA por el propio bootstrap, medido: `rust.lld = true` contesta +# «Cannot enable LLD with `rust.lld = true` when using external llvm-config». La guarda tiene +# sentido —LLD y LLVM comparten ABI de C++— pero deja una sola salida: construir LLD nosotros. +# +# ⚠ Y `llvm21` no servía de repuesto: sobre sus 1,6 G de artefacto **no publica ningún `lld`** +# (`-DLLVM_ENABLE_PROJECTS=""`). Encenderlo ahí re-hashearía llvm21 y con él `rust`; separado, esto +# suma sin mover nada. +# +# ══ QUÉ CAMBIA FRENTE A llvm21 ═════════════════════════════════════════════════════════════════ +# Se compila SÓLO el subproyecto `lld` (`cmake -S lld`), contra el LLVM ya instalado por la dep: +# minutos en vez de horas, y nada de volver a compilar los 1,6 G de librerías. +name = "lld21" +version = "21.1.2" +license = "Apache-2.0 WITH LLVM-exception" + +[source] +# El mismo tarball que `llvm21`, byte por byte: la URL es locator y el sha256 es la identidad +# (ADR 0013), así que compartir fuente entre dos recetas no cuesta nada. +tarball = "https://github.com/llvm/llvm-project/releases/download/llvmorg-21.1.2/llvm-project-21.1.2.src.tar.xz" +sha256 = "1a417d1c8faf8d93e73fec1cbb76d393ed3218974c2283c7bac9672d3d47c54b" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" +strip_debug = true + +[deps] +# `llvm21` NO es un adorno: el build standalone de lld necesita su `lib/cmake/llvm/LLVMConfig.cmake` +# y sus `.a`. Es la misma dep que el paso `Lld` del bootstrap de rustc habría usado. +build = ["llvm21", "cmake", "samurai", "python3", "pkgconf"] + +[build.phases] +# `g++` con los runtimes estáticos, igual que `llvm21` y `cmake`: C++ a escala con zig sigue siendo +# terreno minado, y además LLD tiene que casar ABI con el LLVM contra el que enlaza — que se +# construyó exactamente así. +configure = ''' +CC=gcc CXX='g++ -static-libstdc++ -static-libgcc' \ +cmake -S lld -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DLLVM_DIR=/usr/lib/cmake/llvm \ + -DLLVM_INCLUDE_TESTS=OFF \ + -DLLVM_ENABLE_ZLIB=OFF \ + -DLLVM_ENABLE_ZSTD=OFF \ + -DLLVM_ENABLE_LIBXML2=OFF +''' +compile = "ninja -C build" +install = "DESTDIR=/out ninja -C build install" diff --git a/recipes/rust.toml b/recipes/rust.toml index c0584d88..1d693958 100644 --- a/recipes/rust.toml +++ b/recipes/rust.toml @@ -56,6 +56,23 @@ flags = [] # el mismo defecto y no podría compilar ni una receta del corpus que use `derive`. build = ["llvm21", "cmake", "samurai", "python3", "pkgconf", "curl", "openssl-threads"] +# ⚠⚠ `lld = true` EN EL `[rust]` DE ARRIBA NO SE PUEDE, y lo dice el propio bootstrap en una línea: +# +# Cannot enable LLD with `rust.lld = true` when using external llvm-config. +# +# O sea: que el toolchain se construya su propio `rust-lld` está CERRADO mientras usemos el `llvm21` +# del corpus — y usar el nuestro es justamente lo que queremos. Leí el paso `Lld` del bootstrap (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 no se puede garantizar +# que casen. +# +# ⇒ El enlazador entra por el otro lado: `recipes/lld21.toml` construye el MISMO `lld`, del mismo +# `llvm-project`, contra el `llvm21` ya sellado. Se usa con `-C linker-flavor=ld.lld`. +# +# ⚠ Y el comentario va ACÁ y no adentro del heredoc de `bootstrap.toml` a propósito: ese texto es +# parte de la fase, o sea **entrada de hash**. Explicar algo ahí adentro re-sella el compilador +# entero — hora y media de granja por un párrafo. [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 @@ -100,21 +117,6 @@ channel = "stable" codegen-tests = false deny-warnings = false musl-root = "/usr" -# ⚠ SIN ESTO EL COMPILADOR NO PUEDE ENLAZAR, y el primer sellado lo demostró: `rustc hola.rs` en una -# caja sin `cc` daba «linker `lld` not found», y con el `ld` de binutils «cannot find -lgcc». La -# causa estaba en una línea del log que parece informativa —`skipping llvm-tools (…): external -# LLVM`—: al usar un LLVM externo, que es lo que queremos porque `llvm21` es del corpus, x.py se -# salta las herramientas de LLVM y `rust-lld` es una de ellas. El prebuilt oficial sí la trae, y por -# eso el escalón 1 enlazaba y el 2 no. -# -# `lld = true` construye LLD desde el `src/llvm-project/lld` que YA VIENE en el tarball (1,1 G de -# fuente) contra el cmake del LLVM externo — comprobado que `llvm21` publica su -# `lib/cmake/llvm/LLVMConfig.cmake`, que es lo que ese paso necesita, y que NO dispara un build de -# LLVM entero (el paso `Lld` reusa el `llvm-config` externo). Después, `dist.rs` lo copia al sysroot -# como `rust-lld` sólo `if builder.config.lld_enabled`. -# -# ⚠ `llvm21` no servía de repuesto: medido sobre sus 1,6 G, **no publica ningún `lld`**. -lld = true [target.x86_64-alpine-linux-musl] llvm-config = "/usr/bin/llvm-config"