tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

⎇ main recipes/lld21.toml TOML · 82 lines · 4.9 KB History raw

el enlazador va DENTRO del compilador — `/etc/cargo/config.toml` es una ruta que cargo no lee e903f486d · Sergio ·

1# LLD 21.1.2 — el ENLAZADOR de la distro. Mismo `llvm-project` que `llvm21`, construido aparte.
2#
3# ══ POR QUÉ EXISTE (SDD 31, muro 8) ════════════════════════════════════════════════════════════
4# `rust` desde fuente selló, corre y **no puede enlazar**: en una caja sin `cc` —cualquier takana que
5# no sea un hub— `rustc hola.rs` muere con `linker \`lld\` not found`, y con el `ld` de binutils con
6# `cannot find -lgcc`. La causa está en una línea del log del propio build que parece informativa:
7#
8#     skipping llvm-tools (x86_64-alpine-linux-musl): external LLVM
9#
10# Al usar un LLVM externo —que es lo que queremos, porque `llvm21` es del corpus— x.py se salta las
11# herramientas de LLVM, y `rust-lld` es una de ellas.
12#
13# ⚠ Y la vía obvia está CERRADA por el propio bootstrap, medido: `rust.lld = true` contesta
14# «Cannot enable LLD with `rust.lld = true` when using external llvm-config». La guarda tiene
15# sentido —LLD y LLVM comparten ABI de C++— pero deja una sola salida: construir LLD nosotros.
16#
17# ⚠ Y `llvm21` no servía de repuesto: sobre sus 1,6 G de artefacto **no publica ningún `lld`**
18# (`-DLLVM_ENABLE_PROJECTS=""`). Encenderlo ahí re-hashearía llvm21 y con él `rust`; separado, esto
19# suma sin mover nada.
20#
21# ══ QUÉ CAMBIA FRENTE A llvm21 ═════════════════════════════════════════════════════════════════
22# Se compila SÓLO el subproyecto `lld` (`cmake -S lld`), contra el LLVM ya instalado por la dep:
23# minutos en vez de horas, y nada de volver a compilar los 1,6 G de librerías.
24name    = "lld21"
25version = "21.1.2"
26license = "Apache-2.0 WITH LLVM-exception"
27
28[source]
29# El mismo tarball que `llvm21`, byte por byte: la URL es locator y el sha256 es la identidad
30# (ADR 0013), así que compartir fuente entre dos recetas no cuesta nada.
31tarball = "https://github.com/llvm/llvm-project/releases/download/llvmorg-21.1.2/llvm-project-21.1.2.src.tar.xz"
32sha256  = "1a417d1c8faf8d93e73fec1cbb76d393ed3218974c2283c7bac9672d3d47c54b"
33
34[build]
35compiler = "zig-cc"
36target   = "x86_64-linux-musl"
37# ⚠ `dynamic` NO es una preferencia: con `static` el binario SELLA, arranca y **se muere en cuanto
38# hace algo** (medido 2026-09-16). `ld.lld --version` y `--help` contestan bien; cualquier enlace
39# —incluso uno que sólo debería dar un error, como un fichero de entrada inexistente— termina en
40# SIGSEGV con el banner de LLVM y un «Stack dump:» vacío. La firma es la de los registros estáticos
41# de LLVM: `cl::opt`, `TargetRegistry` y compañía se inicializan desde constructores globales que
42# viven en objetos de las `.a`, y un enlace estático agresivo los DESCARTA por no estar
43# referenciados — lo que funciona es lo que no los necesita (`--version`), y lo que no, revienta.
44# Es la misma familia que `link-static-mentira-libtool`: el flag global de la receta decide cosas
45# que la receta no dice.
46link     = "dynamic"
47strip_debug = true
48
49[deps]
50# `llvm21` NO es un adorno: el build standalone de lld necesita su `lib/cmake/llvm/LLVMConfig.cmake`
51# y sus `.a`. Es la misma dep que el paso `Lld` del bootstrap de rustc habría usado.
52build = ["llvm21", "cmake", "samurai", "python3", "pkgconf", "zlib"]
53
54[build.phases]
55# ⚠ `LLVM_ENABLE_ZLIB` va ENCENDIDO —al revés que en `llvm21`— y lo decidió un error, no el gusto:
56#
57#     lld: error: …/self-contained/crtn.o:(.debug_line) is compressed with ELFCOMPRESS_ZLIB,
58#          but lld is not built with zlib support
59#
60# Los objetos `crt*` que rust trae en su sysroot llevan las secciones de depuración COMPRIMIDAS, así
61# que un enlazador sin zlib no puede ni leerlos. Para `llvm21` apagarlo era gratis; para el
62# ENLAZADOR no lo es.
63#
64# `g++` con los runtimes estáticos, igual que `llvm21` y `cmake`: C++ a escala con zig sigue siendo
65# terreno minado, y además LLD tiene que casar ABI con el LLVM contra el que enlaza — que se
66# construyó exactamente así.
67configure = '''
68CC=gcc CXX='g++ -static-libstdc++ -static-libgcc' \
69cmake -S lld -B build -G Ninja \
70  -DCMAKE_BUILD_TYPE=Release \
71  -DCMAKE_INSTALL_PREFIX=/usr \
72  -DLLVM_DIR=/usr/lib/cmake/llvm \
73  -DLLVM_INCLUDE_TESTS=OFF \
74  -DLLVM_ENABLE_ZSTD=OFF \
75  -DLLVM_ENABLE_LIBXML2=OFF
76'''
77compile = "ninja -C build"
78# ⚠ LOS CINCO `lld` SON EL MISMO BINARIO, Y cmake LOS INSTALA COMO CINCO COPIAS: medido, 5 × 96 M =
79# **478 M de artefacto para 97 M de enlazador**. `lld` despacha por `argv[0]`, así que los cuatro
80# alias son symlinks por diseño de upstream — instalarlos como copias es sólo cómo quedó su cmake.
81# En una caja cuya raíz son 5,8 G, 380 M de duplicado no son un detalle.
82install = "DESTDIR=/out ninja -C build install && cd /out/usr/bin && for f in ld.lld ld64.lld lld-link wasm-ld; do ln -sf lld \"$f\"; done"