gnome onda 3: 🏔 GNOME-SHELL SELLADO (b3:b6aec8a2) — LA CIMA

/usr/bin/gnome-shell construido desde fuente, con sus cuatro typelibs (St-16,
Shell-16, Gvc-1.0, Shew-0) y el NEEDED cerrando en artefactos sellados + libc.so:
cero fuga al sysroot de Alpine.

El draft estimaba "~10 recetas nuevas, dominadas por eds+icu". Fueron 13, pero
casi ninguna donde el mapa las esperaba. Lo que la última tanda destapó:

  dbus-shared    la cima enlaza atk-bridge-2.0, cuyo .pc Requires atspi-2 y ése
                 dbus-1 — el dbus canónico es estático no-PIC y el configure ni
                 llegaba a compilar. Cuarta variante -shared de la cadena, todas
                 por la misma raíz: el corpus se construyó para un userland
                 ESTÁTICO y el escritorio es dinámico por obligación.

  pulseaudio     la frontera llegó por el camino más indirecto de la campaña:
  + libsndfile   gnome-shell incluye el subproyecto gvc (el control de volumen)
                 SIN condicional (meson.build:256) y gvc pide libpulse duro.
                 Se construye SÓLO EL CLIENTE (-Ddaemon=false): gvc necesita
                 HABLAR el protocolo, no implementarlo, y el demonio de sonido de
                 esta distro es una decisión aparte todavía abierta (PulseAudio vs
                 PipeWire) que construir el daemon habría cerrado de prestado.
                 libsndfile con --disable-external-libs = una receta, no cinco.

Dos parches al árbol, ambos verificados antes de aplicarse:
  · subdir('po') fuera (:324). CUARTA vez que el msgfmt de gettext-tiny aborta
    con SIGABRT, acá en po/ar.po; ya pasó en iso-codes, gcr y eds. La deuda está
    clara: hace falta el gettext de GNU de verdad.
  · los #include <X11/Xlib.h> y <X11/Xatom.h> de src/shell-app-usage.c son
    VESTIGIALES — el fichero no usa un solo símbolo de X11. El código X11 real
    (el tray XEmbed) SÍ está cerrado por have_x11_client, que sale de mutter y
    acá es false. shell-app-usage.c quedó fuera del guard por olvido del upstream.

