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…
musl-shared: el corpus publica su propio CARGADOR — 23 binarios dejan de ser inertes
1# musl-shared 1.2.5 — variante DINÁMICA de musl: el CARGADOR y `libc.so`.
2#
3# ── POR QUÉ EXISTE ──────────────────────────────────────────────────────────────────────────────
4# El musl canónico (`recipes/musl.toml`) es `--disable-shared`: emite headers, `libc.a` y los
5# `crt*.o`, que es lo que quiere el enlace estático del corpus. Su comentario decía que el artefacto
6# aportaba «el loader, para uso dinámico futuro» — y era FALSO: con `--disable-shared` musl no
7# construye ni `libc.so` ni `ld-musl-x86_64.so.1`. Corregido allá; acá está el loader de verdad.
8#
9# ── EL AGUJERO QUE TAPA, MEDIDO (2026-09-10, SDD 28 §6.4) ───────────────────────────────────────
10# La imagen del `perfil.servidor` traía **23 binarios que no podían correr**:
11#
12# $ python3 -c "print(1)"
13# sh: python3: not found ← y `command -v python3` decía /usr/bin/python3
14#
15# No faltaban: eran ELF DINÁMICOS pidiendo `/lib/ld-musl-x86_64.so.1`, y **ningún artefacto del
16# corpus publicaba ese fichero**. Funcionaban en el hub sólo porque el rootfs Alpine del LAB lo
17# presta (`.dev-fs/alpine/lib/ld-musl-x86_64.so.1`) — la misma fuga de soberanía que documentan
18# `zlib-shared` y `expat-shared`, un piso más abajo, y con el agravante de que el lab NO entra en
19# `hash_inputs`: la dependencia era invisible para el store.
20#
21# Los 23: la suite `binutils` entera (ar as ld nm objcopy objdump ranlib readelf strip addr2line
22# c++filt elfedit gprof size ld.bfd) más `perl`, `python3`, `sqlite3`, `flex` y `nft`. Entre ellos
23# está TODO el instrumental del proyecto, que es Python.
24#
25# ── POR QUÉ UNA VARIANTE Y NO `--enable-shared` EN LA CANÓNICA ──────────────────────────────────
26# `musl` es componente de **Stage 1** (musl + busybox + hammerd + arje-zero) y su `of_tree` es el
27# baseline de `selfhost-verify.sh`. Re-hashearlo obliga a rehacer ese baseline A PROPÓSITO, y eso es
28# su propia unidad de trabajo, no algo que se arrastra de rebote. El patrón `*-shared` deja la
29# canónica intacta: el nombre es DISTINTO, así que conviven en el mismo store y cada consumidor toma
30# la que necesita. Mismo criterio que zlib-shared / expat-shared / ncurses-shared.
31#
32# ⚠ Y no es dep de nadie: medido, `musl` no aparece en el `[deps]` de ninguna receta del corpus
33# (sólo la suya). El enlace estático lo resuelve el musl que trae zig. Por eso esta variante suma
34# sin mover un solo ArtifactHash.
35
36name = "musl-shared"
37version = "1.2.5"
38license = "MIT"
39
40[source]
41tarball = "https://musl.libc.org/releases/musl-1.2.5.tar.gz"
42sha256 = "a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4"
43
44[build]
45# ⚠ `gcc` Y NO `zig-cc`, y es MEDIDO. Con zig cc el `libc.so` sale con 1586 símbolos dinámicos
46# contra los 1654 del musl de Alpine, y los 68 que faltan son EXACTAMENTE los que musl implementa en
47# ensamblador x86_64 —`memset`, `memcpy`, `memmove`, `memcmp`, `strlen` y toda la familia matemática
48# (`ceil floor sqrt fmod exp log sin cos tan fma round trunc`)— más los `__stack_chk_*`.
49#
50# No es que no se compilen: en el `libc.a` del musl canónico están. Lo que pasa es que zig los
51# RESUELVE CON SU PROPIO musl y los deja ocultos — medido: `memset` aparece como
52# `FUNC LOCAL HIDDEN` de tamaño 0, así que no entra en la tabla dinámica. El resultado es un
53# cargador que arranca, empieza a relocar y muere con `memset: symbol not found`, que se lee como
54# "el binario está roto" y no como "a la libc le faltan símbolos".
55compiler = "gcc"
56target = "x86_64-linux-musl"
57link = "dynamic"
58
59[deps]
60build = ["make"]
61
62[build.phases]
63# `--enable-shared` produce `libc.so`; `make install` lo pone en `/usr/lib/libc.so` y crea el
64# cargador en `$syslibdir` (`/lib/ld-musl-x86_64.so.1`), que es literalmente el mismo fichero: en
65# musl el loader Y la libc son el mismo objeto.
66configure = "./configure --prefix=/usr --syslibdir=/lib --enable-shared --disable-static"
67compile = "make -j\"$(nproc)\""
68install = "make DESTDIR=/out install"