# zathura 2026.07.18 — lector de documentos con teclas de vi, para las cuatro imágenes. # # ══ ⚠ CORRIGE UNA CREENCIA DEL REPO: ESTO NO ESTÁ BLOQUEADO POR GTK3 ═══════════════════════════ # `docs/plan-apps-usuario-final.md` dejaba a zathura como «verificar antes que su cadena sea GTK4 y # no GTK3», porque en Alpine `girara` —su librería de apoyo— era GTK3, y GTK3 está aparcado por # diseño en esta distro. **Upstream VACIÓ girara**: en 2026.07.18 su árbol son siete `.c` de # utilidades y su `meson.build` no menciona GTK ni una vez. Toda la UI se mudó acá adentro, y esto # pide **GTK4 >= 4.12**, que está en el corpus (4.18.6). El muro no existe. Medido, no recordado. # # ══ EL BACKEND ES UNA RECETA APARTE, Y ESO IMPORTA ═════════════════════════════════════════════ # zathura sin plugin ABRE LA VENTANA Y NADA MÁS: los formatos entran por `.so` que carga con # gmodule desde `/usr/lib/zathura`. El de PDF es `zathura-pdf-poppler`, que necesita # `poppler-glib` — y ésa hubo que escribirla, porque la poppler que ya existía va # `-DENABLE_GLIB=OFF` y encima vive en `incoming-kde`. Ver `recipes/poppler-glib.toml`. # `export_dynamic: true` (meson.build:207,221) es lo que hace que el plugin resuelva los símbolos # `zathura_*` contra el EJECUTABLE al hacer dlopen. Ojo con eso y el wrapper de zig: hay una regla # que quita `-static` ante `--export-dynamic`, la misma que documenta `recipes/luajit.toml`. # # ⚠ **NO SE DECLARA EN `escritorio-kde`, y es a propósito.** Esa imagen ya trae `okular`, que # arrastra `incoming-kde/poppler`; las dos popplers instalan `/usr/lib/libpoppler.so.146` y son # artefactos DISTINTOS, así que hidratar las dos pone dos ficheros en la misma ruta y gana el que se # proyecte último — el cuadro de las dos glib. La salida no sería listarla igual, sería jubilar una # de las dos popplers. Está escrito también en `recipes/poppler-glib.toml` y en `targets.toml`. # # ══ OPCIONES TODAS EXPLÍCITAS (las siete nacen `auto`) ═════════════════════════════════════════ # `landlock=enabled` — y no es relleno: es el mismo mecanismo del kernel que usa `harkaq`, la jaula # de este repo, así que el visor entra encajado con la casa. Se comprobó que la cadena da: pide # `linux/landlock.h` **y** el campo `scoped` de `struct landlock_ruleset_attr`, que existe en las # `linux-headers` 6.16.12 del corpus (línea 53 del header). Sin ese campo la perilla se apagaría # sola, que es el modo de fallar que este repo persigue. # `seccomp=disabled` — `libseccomp` sólo vive en `incoming-gnome`; una receta del corpus no alcanza # una cola hermana. Landlock cubre el encierro. # `synctex=disabled` — no hay receta `synctex` (es de TeX Live). # `manpages=disabled` — su target pide `sphinx-build`, que no está en el corpus. # `convert-icon=disabled` — pide `rsvg-convert`, y librsvg vive sólo en `incoming-gnome`. Sólo # genera PNG del icono a cinco tamaños; el SVG se instala igual. # `tests-x11` / `tests-wayland` apagadas: X11 está al tacho y la de wayland pide weston. # # ══ ⚠ `-Dc_link_args` CON LAS PRIVADAS DE gtk4 — EL PATRÓN QUE YA ESTÁ ESCRITO EN EL CORPUS ═════ # La gtk4 del corpus es `libgtk-4.a` y **su `.pc` no declara `Libs.private` en absoluto** (asume # link dinámico contra `libgtk-4.so`). Consecuencia: meson resuelve `dependency('gtk4')` como # `-lgtk-4` a secas y el link muere con # # ld.lld: error: undefined symbol: epoxy_glBindRenderbuffer # >>> referenced by gtkglarea.c ... in archive /usr/lib/libgtk-4.a # # **culpando a zathura cuando lo que falta es propagar epoxy.** `-Dprefer_static=true` NO lo # arregla: no hay `Libs.private` que preferir. Hay que nombrar a mano las privadas que gdk/gsk # enlazan directo, que son las mismas ocho que `recipes/gtk4-hello.toml` ya dejó escritas — # harfbuzz-subset, epoxy, xkbcommon, wayland-client, wayland-egl, libtiff-4, libjpeg y # cairo-script-interpreter. Se hace acá y no arreglando `gtk4.pc` porque re-hashear gtk4 arrastra # **7 dependientes directos, 6 de ellos sellados que caerían a deuda**; mismo criterio que el # wrapper de `ar` de las recetas Cargo: per-receta, no framework. name = "zathura" version = "2026.07.18" license = "Zlib" [source] repo = "https://github.com/pwmt/zathura.git" commit = "4fad4e4d82ac3275632fcbc55386915ff361e404" [build] compiler = "zig-cc" target = "x86_64-linux-musl" # Dinámico: gtk4 y poppler-glib se exponen como `.so`, y el plugin se carga con dlopen. link = "dynamic" flags = [] [build.phases] configure = ''' set -e export PKG_CONFIG_PATH=/usr/lib/pkgconfig export PYTHONPATH=/usr/lib/python3.12/site-packages # Ver la cabecera: gtk4.pc no trae Libs.private, así que las privadas de gdk/gsk se nombran a mano. PRIV="$(pkg-config --libs --static harfbuzz-subset epoxy xkbcommon wayland-client wayland-egl libtiff-4 libjpeg cairo-script-interpreter)" meson setup output --prefix=/usr --buildtype=release \ -Dprefer_static=true \ -Dc_link_args="$PRIV" \ -Dsynctex=disabled -Dseccomp=disabled -Dlandlock=enabled -Dmanpages=disabled \ -Dtests-x11=disabled -Dtests-wayland=disabled -Dconvert-icon=disabled ''' 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" # ⚠ `sqlite` Y `-Dprefer_static=true` ESTÁN ACÁ PORQUE UN VIGÍA CAZÓ UNA FUGA AL LAB ═══════════ # La primera versión selló con `NEEDED libsqlite3.so.0`, un SONAME que **ningún artefacto del # cierre publica** (el `sqlite` del corpus es `.a`): meson había resuelto `dependency('sqlite3')` # contra el **sysroot Alpine DEL LAB**. Artefacto sellado, perfil al 100%, y una imagen que sólo # arranca en una máquina con Alpine debajo. El lab NO entra en `hash_inputs` ⇒ el store no puede # notarlo. Lo encontró `scripts/vigia-sonames.py escritorio-sway`, que existe para exactamente esto. # # **Y declarar la dep NO alcanzó** — vale la pena que quede escrito, porque era la corrección # obvia y es la incompleta. Con `sqlite` en `[deps]` el NEEDED seguía ahí: el `.pc` del corpus le da # a meson un `-lsqlite3` pelado y el linker prefiere la `.so` del lab sobre la `.a` del store. # Lo que lo arregla es `-Dprefer_static=true`, que hace que meson pida los `.pc` en modo estático. # Efecto medido: los NEEDED bajaron de DIEZ a CUATRO —libxkbcommon, las dos de wayland y libc— # y los cuatro los publica el cierre. expat, libffi, zlib, pixman, xxhash y sqlite entraron # estáticos. Las dos cosas hacen falta: sin la dep, meson ni encuentra el `.pc` del corpus. # # ⚠ `glib-shared` Y NO `glib`: una copia ESTÁTICA de GObject acá y otra dentro de # `libpoppler-glib.so` hacen que el plugin de PDF muera con `cannot register existing type 'gchar'` # al hacer dlopen. El porqué largo está en `recipes/poppler-glib.toml`. Las tres recetas de la # cadena —ésta, poppler-glib y el plugin— tienen que declarar la MISMA. # # `.pc Requires` → `[deps].build`. La cadena larga es la de gtk4 (pango, gdk-pixbuf, graphene, # cairo-gobject, libepoxy…), copiada de `recipes/gtk4.toml` porque es exactamente su clausura de # pkg-config. `file` da `libmagic` (detección de tipo de documento), `xxhash` la caché de páginas # renderizadas y `json-glib` la sesión. `gettext-tiny` porque `po/` y el `.desktop` pasan por i18n. [deps] build = [ "meson", "samurai", "python3", "pkgconf", "linux-headers", "gettext-tiny", "girara", "xxhash", "json-glib", "file", "sqlite", "gtk4", "glib-shared", "pcre2-shared", "cairo", "pango", "gdk-pixbuf", "graphene", "libepoxy", "wayland", "wayland-protocols", "libxkbcommon", "libdrm", "mesa", "fontconfig", "harfbuzz", "fribidi", "freetype", "pixman", "expat", "libpng", "libjpeg-turbo", "libtiff", "libffi", "zlib", "zlib-shared", "bzip2-shared", ]