diff --git a/docs/evidencia/gnome-shell-qemu-2026-09-03-libs-compartidas.png b/docs/evidencia/gnome-shell-qemu-2026-09-03-libs-compartidas.png new file mode 100644 index 00000000..c4cf2509 Binary files /dev/null and b/docs/evidencia/gnome-shell-qemu-2026-09-03-libs-compartidas.png differ diff --git a/scripts/gnome/qemu-desktop-image.sh b/scripts/gnome/qemu-desktop-image.sh index 9e482248..a29ccb40 100755 --- a/scripts/gnome/qemu-desktop-image.sh +++ b/scripts/gnome/qemu-desktop-image.sh @@ -32,7 +32,9 @@ cp -al "$BASE" "$MERGED" cp -al --remove-destination "$GNOME"/. "$MERGED"/ . "$ROOT/scripts/lib/pid1-desde-store.sh" +. "$ROOT/scripts/lib/libs-compartidas-desde-store.sh" inyectar_pid1 "$MERGED" "$BASE" +inyectar_libs_compartidas "$MERGED" echo "==> parcheando mesa software desde $MESA" # El cierre GNOME trae mesa con SÓLO iris_dri.so (Intel real). En QEMU no hay GPU: hace falta diff --git a/scripts/kde/qemu-desktop-image.sh b/scripts/kde/qemu-desktop-image.sh index 98c5dd94..eb87860f 100755 --- a/scripts/kde/qemu-desktop-image.sh +++ b/scripts/kde/qemu-desktop-image.sh @@ -35,7 +35,9 @@ cp -al "$BASE" "$MERGED" cp -al --remove-destination "$KDE"/. "$MERGED"/ . "$ROOT/scripts/lib/pid1-desde-store.sh" +. "$ROOT/scripts/lib/libs-compartidas-desde-store.sh" inyectar_pid1 "$MERGED" "$BASE" +inyectar_libs_compartidas "$MERGED" echo "==> parcheando mesa (software GL) desde $MESA (llvmpipe=$LLVMPIPE)" # el artefacto trae usr/lib/{dri/*swrast*,libEGL,libgbm,libglapi,libGLESv2}; copiamos SIN --remove para diff --git a/scripts/lib/libs-compartidas-desde-store.sh b/scripts/lib/libs-compartidas-desde-store.sh new file mode 100644 index 00000000..d57e42f4 --- /dev/null +++ b/scripts/lib/libs-compartidas-desde-store.sh @@ -0,0 +1,43 @@ +# libs-compartidas-desde-store.sh — helper compartido por los scripts de imagen: poner en el rootfs +# fundido las librerías COMPARTIDAS que el cierre hidratado NO trae, tomándolas de su artefacto +# sellado (`-shared`). +# +# ── POR QUÉ EXISTE ────────────────────────────────────────────────────────────────────────────── +# La receta canónica de libffi/expat/bzip2 es `--disable-shared`: su artefacto publica sólo el `.a`. +# Pero libgobject, libgirepository, libwayland-{client,server}, libp11-kit y libgjs salen con +# `NEEDED`/símbolos `ffi_*`, y mesa entero (iris_dri, swrast_dri, kms_swrast_dri, libEGL, libgbm) +# con `XML_*`. En el HOST eso resuelve contra el sysroot Alpine DEL LAB, así que el artefacto sella, +# el perfil reporta 100% y nadie se entera. En la imagen no hay lab: el loader de musl aborta con +# +# Error relocating /usr/lib/libgobject-2.0.so.0: ffi_call: symbol not found +# +# y el escritorio muere con código 127 antes de pintar. Es el mismo punto ciego que documenta +# `scripts/vigia-sonames.py` («mesa y wayland pidiendo expat y libffi»), visto desde el lado de la +# imagen: el cierre de BUILD no es el cierre de RUNTIME. +# +# El artefacto se elige por `hammer hash` sobre la receta —el de la receta de HOY—, no por el más +# reciente del store: con dos artefactos del mismo paquete conviviendo, la fecha no dice cuál rige. +# Mismo criterio que `pid1-desde-store.sh` y que los inyectores de arje-*-compat. +# +# ABORTA si falta un artefacto. Deliberado: seguir sin él produce una imagen que arranca hasta el +# escritorio y muere ahí, que es el modo de falla que este helper existe para cerrar. +# +# Uso: . scripts/lib/libs-compartidas-desde-store.sh ; inyectar_libs_compartidas "$MERGED" +# Var: LIBS_COMPARTIDAS="libffi-shared expat-shared bzip2-shared" (override de la lista) + +inyectar_libs_compartidas() { + local merged="$1" recetas hash dir n + recetas="${LIBS_COMPARTIDAS:-libffi-shared expat-shared bzip2-shared}" + echo "==> libs compartidas del store (el cierre sólo trae los .a)" + for n in $recetas; do + hash=$(./target/release/hammer --store store hash "recipes/$n.toml" 2>/dev/null | tail -1 | sed 's/^b3://') + dir="store/$hash-$n" + if [ -n "$hash" ] && [ -d "$dir" ]; then + cp -a --remove-destination "$dir"/usr/lib/*.so* "$merged"/usr/lib/ 2>/dev/null || true + echo " ✓ $n $(echo "$hash" | cut -c1-12)" + else + echo " ✗ falta $n sellado en store/ — el escritorio morirá con 'symbol not found'" >&2 + return 1 + fi + done +}