Y --undefined-version en pulseaudio: usa UN version-script para las tres libs
cliente, así que al enlazar libpulse.so el script nombra símbolos de
libpulse-simple y libpulse-mainloop-glib. GNU ld avisa; lld corta. Mismo flag que
libtiff-shared.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-28 20:46:05 -04:00
co-authored by Claude Opus 5
parent 94f311177b
commit 794d9b595e
4 changed files with 197 additions and 42 deletions
+40
View File
@@ -0,0 +1,40 @@
# dbus-shared 1.16.2 — variante DINÁMICA (libdbus-1.so.3) para la isla dinámica de GNOME.
#
# El dbus canónico (recipes/dbus.toml) es `--prefer-static -Ddefault_library=static` y su
# libdbus-1.a no es PIC. gnome-shell la alcanza por transitividad: enlaza atk-bridge-2.0, cuyo .pc
# declara `Requires: atspi-2` y ése `Requires: dbus-1`, así que pkg-config la arrastra al enlace de
# un binario dinámico. Sin la .so el configure ni siquiera llega a compilar — corta con
# `Package 'dbus-1', required by 'atspi-2', not found` cuando el único dbus visible es estático.
#
# Es la cuarta variante -shared de esta cadena (zlib, sqlite, libxml2, libuuid + ésta) y todas por
# la misma raíz: el corpus se construyó para un userland ESTÁTICO y el escritorio es dinámico por
# obligación, no por gusto — la introspección de GObject exige .so reales.
#
# Se mantienen los apagados del canónico (systemd/x11-autolaunch/docs) y su misma versión: un solo
# dbus en la distro, no dos protocolos conviviendo. -Dtools=true igual que el canónico para que el
# artefacto siga trayendo dbus-daemon/dbus-run-session y pueda levantar un bus de verdad.
name = "dbus-shared"
version = "1.16.2"
[source]
tarball = "https://dbus.freedesktop.org/releases/dbus/dbus-1.16.2.tar.xz"
sha256 = "0ba2a1a4b16afe7bceb2c07e9ce99a8c2c3508e5dec290dbb643384bd6beb7e2"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "dynamic"
flags = []
[build.phases]
configure = "PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release -Ddefault_library=shared -Dsystemd=disabled -Dx11_autolaunch=disabled -Ddoxygen_docs=disabled -Dxml_docs=disabled -Dtools=true -Dsystem_pid_file=/run/dbus/dbus.pid"
compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
install = '''
set -e
PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install --no-rebuild -C output
# can't install tmpfs
rm -rf /out/run
'''
[deps]
build = ["meson", "samurai", "python3", "pkgconf", "expat"]
+57 -42
View File
@@ -1,9 +1,58 @@
# gnome-shell 48.8 — la cima del frente GNOME: la UI del escritorio (top bar, overview, lock screen).
# Cuelga de mutter (compositor) + gjs (su lógica está en JavaScript sobre spidermonkey). meson static.
# sha256 REAL de curl|sha256sum.
# gnome-shell 48.8 — LA CIMA del frente GNOME: la UI del escritorio (barra superior, overview,
# pantalla de bloqueo). Su lógica está en JavaScript sobre gjs/spidermonkey y su compositor es
# mutter; por eso es lo último que cae y por eso toda la onda 3 tuvo que ser una ISLA DINÁMICA —
# el shell lee sus dependencias por typelib, y un typelib exige una .so real que gjs pueda dlopen().
# Ver [[gnome-introspection-dinamica]].
#
# ⚠ DRAFT PARA EL MAPA: NO sella a la primera — es la cima, su cadena es la más profunda. Valor hoy =
# la FRONTERA declarada. Feature-minimal: tests/man/docs off; sin networkmanager (opcional).
# ── LA FRONTERA, YA CERRADA ─────────────────────────────────────────────────────────────────────
# El draft de esta receta estimaba "~10 recetas nuevas, dominadas por eds+icu; es una campaña, no
# una tanda". Fue una campaña, y el presupuesto se movió en las dos direcciones:
# · icu4c NO había que autorarla: ya estaba sellada por KDE y sólo depende de pkgconf+python3,
# o sea del corpus padre, así que copiarla a esta cola dio hash idéntico y cero rebuild.
# · libxml2 para libsoup NO hacía falta (libsoup 3.x la dejó de usar), ni para libical (sólo la
# enlaza un binario de build). Sí para eds, y ahí sí en .so ⇒ libxml2-shared.
# · NSS, en cambio, NO se pudo esquivar: el -DENABLE_SMIME=OFF de eds está roto en 3.56.2 porque
# camel.c incluye nss/nspr sin guardar. Se pagó, y selló a la primera (ver nss.toml).
# Las deps de :71-89 verificadas contra el meson.build real están TODAS selladas hoy:
# atk-bridge-2.0 → at-spi2-core · libecal-2.0 + libedataserver-1.2 → evolution-data-server
# gcr-4 → gcr · polkit-agent-1 → polkit · libxml-2.0 → libxml2-shared · json-glib
# clutter/cogl/mtk/libmutter → mutter · gjs · gtk4 · gnome-desktop-4 · gsettings-desktop-schemas
#
# ── APAGADOS, y la receta que cada uno ahorra ───────────────────────────────────────────────────
# Ojo que acá TODOS los defaults vienen en true (meson.options), así que no apagar es optar por la
# frontera más cara:
# -Dnetworkmanager=false → libnm (NetworkManager entero). Es el applet de red del panel; el
# escritorio arranca sin él. libsecret, la otra dep de esa rama, YA está
# sellada (entró por eds), así que lo único que falta acá es NetworkManager.
# -Dportal_helper=false → el propio meson ERROREA si se deja en true sin networkmanager (:113).
# -Dcamera_monitor=false → libpipewire-0.3. Es el indicador de "cámara en uso"; PipeWire es una
# campaña propia y no la pide nada más de esta onda.
# -Dsystemd=false → libsystemd. Cuarta vez que la C-ABI de logind aparece en este frente y
# cuarta que se esquiva; mutter sigue siendo la única sin salida (por eso
# existe libelogind sobre arje-sdlogin-compat).
# -Dman=false → rst2man (docutils). Mismo motivo que en mutter, donde hubo que sacar
# subdir('doc/man') a mano.
# -Dtests=false -Dgtk_doc=false
# -Dextensions_app=false -Dextensions_tool=false → la app GTK4 de extensiones y su CLI. NO son el
# shell: son herramientas aparte que se instalan al lado. Se dejan fuera de
# la primera pasada para que la cima caiga con la superficie mínima; ambas
# tienen todas sus deps ya selladas, así que encenderlas después es barato.
#
# El segundo sed borra `#include <X11/Xlib.h>` y `<X11/Xatom.h>` de src/shell-app-usage.c. NO es
# una mutilación: son includes VESTIGIALES de la era X11 — el fichero no usa un solo símbolo de X11
# (`grep X11\|XA_\|Display \*\|Atom ` devuelve exactamente esas dos líneas y nada más). El código X11
# de verdad vive en src/tray/ (el tray XEmbed), y ÉSE sí está cerrado por `have_x11_client`, que sale
# de mutter y acá es false porque nuestro mutter es Wayland puro. O sea que shell-app-usage.c es el
# único que quedó fuera del guard, por olvido del upstream.
#
# El primer sed saca `subdir('po')` (:324). CUARTA vez en esta campaña que el msgfmt de gettext-tiny —lo
# único que hay en el corpus— aborta con SIGABRT, acá en po/ar.po; ya pasó en iso-codes, gcr y eds.
# La deuda está clara y anotada: hace falta autorar el gettext de GNU de verdad. Se pierden los
# textos traducidos del shell, no el shell.
#
# ISLA DINÁMICA: link=dynamic y las variantes -shared de la cadena C (cairo/freetype/libpng/
# libjpeg-turbo/libtiff/zlib/fontconfig), igual que gtk4 y mutter. Con las estáticas el linker corta
# con `relocation R_X86_64_32 ... recompile with -fPIC` — es el muro que ya frenó a mutter.
name = "gnome-shell"
version = "48.8"
@@ -14,46 +63,12 @@ sha256 = "cb9b7d86cf362530e648e68caaf109a32af4e832874a26791ca8789773efd233"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "static"
link = "dynamic"
[build.phases]
configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload --prefer-static -Ddefault_library=static -Dtests=false -Dman=false -Ddocumentation=false -Dnetworkmanager=disabled -Dc_args=-Wno-error=date-time"
configure = "sed -i \"/^subdir('po')$/d\" meson.build && sed -i '/^#include <X11\\/X\\(lib\\|atom\\).h>$/d' src/shell-app-usage.c && PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Ddefault_library=shared -Dnetworkmanager=false -Dportal_helper=false -Dcamera_monitor=false -Dsystemd=false -Dman=false -Dtests=false -Dgtk_doc=false -Dextensions_app=false -Dextensions_tool=false -Dc_args=-Wno-error=date-time"
compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
install = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild"
# Resolubles: stack gtk4/libadwaita + gjs (ya en incoming-gnome/) y su cierre .pc.
# FRONTERA (deps REQUERIDAS sin receta alcanzable — la cadena de la cima):
# mutter → YA en incoming-gnome/ (draft); es la dep dura (libmutter).
# gjs → YA en incoming-gnome/ (motor JS del shell).
# gobject-introspection→ YA en incoming-gnome/ (typelibs).
# gsettings-desktop-schemas, gnome-desktop → YA en incoming-gnome/.
#
# ⚠ LISTA CORREGIDA CONTRA EL meson.build REAL (2026-07-28). La de abajo se escribió de memoria y
# tenía dos errores: sobraban `ibus` y `startup-notification` (no aparecen en el meson.build de
# 48.8), y FALTABA la más cara de todas. Las verdaderas, TODAS incondicionales y de nivel superior
# (gnome-shell-48.8/meson.build:71-89):
# atk-bridge-2.0 :71 → at-spi2-core — SIN RECETA. Ojo: la at-spi2-core moderna trae
# ADENTRO el atk que autoramos suelto ⇒ chocan por atk-1.0.pc (ver atk.toml).
# libecal-2.0 :72 ┐ **evolution-data-server** — SIN RECETA, y es la pieza cara: arrastra
# libedataserver-1.2 :73 ┘ libical, libsoup, nss e icu, ninguna en el corpus. Es el calendario
# del panel superior. NO hay opción para apagarlo, y NO es cosa de la
# versión: verificado que 50.3 (la serie más nueva) lo sigue pidiendo
# igual, así que subir de versión no lo esquiva.
# gcr-4 :74 → gcr — SIN RECETA (keyring/prompt; arrastra p11-kit y libgcrypt).
# libxml-2.0 :81 → YA en el corpus, sellada.
# polkit-agent-1 :86 → polkit — SIN RECETA (elevación de privilegios).
# json-glib → CERRADA esta sesión (b3:1b90c876).
# Condicionales (las evitamos): x11/xext/xfixes sólo si mutter trae X11 (no lo trae); libnm+libsecret
# sólo con networkmanager; libpipewire sólo con screencast; libsystemd sólo con la opción systemd.
#
# COSTO REAL DE LA CIMA: ~10 recetas nuevas, dominadas por eds+icu. Es una campaña, no una tanda.
#
# (lista original, conservada para ver en qué se equivocó el mapa de memoria:)
# gcr, libsecret — REQUERIDA (keyring/prompt).
# polkit — REQUERIDA (elevación de privilegios).
# ibus — REQUERIDA (input methods).
# startup-notification — REQUERIDA.
# at-spi2-core, atk — REQUERIDA (accesibilidad).
# json-glib — REQUERIDA.
[deps]
build = ["meson", "samurai", "python3", "pkgconf", "mutter", "gjs", "gobject-introspection", "gsettings-desktop-schemas", "gnome-desktop", "gtk4", "libadwaita", "glib", "pango", "cairo", "graphene", "libepoxy", "wayland", "wayland-protocols", "libdrm", "harfbuzz", "fribidi", "libpng", "pixman", "freetype", "expat", "libffi", "pcre2", "zlib", "gdk-pixbuf", "libjpeg-turbo", "libtiff", "mesa", "fontconfig"]
build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "py3-setuptools", "gi-foreign-girs", "gobject-introspection", "glib", "glib-introspected", "gjs", "mutter", "gtk4", "gnome-desktop", "gsettings-desktop-schemas", "at-spi2-core", "dbus-shared", "gcr", "polkit", "evolution-data-server", "json-glib", "libxml2-shared", "libsecret", "pulseaudio", "libsndfile", "spidermonkey", "graphene", "pango", "gdk-pixbuf", "mesa", "libdrm", "libepoxy", "pixman", "harfbuzz", "fribidi", "wayland", "wayland-protocols", "libinput", "libxkbcommon", "cairo-shared", "libpng-shared", "freetype-shared", "libjpeg-turbo-shared", "libtiff-shared", "fontconfig-shared", "zlib-shared", "expat", "libffi", "pcre2", "sqlite-shared", "libsoup", "libical", "icu4c", "nspr", "nss", "libgcrypt-shared", "libgpg-error-shared", "libuuid-shared", "nghttp2", "libpsl", "p11-kit", "lcms2", "libdisplay-info", "hwdata", "colord", "libgudev", "libudev-zero", "libgusb", "libusb", "libei", "libevdev", "xkeyboard-config", "iso-codes", "libseccomp", "libelogind", "udev-pc", "libxcvt"]
+46
View File
@@ -0,0 +1,46 @@
# libsndfile 1.2.2 — lectura/escritura de ficheros de audio (WAV, AIFF, AU…). Entra al frente GNOME
# por debajo de pulseaudio: `sndfile` es dep INCONDICIONAL de su meson.build:615 (top-level, sin
# `required:` que la ablande), así que ni siquiera `-Ddaemon=false` la esquiva. Cadena de la cima:
# gnome-shell → subprojects/gvc → libpulse → libsndfile.
#
# --disable-external-libs es lo que hace que esta receta sea UNA y no CINCO: por defecto libsndfile
# enlaza FLAC, Ogg y Vorbis, ninguna en el corpus. Apagándolos queda una librería C autocontenida
# que no depende de nada fuera de libc. Lo que se pierde es leer .flac/.ogg; lo que consume el
# escritorio de acá son los sonidos de sistema en WAV, que es el formato nativo de libsndfile.
# --disable-mpeg apaga LAME/mpg123 por lo mismo.
#
# --disable-alsa: ALSA sólo la usa el programa de ejemplo sndfile-play, no la librería.
# --disable-sqlite: sólo la usa la utilidad sndfile-regtest.
# --disable-full-suite: no instala los ~10 binarios de utilería (sndfile-info, sndfile-convert…);
# lo que gvc necesita es libsndfile.so y su .pc.
#
# ISLA DINÁMICA: shared, porque libpulse y todo lo que cuelga de gnome-shell son .so.
name = "libsndfile"
version = "1.2.2"
[source]
tarball = "https://github.com/libsndfile/libsndfile/releases/download/1.2.2/libsndfile-1.2.2.tar.xz"
sha256 = "3799ca9924d3125038880367bf1468e53a1b7e3686a934f098b7e1d286cdb80e"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "dynamic"
[build.phases]
configure = '''
./configure \
--build=$CBUILD --host=$CHOST \
--prefix=/usr \
--enable-shared --disable-static \
--disable-external-libs \
--disable-mpeg \
--disable-alsa \
--disable-sqlite \
--disable-full-suite
'''
compile = 'make -j"$(nproc)"'
install = 'make DESTDIR=/out install'
[deps]
build = ["make", "pkgconf"]
+54
View File
@@ -0,0 +1,54 @@
# pulseaudio 17.0 — pero SÓLO las librerías cliente (libpulse, libpulse-simple,
# libpulse-mainloop-glib). No el demonio de sonido.
#
# POR QUÉ ENTRA: gnome-shell incluye el subproyecto `gvc` (el control de volumen del panel) de forma
# INCONDICIONAL — meson.build:256 lo llama sin `if`, y no hay opción para apagarlo — y gvc pide
# `libpulse` y `libpulse-mainloop-glib` duros (subprojects/gvc/meson.build:58). Es la última
# frontera de la cima y llega por el camino más indirecto de toda la campaña:
# gnome-shell → gvc → libpulse → libsndfile.
#
# ── SÓLO CLIENTE, Y POR QUÉ ESO ES LA DECISIÓN CORRECTA ─────────────────────────────────────────
# -Ddaemon=false -Dclient=true. Lo que gvc necesita es hablar el protocolo de PulseAudio, no
# IMPLEMENTARLO: el demonio de sonido de esta distro es una decisión aparte y todavía abierta
# (PulseAudio vs PipeWire), y construir el demonio acá la cerraría de prestado — además de arrastrar
# alsa-lib, orc, speex, soxr y webrtc-audio-processing. Con sólo el cliente, el shell muestra y
# mueve el volumen contra CUALQUIER servidor que hable el protocolo, incluido pipewire-pulse.
#
# -Dglib=enabled NO es opcional: `libpulse-mainloop-glib` es justamente la integración con el bucle
# de eventos de GLib, y es la segunda de las dos .pc que pide gvc.
#
# sndfile sigue haciendo falta pese a -Ddaemon=false: `dependency('sndfile')` está en el top-level
# del meson.build (:615) sin `required:` que la ablande. De ahí la receta libsndfile de esta cola,
# que con --disable-external-libs queda autocontenida (una receta, no cinco).
#
# -Ddatabase=simple: el default es 'tdb' y arrastraría tdb entero. 'simple' es el backend interno.
# Ni siquiera lo usa el cliente, pero el meson lo evalúa igual.
#
# --undefined-version: PulseAudio usa UN SOLO version-script (map-file) con la etiqueta PULSE_0 para
# las tres librerías cliente, así que al enlazar libpulse.so el script nombra símbolos que viven en
# libpulse-simple (pa_simple_new…) y en libpulse-mainloop-glib (pa_glib_mainloop_new…). GNU ld lo
# tolera con un warning; lld lo trata como ERROR. Mismo flag y mismo motivo que en libtiff-shared.
#
# El resto de los `disabled` son backends del demonio y su ecosistema (alsa, bluez5, jack, avahi,
# lirc, x11, orc, soxr, speex, fftw, openssl, systemd, udev, gtk, gsettings, webrtc-aec, tcpwrap,
# asyncns) — cada uno una receta que no hay que autorar. -Delogind=disabled sigue la misma línea que
# el resto de la onda: la C-ABI de logind se esquiva salvo en mutter.
name = "pulseaudio"
version = "17.0"
[source]
tarball = "https://freedesktop.org/software/pulseaudio/releases/pulseaudio-17.0.tar.xz"
sha256 = "053794d6671a3e397d849e478a80b82a63cb9d8ca296bd35b73317bb5ceb87b5"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "dynamic"
[build.phases]
configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Ddefault_library=shared -Ddaemon=false -Dclient=true -Dglib=enabled -Ddatabase=simple -Ddoxygen=false -Dman=false -Dtests=false -Dgcov=false -Dalsa=disabled -Dasyncns=disabled -Davahi=disabled -Dbluez5=disabled -Ddbus=disabled -Delogind=disabled -Dfftw=disabled -Dgsettings=disabled -Dgtk=disabled -Djack=disabled -Dlirc=disabled -Dopenssl=disabled -Dorc=disabled -Dsamplerate=disabled -Dsoxr=disabled -Dspeex=disabled -Dsystemd=disabled -Dtcpwrap=disabled -Dudev=disabled -Dwebrtc-aec=disabled -Dx11=disabled -Dc_args=-Wno-error=date-time -Dc_link_args=-Wl,--undefined-version"
compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
install = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild"
[deps]
build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "glib", "libsndfile", "libffi", "pcre2", "zlib-shared"]