# dunst 1.12.2 — el daemon de notificaciones que le faltaba a la imagen de sway. # # ── POR QUÉ EXISTE ESTA RECETA, Y POR QUÉ ACÁ ────────────────────────────────────────────────── # El SDD 26 §6.10 midió perfil por perfil quién ATIENDE `org.freedesktop.Notifications`, que es la # otra mitad de tener `libnotify`: # # escritorio-kde plasma-workspace ✓ completa # escritorio-gnome gnome-shell ✓ completa # escritorio-cosmic cosmic-notifications ✓ completa # escritorio-sway — ✗ MEDIA: nadie atiende # # Con `libnotify` en la imagen y nadie del otro lado, una página que pide notificar no falla: el # navegador manda el mensaje al bus y no lo recoge nadie. Media función, cero errores — la forma que # este proyecto ya se cansó de pagar. # # ── POR QUÉ dunst Y NO mako, QUE ES EL DE LA CASA wlroots ────────────────────────────────────── # Por dos razones medidas, no por gusto: # # 1. **El nombre `mako` YA ESTÁ OCUPADO en el corpus** por el motor de plantillas de Python que usa # Mesa para su codegen. Un `recipes/incoming-wlr/mako.toml` no lo pisaría en el disco —la # resolución es sibling-first— pero el cierre del perfil incluye las herramientas de build, así # que la imagen de sway terminaría con DOS artefactos llamados `mako` peleando por las mismas # rutas al hidratar. Es exactamente la colisión de homónimos que la granja ya nos cobró una vez. # 2. mako habla D-Bus por `sd-bus`, que en musl significa una receta nueva (`basu`). dunst habla por # **GDBus**, o sea `gio-2.0`, que ya está sellado. Cero recetas nuevas de dependencia. # # ── WAYLAND=1 X11=0, Y EL GUARDIÁN QUE LO EXIGE ─────────────────────────────────────────────── # dunst compila los dos backends por defecto y el `config.mk` avisa de la trampa con todas las # letras: «Disable dependency on wayland. This will force dunst to use xwayland». O sea que un build # descuidado sella un binario que en esta distro —Wayland-only, sin GLX y sin Xwayland nativo— NO # PINTA NADA y tampoco falla al arrancar. Por eso el `X11=0` no alcanza como intención: la fase # `install` comprueba en el ELF que `libwayland-client` esté entre los NEEDED y que `libX11` NO # esté. La intención se declara en el flag; el hecho se lee en el binario. # # ── EL FICHERO DE SERVICIO D-BUS ES LA MITAD QUE IMPORTA ────────────────────────────────────── # Sin systemd (`SYSTEMD=0`, que es la postura de la distro) el daemon lo arranca **el bus**: el # `.service` declara `Name=org.freedesktop.Notifications` con su `Exec`, y cualquier app que pida ese # nombre lo levanta sola. Sin ese fichero habría que acordarse de lanzar dunst a mano en la config de # sway, que es justo el tipo de «lo instalé y no anda» que este proyecto trata de no dejar. Se le # quita la línea `SystemdService=`, que acá no puede significar nada, y la fase comprueba que el # nombre bien escrito quedó adentro. # # ── `DUNSTIFY=0`: EL EMISOR QUE TRAE dunst SEGFAULTEA, Y NO ES CULPA DE dunst ───────────────── # Entró primero con `DUNSTIFY=0` —parecía gratis, `libnotify` ya está en el corpus— y el binario # resultante **muere con SIGSEGV hasta en `dunstify --help`**, o sea antes de tocar el bus. Medido en # la jaula: rc=139 en las tres pruebas. # # La causa es el cuadro que este repo ya tiene escrito: **dos GLib en el mismo proceso**. Nuestro # `libnotify.so.4` es COMPARTIDO y arrastra `libgobject/libglib/libgio/libgdk_pixbuf` `.so` # (`readelf -d` lo dice), mientras que dunst y sus clientes de esta cola enlazan la GLib **estática** # del corpus. Un dunstify que mezcla las dos termina con dos copias del sistema de tipos de GObject y # se cae al arrancar. El daemon NO tiene el problema: no toca libnotify. # # Y no se pierde nada, que es lo que hace que ésta sea la salida correcta y no una rendición: el # emisor de la casa es **`notify-send`, que viene DENTRO del artefacto de `libnotify`** y ya está en # las cuatro imágenes, enlazado de forma consistente contra la cadena compartida. Un binario que # segfaultea shipeado en la imagen es peor que no shipearlo. # # ── EL BINARIO PESA 46 MB, Y LA PALANCA NO ESTÁ EN ESTA RECETA ─────────────────────────────── # Anotado porque el reflejo se equivoca dos veces. `config.mk` hardcodea `-g`, así que uno prueba # `EXTRA_CFLAGS=-g0` esperando bajar decenas de megas: medido, 46.296.624 → 45.933.472 bytes, o sea # 0,8%. Y sin embargo la grasa SÍ es depuración — `strip --strip-debug` deja el binario en 7.627.464 # bytes, los mismos con `-g0` y sin él. Son 38 MB de `.debug_*` que vienen de los `.a` de # glib/gio/pango/cairo/gdk-pixbuf, no de compilar dunst. # Por eso acá no se toca: strippear en el enlace sería inventar una política en UNA receta cuando el # corpus entero tiene la misma forma (swaybg 22 MB, fuzzel 10 MB) y ya hay un documento para eso, el # SDD 23. Lo que corresponde es medirlo y dejarlo escrito donde se ve. # # `VERSION` se pasa a mano: el Makefile la saca de `git describe` y cae a un literal si no hay `.git`. # Con el commit pineado las dos ramas son deterministas, pero cuál de las dos corre depende de si el # árbol de fuentes trae `.git` — un detalle del build system que no tiene por qué entrar al binario. name = "dunst" version = "1.12.2" license = "BSD-3-Clause" [source] # Por commit y no por `/archive/.tar.gz`, misma razón que `fuzzel` y `foot`: el tarball lo # genera la forge al vuelo y su sha256 se muere solo cuando GitHub actualiza su git/gzip. # ⚠ El tag `v1.12.2` es anotado; éste es el commit desreferenciado (`v1.12.2^{}`). repo = "https://github.com/dunst-project/dunst.git" commit = "fc78b9f11aa8b63f4d81c96466206a9b63a22f07" [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "dynamic" zig_version = "0.13.0" [build.phases] configure = ''' # ── EL `-lexpat` TIENE QUE IR AL FINAL, Y EL Makefile NO DEJA ──────────────────────────────── # `libfontconfig.a` referencia XML_* y el expat estático hay que darlo DESPUÉS: el linker resuelve # de izquierda a derecha. En las recetas meson de esta cola eso se hace con `-Dc_link_args=-lexpat`, # pero acá manda un Makefile que arma la línea como `${LDFLAGS} = DEFAULT + + LIBS`, # o sea que cualquier `-lexpat` nuestro cae ANTES de fontconfig y no sirve de nada. Sobreescribir # `LIBS` significaría reproducir a mano toda la salida de pkg-config. # La salida es un wrapper de un solo token que agrega la librería al final de CADA invocación —el # mismo truco que usa `recipes/ffmpeg.toml` para sus `--cc/--ar`—. En las compilaciones `-c` el # `-lexpat` sobra y clang lo ignora con un aviso. ZW="$PWD/.zwrap"; mkdir -p "$ZW" printf '#!/bin/sh\nexec %s "$@" -lexpat\n' "$CC" > "$ZW/cc" chmod +x "$ZW/cc" ''' compile = ''' make -j"$(nproc)" CC="$PWD/.zwrap/cc" WAYLAND=1 X11=0 SYSTEMD=0 DUNSTIFY=0 \ PREFIX=/usr SYSCONFDIR=/etc/xdg VERSION="1.12.2" ''' install = ''' make DESTDIR=/out CC="$PWD/.zwrap/cc" WAYLAND=1 X11=0 SYSTEMD=0 DUNSTIFY=0 \ PREFIX=/usr SYSCONFDIR=/etc/xdg VERSION="1.12.2" install # ── GUARDIÁN 1: ¿es el backend de wayland, o quedó el de X11? ──────────────────────────────── # «Compilé con X11=0» es una intención; esto es el hecho. Un dunst con backend X11 en una distro # sin Xwayland arranca, toma el bus y no dibuja nunca. readelf -d /out/usr/bin/dunst | grep -q 'libwayland-client' || { echo "guardián: dunst NO enlaza libwayland-client — el backend wayland no entró" >&2; exit 1; } if readelf -d /out/usr/bin/dunst | grep -q 'libX11'; then echo "guardián: dunst enlaza libX11 — X11=0 no agarró" >&2; exit 1 fi # ── GUARDIÁN 2: el nombre del bus, escrito en el fichero que lo activa ─────────────────────── SVC=/out/usr/share/dbus-1/services/org.knopwob.dunst.service [ -f "$SVC" ] || { echo "guardián: no se instaló el .service de D-Bus — nadie lo activaría" >&2; exit 1; } grep -q '^Name=org.freedesktop.Notifications$' "$SVC" || { echo "guardián: el .service no reclama org.freedesktop.Notifications" >&2; exit 1; } # Sin systemd esa línea no puede significar nada; se va para que el bus no la mire siquiera. sed -i '/^SystemdService=/d' "$SVC" test -x /out/usr/bin/dunstctl || { echo "guardián: falta dunstctl" >&2; exit 1; } # Y que NO se haya colado el emisor roto: si alguien vuelve a poner DUNSTIFY=1 sin leer el porqué # de arriba, esto lo frena acá y no en la pantalla de un usuario. if [ -e /out/usr/bin/dunstify ]; then echo "guardián: se instaló dunstify — segfaultea por las dos GLib; el emisor es notify-send" >&2 exit 1 fi echo "guardián: dunst wayland-only, y el bus lo puede activar por org.freedesktop.Notifications" ''' [deps] build = ["pkgconf", "perl", "wayland", "wayland-protocols", "glib", "pango", "cairo", "gdk-pixbuf", "libnotify", "pixman", "fontconfig", "freetype", "harfbuzz", "fribidi", "libpng", "expat", "libffi", "pcre2", "zlib"] run = ["wayland", "glib", "pango", "cairo", "gdk-pixbuf"]