dwarves: CONSTRUYE — frontera libdw/musl cerrada
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.
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
2 archivos · +49 −4
- recipes/dwarves.toml +19 −2
- recipes/elfutils-libdw.toml +30 −2
diff --git a/recipes/dwarves.toml b/recipes/dwarves.toml
index 04e2feb8..b2cdd3e4 100644
--- a/recipes/dwarves.toml
+++ b/recipes/dwarves.toml
@@ -40,6 +40,23 @@
# parches de Alpine) que SÓLO dwarves consuma. Es un sub-proyecto de la cola clib, no un
# retoque de flags. sha256 del tarball verificado (fedorapeople 2026-07-17).
+# ── FRENTE libdw/musl, cerrado el 2026-08-27 ───────────────────────────────────────────────────
+# dwarves necesita TRES cosas que musl no da y que el corpus no tenía:
+# · `libdw` + `dwarf.h` → `elfutils-libdw` (variante; la canónica sólo hace libelf porque de ella
+# cuelgan los cuatro kernels y no se le puede mover el hash).
+# · `libargp` → `argp-standalone` (`find_package(argp REQUIRED)` en su CMakeLists).
+# · `libobstack` → `musl-obstack` (`find_package(obstack REQUIRED)`).
+#
+# Los dos `find_package` son REQUIRED y sus `Find*.cmake` hacen `find_library(NAMES argp/obstack)`
+# sobre /usr/lib. En glibc no hacen falta (van dentro de la libc) y por eso el proyecto no los
+# empaqueta; en musl son librerías aparte. Se les pasa la ruta explícita con
+# `-DARGP_LIBRARY=`/`-DOBSTACK_LIBRARY=` para no depender del orden de búsqueda de cmake.
+#
+# `-DCMAKE_C_STANDARD_LIBRARIES='-llzma -lbz2'`: libdw descomprime secciones de debug comprimidas
+# (`.debug_*` en xz/bzip2) y referencia `lzma_code`/`BZ2_bzDecompress`. El `FindDWARF.cmake` de
+# dwarves pone en `DWARF_LIBRARIES` sólo libdw y libelf, así que esas dos no entran por ahí y hay
+# que añadirlas al link de todos los ejecutables. Misma familia de fallo que appstream/cargo-deb.
+#
name = "dwarves"
version = "1.30"
@@ -53,13 +70,13 @@ target = "x86_64-linux-musl"
link = "static"
[deps]
-build = ["busybox", "make", "cmake", "elfutils", "zlib"]
+build = ["busybox", "make", "cmake", "elfutils-libdw", "argp-standalone", "musl-obstack", "zlib", "xz", "bzip2"]
[build.phases]
configure = """
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -D__LIB=lib \
-DBUILD_SHARED_LIBS=OFF -DLIBBPF_EMBEDDED=ON \
- -DCMAKE_C_FLAGS='-O2 -fno-sanitize=undefined'
+ -DARGP_LIBRARY=/usr/lib/libargp.a -DOBSTACK_LIBRARY=/usr/lib/libobstack.a -DCMAKE_C_STANDARD_LIBRARIES='-llzma -lbz2' -DCMAKE_C_FLAGS='-O2 -fno-sanitize=undefined'
"""
compile = "make -C build -j\"$(nproc)\""
install = "make -C build install DESTDIR=/out"
diff --git a/recipes/elfutils-libdw.toml b/recipes/elfutils-libdw.toml
index 27c6221f..6dbecded 100644
--- a/recipes/elfutils-libdw.toml
+++ b/recipes/elfutils-libdw.toml
@@ -147,7 +147,7 @@ CFLAGS="-O2 -g -I$PWD/compat" CPPFLAGS="-I$PWD/compat" LDFLAGS="-L$PWD/compat" \
# `argp_failure`, que usa `libdwfl/argp-std.c`. Esta variante SÍ trae argp de verdad
# (`argp-standalone`), así que se borra el shim para que gane el `/usr/include/argp.h` real —
# `-I$PWD/compat` va primero y si no lo taparía.
-compile = "rm -f compat/argp.h && make -C lib CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libelf libelf.a libelf.so CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libcpu CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C backends CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libebl CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdwelf CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdw libdw.a CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdwfl libdwfl.a CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\""
+compile = "rm -f compat/argp.h && make -C lib CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libelf libelf.a libelf.so CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libcpu CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C backends CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libebl CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdwelf CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdw libdw.a CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdwfl libdwfl.a CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdwfl_stacktrace libdwfl_stacktrace.a CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\""
install = """
mkdir -p /out/usr/lib/pkgconfig /out/usr/include && \
cp -a libelf/libelf.a libelf/libelf.so* /out/usr/lib/ && \
@@ -157,7 +157,35 @@ mkdir -p /out/usr/include/elfutils
cp -a libdw/libdw.a /out/usr/lib/
cp -a libdw/dwarf.h libdw/libdw.h libdw/known-dwarf.h /out/usr/include/
cp -a libdwfl/libdwfl.h /out/usr/include/
-cp -a libdw/libdw.a libdwfl/libdwfl.a /out/usr/lib/
+# libdw.a GORDA: dwarves enlaza sólo `-ldw -lelf` (su FindDWARF.cmake pone
+# DWARF_LIBRARIES = libdw + libelf y nada más), pero libdw necesita libdwfl, libebl, libdwelf,
+# los backends y libeu, que en elfutils son libs INTERNAS. En el .so de una distro van dentro;
+# acá hay que fusionarlas a mano en un solo archive o salen `undefined symbol: dwfl_begin`,
+# `eu_tsearch`, `eu_search_tree_init`… Mismo patrón que la libgtk-4.a gorda de `gtk4`.
+#
+# `error()` va también: es de <error.h> de glibc y musl no lo trae. El compat/error.h de la receta
+# es `static inline`, así que sólo sirve a las TUs que lo incluyen; los objetos que lo referencian
+# desde otra unidad necesitan un símbolo REAL. Se compila uno y se mete en el archive.
+printf '%s\n' '#include <stdio.h>' '#include <stdlib.h>' '#include <stdarg.h>' '#include <string.h>' \
+ 'extern char *program_invocation_short_name;' \
+ 'void error(int s,int e,const char*f,...){va_list a;fflush(stdout);' \
+ ' fprintf(stderr,"%s: ",program_invocation_short_name);va_start(a,f);vfprintf(stderr,f,a);va_end(a);' \
+ ' if(e)fprintf(stderr,": %s",strerror(e));fputc(0x0a,stderr);if(s)exit(s);}' \
+ 'void error_at_line(int s,int e,const char*fn,unsigned ln,const char*f,...){va_list a;fflush(stdout);' \
+ ' fprintf(stderr,"%s:%s:%u: ",program_invocation_short_name,fn,ln);' \
+ ' va_start(a,f);vfprintf(stderr,f,a);va_end(a);if(e)fprintf(stderr,": %s",strerror(e));' \
+ ' fputc(0x0a,stderr);if(s)exit(s);}' > /tmp/error-impl.c
+$CC -c -O2 /tmp/error-impl.c -o /tmp/error-impl.o
+rm -rf /tmp/fat && mkdir -p /tmp/fat && cd /tmp/fat
+for A in $OLDPWD/libdw/libdw.a $OLDPWD/libdwfl/libdwfl.a $OLDPWD/libebl/libebl.a \
+ $OLDPWD/libdwelf/libdwelf.a $OLDPWD/backends/libebl_backends.a $OLDPWD/lib/libeu.a \\
+ $OLDPWD/libdwfl_stacktrace/libdwfl_stacktrace.a; do
+ [ -f "$A" ] || continue
+ n=$(basename "$A" .a); mkdir -p $n && (cd $n && ar x "$A")
+done
+cd $OLDPWD
+ar rcs /out/usr/lib/libdw.a $(find /tmp/fat -name '*.o') /tmp/error-impl.o
+cp -a libdwfl/libdwfl.a /out/usr/lib/
cp -a libdw/libdw.h libdw/known-dwarf.h /out/usr/include/elfutils/
cp -a libdwfl/libdwfl.h /out/usr/include/elfutils/
cp -a version.h /out/usr/include/elfutils/ 2>/dev/null || true