`unable to find static system library 'bz2'`. La receta no tenía `[deps]`.
Novena de la familia (appstream, cargo-deb, cargo-make, dprint, dufs, fnm,
macchina, maturin).
⚠ Sin verificar a propósito: el build tarda ~60 min (falló a los 3550 s) y el
flock es exclusivo, así que comprobarlo cuesta una hora de campaña parada. El
patrón lleva ocho arreglos idénticos verificados y la campaña lo verifica sola
en la siguiente pasada.
`unable to find static system library 'lzma'`. La receta no tenía `[deps]`.
Octava de la familia (appstream, cargo-deb, cargo-make, dprint, dufs, fnm,
macchina). Verificado: sella, 0 librerías faltantes, binario en /usr/bin.
⚠ Nota de método: verificar ESTA costó ~20 min de campaña parada, porque el
build tarda más que su fallo (1033 s) y el flock es exclusivo. Para el resto de
esta familia —arreglo de UNA línea con el patrón ya verificado 8 veces— sale
más barato commitear y dejar que la campaña lo verifique en su siguiente
pasada.
`unable to find static system library 'sqlite3'`. La receta no tenía `[deps]`:
el lab trae el toolchain de Rust pero no las libs C que los crates `*-sys`
esperan del sistema. `sqlite` está sellada y aporta /usr/lib/libsqlite3.a.
Séptima de la misma familia (appstream, cargo-deb, cargo-make, dprint, dufs,
fnm). Verificado: sella, 0 errores de librería faltante.
El 2026-08-28 `/dev/sda2` llegó al 100% —CERO bytes— porque
`/home/sergio/go/pkg/mod` pasó de 498 MB a 25 G construyendo las recetas Go.
El vigía miraba store/work-sources/CARGO_HOME y no eso, así que no avisó.
Los builds Go morían con `write /home/sergio/go/pkg/mod/cache/download/…: no
space left on device`, que no se lee como un fallo de disco del build porque la
ruta no está en el repo (httpx, hugo, impl…). Y un `/` lleno no rompe una
tanda: rompe la máquina (gitea, caddy).
GOPATH se movió a /mnt/cosecha/gopath por symlink, igual que ~/.cargo. Se añade
al vigía igualmente, para que lo vea si alguien lo devuelve a `/`.
Cadena completa, cuatro recetas nuevas y una modificada:
musl-obstack -> libobstack (find_package(obstack REQUIRED))
argp-standalone -> libargp (find_package(argp REQUIRED))
musl-fts -> fts(3), que usa libdwfl/linux-kernel-modules.c
elfutils-libdw -> libdw + libdwfl (VARIANTE: la canónica sólo hace libelf
porque de ella cuelgan los cuatro kernels)
Lo que costó, en orden de aparición:
· libdw a secas NO necesita argp/obstack/fts — la nota de la canónica es cierta
de libdwfl y src/, no de libdw. El `obstack` de libdw estaba en un COMENTARIO.
· Pero dwarves SÍ usa libdwfl (15 dwfl_* en dwarf_loader.c) ⇒ vuelven argp y fts.
· libdwfl no compila suelto: hay que seguir el orden de SUBDIRS del raíz
(lib → libelf → libcpu → backends → libebl → libdwelf → libdw → libdwfl →
libdwfl_stacktrace).
· El compat/argp.h de la canónica TAPA el argp real y no declara argp_failure.
· libdw.a GORDA: FindDWARF.cmake pone DWARF_LIBRARIES = libdw + libelf y nada
más, pero libdw necesita libdwfl/libebl/libdwelf/backends/libeu, que son libs
internas. Se fusionan en un archive (patrón de la libgtk-4.a) junto con un
`error()` real, que musl no trae y el shim de la receta sólo daba inline.
· Y al final, lzma/bz2: libdw descomprime .debug_* comprimidas.
Verificado de verdad, no por exit code: pahole v1.30 arranca (con el loader
musl del lab) y DECODIFICA DWARF — sobre un binario de prueba imprime los
offsets, los tamaños y hasta el agujero de 3 bytes de padding.
dwarves llama a 15 `dwfl_*` distintas desde dwarf_loader.c, así que libdw sola
no alcanza. libdwfl SÍ arrastra argp (argp-std.c) y fts (linux-kernel-modules.c)
⇒ la receta declara `argp-standalone` y `musl-fts`. Esos objetos casi nunca se
enlazan (dwarves no usa dwfl_standard_argp ni dwfl_linux_kernel_*) pero tienen
que COMPILAR.
Dos cosas que costaron:
· libdwfl no se puede construir suelto: su Makefile lee los .manifest de otros
subdirs. Hay que seguir el orden de SUBDIRS del raíz:
lib → libelf → libcpu → backends → libebl → libdwelf → libdw → libdwfl.
· `rm -f compat/argp.h`: el shim de la canónica es sólo tipos/decls y no declara
`argp_failure`, que usa argp-std.c. Como esta variante trae argp de verdad, hay
que BORRAR el shim para que gane el /usr/include/argp.h real — `-I$PWD/compat`
va primero y si no lo tapa.
Tercera pieza del frente libdw/musl. `libdwfl` de elfutils usa fts en
linux-kernel-modules.c, y dwarves necesita libdwfl.
⚠ Sus símbolos casi nunca se ENLAZAN (dwarves no llama dwfl_linux_kernel_*, así
que ese objeto no sale del archive), pero el fichero tiene que COMPILAR: hace
falta un <fts.h> real con los campos y constantes que usa. Escribir ese header
a mano es fácil de hacer mal en silencio; traer la implementación real es más
honesto.
Se compila a mano como musl-obstack. Gotcha menor: fts.c hace
`#include "config.h"` con COMILLAS (obstack.c lo hace con ÁNGULOS).
Tercera pata del frente libdw/musl, para `dwarves`.
VARIANTE y no tocar `recipes/elfutils.toml`: de la canónica cuelgan los CUATRO
kernels (su tools/objtool enlaza -lelf) y moverle el hash los invalidaría.
Mismo patrón que openssl-threads.
⚠ La canónica avisa que «libdw/libdwfl arrastran argp/obstack/fts, lo
verdaderamente difícil en musl». Es cierto de `libdwfl` y de `src/`, pero NO de
`libdw` a secas, que es lo único que pide dwarves. Verificado sobre el fuente:
· `argp_`/`fts_open` → sólo en libdwfl/, CERO en libdw/.
· `obstack` → en libdw/ aparece UNA vez y es dentro de un COMENTARIO de
libdwP.h: elfutils lleva su propia «simplified thread-local reimplementation
of obstacks» y no incluye <obstack.h> en ningún sitio.
⇒ los stubs de compat/ que ya montaba la receta bastan; libdw compila tal cual.
Verificado: sella y libdw.a exporta 129 símbolos `dwarf_*` reales
(dwarf_begin, dwarf_begin_elf, dwarf_getelf…), más dwarf.h/libdw.h/known-dwarf.h.
Segunda pata del frente libdw/musl: `dwarves` hace `find_package(argp REQUIRED)`
y musl no trae argp. Es lo que Alpine empaqueta como `argp-standalone`.
Se compila a mano (sin autotools, como musl-obstack) y SÓLO los siete
`argp-*.c` que el propio Makefile.am pone en `libargp_a_SOURCES`. Los otros .c
del tarball (mempcpy/strchrnul/strndup/strcasecmp) son LIBOBJS de autoconf —
reemplazos para sistemas que NO los tienen— y musl SÍ los tiene, así que
incluirlos duplicaría símbolos de la libc.
Gotcha: `UNUSED` no es del código, lo define el `acinclude.m4` de autoconf. Sin
él las firmas `char* arg UNUSED` no parsean y salen `expected ')'` y varios
`undeclared identifier 'state'` — errores que parecen del código y son de
config. Va en el config.h a mano.
Primera pieza del frente libdw/musl (para `dwarves`). La necesitan DOS cosas:
`libdw` de elfutils (su libdwP.h mete `struct obstack` en el Dwarf) y el propio
`dwarves`, que hace `find_package(obstack REQUIRED)`. Es lo que Alpine
empaqueta como `musl-obstack`.
Se compila A MANO: el tarball trae Makefile.am pero no un `configure` generado,
y el corpus no tiene autoconf/automake/libtool. Son dos .c.
Dos gotchas resueltos:
· `obstack.c` hace `#include <config.h>` SIN guarda (fuera de _LIBC) ⇒ hay que
fabricarle uno. Lo único que mira es HAVE_LIBINTL_H, que musl no tiene, así
que el config.h mínimo vale.
· Es `<config.h>` con ÁNGULOS, no comillas ⇒ no basta con dejarlo en el cwd,
hace falta `-I.` en el compile.
El nombre importa: dwarves lo busca con `find_library(NAMES obstack)` en
/usr/lib ⇒ instala /usr/lib/libobstack.a y obstack.h.