From f7aafc9d26c9e99410d97cd41361106340b602b1 Mon Sep 17 00:00:00 2001 From: sergio Date: Fri, 7 Aug 2026 20:48:55 -0400 Subject: [PATCH] =?UTF-8?q?sway=201.10=20SELLADA=20=E2=80=94=20primer=20co?= =?UTF-8?q?mpositor=20Wayland=20ligero=20del=20cat=C3=A1logo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit b3:ae10753a5467f3642464aaad0b1b41135b8c51972091042baf0d09134af46c7e · sway, swaybar, swaymsg y swaynag. Construido en el worker sobre el wlroots 0.18.2 sellado hace un rato (sway 1.10 pide `wlroots-0.18` explícitamente: no es una versión cualquiera, es LA que casa). XWAYLAND SE HEREDA, NO SE PASA. sway no tiene perilla propia: lee las variables del .pc de wlroots (`xcb = wlroots_features['xwayland'] ? dependency('xcb') : null_dep`). Como nuestro wlroots se selló con have_xwayland=false, sway se salta xcb y xcb-icccm solo. Para eso servía haber inspeccionado esas variables al verificar el artefacto anterior. Si algún día se quiere Xwayland, se cambia en wlroots, no acá. TRES COSAS QUE SALIERON AL CONSTRUIR, y ninguna estaba en sway: 1. `json-c` NO DECLARABA NADA y sellaba igual — porque el rootfs del laptop trae cmake y make y el sandbox los tomaba «de prestado». En el worker muere con `cmake: not found` (exit 127, el mismo código que engaña con meson). Una receta que sólo construye en la máquina del autor es una bomba de relojería. Declarados cmake+make+pkgconf; el arreglo es declarar, NUNCA engordar el rootfs del worker. Re-hashea json-c y su único dependiente, que es sway: gratis. Salió a la luz construyendo sway, o sea que el fallo estaba a tres niveles de donde miraba. 2. 45 SÍMBOLOS INDEFINIDOS AL ENLAZAR, todos `XML_*` — expat, y sólo expat (clasificada la lista completa, no adivinado por el primero). sway no usa expat: lo usa `fontconfig`, que en el corpus es estático, y su `.a` trae las llamadas sin resolver. `fontconfig.pc` lo declara en `Requires.private`, que es la línea que pkg-config sólo expande en resolución ESTÁTICA, y meson llama a dependency('cairo') en modo normal. No es un fallo de fontconfig ni de cairo: es donde el modelo de pkg-config y el enlace estático no encajan. Resuelto con `-Dc_link_args=-lexpat`; como los indefinidos eran de UN solo prefijo, se sabe que no falta nada más. 3. `-Dtray=disabled` esquiva la única dep que nos falta de verdad. La bandeja habla sd-bus y sway ofrece tres proveedores (libsystemd | libelogind | basu): no hay systemd por decisión, `basu` no está en el catálogo, y el `libelogind` que sí tenemos NO sirve — es la reimplementación propia de la C-ABI sd-login de arje-compat, no un sd-bus. Misma trampa del nombre que ya mordió con `knighttime`. Traer basu es un ticket aparte y pequeño. Con esto el frente de WMs ligeros deja de ser un hueco: había 0 compositores y ahora hay uno que arranca desde wlroots propio, sin X11 y sin systemd. Co-Authored-By: Claude Opus 5 (1M context) --- recipes/incoming-wlr/sway.toml | 79 ++++++++++++++++++++++++++++++++++ recipes/json-c.toml | 19 ++++++++ 2 files changed, 98 insertions(+) create mode 100644 recipes/incoming-wlr/sway.toml diff --git a/recipes/incoming-wlr/sway.toml b/recipes/incoming-wlr/sway.toml new file mode 100644 index 00000000..083f9ce1 --- /dev/null +++ b/recipes/incoming-wlr/sway.toml @@ -0,0 +1,79 @@ +# sway 1.10 — el primer compositor Wayland ligero del catálogo. Tiling, i3-compatible, y el +# consumidor natural de wlroots 0.18 que se selló justo antes (sway 1.10 pide `wlroots-0.18` +# explícitamente: no es una versión cualquiera, es LA que casa). +# +# ── XWAYLAND: sway NO tiene perilla propia, la HEREDA de wlroots ──────────────────────────────── +# Detalle que ahorra una iteración entera. En `meson.build`: +# xcb = wlroots_features['xwayland'] ? dependency('xcb') : null_dep +# xcb_icccm = wlroots_features['xwayland'] ? dependency('xcb-icccm') : null_dep +# O sea que sway LEE las variables del `.pc` de wlroots y decide. Como nuestro wlroots se selló con +# `have_xwayland=false`, sway se salta xcb y xcb-icccm SOLO, sin que haya que pasarle nada. Para eso +# servían esas variables que se verificaron al inspeccionar el artefacto de wlroots. +# ⇒ Corolario: si algún día se quiere Xwayland, se cambia en wlroots, no acá. +# +# ── `-Dtray=disabled`: lo que esquiva la única dep que NOS FALTA ─────────────────────────────── +# La bandeja de swaybar habla D-Bus por sd-bus, y sway ofrece tres proveedores +# (`sd-bus-provider`: libsystemd | libelogind | basu). No tenemos ninguno **utilizable**: no hay +# systemd por decisión, `basu` no está en el catálogo, y el `libelogind` que sí tenemos NO sirve +# acá — es la reimplementación propia de la C-ABI **sd-login** de arje-compat, no un sd-bus. (Es la +# misma trampa del nombre que ya mordió con `knighttime`: se llama parecido y es otra cosa.) +# ⇒ Con la bandeja apagada, sway no pide sd-bus y la receta cierra hoy. Traer `basu` es un ticket +# aparte y pequeño, para cuando se quiera bandeja de sistema. +# +# ── `-Dman-pages=disabled` ───────────────────────────────────────────────────────────────────── +# `scdoc` SÍ está en el corpus, así que esto se puede prender cuando se quiera; se deja apagado en +# el primer sellado para que la superficie de fallo sea la mínima. Es una decisión de orden, no un +# muro: una distro sí quiere sus man pages. +# +# ── `link = "dynamic"` ───────────────────────────────────────────────────────────────────────── +# Un compositor **dlopea los drivers DRI de mesa en runtime**; estático no sirve. Mismo criterio que +# `mirada-compositor`. +# +# ── `-Dc_link_args=-lexpat`: el `Requires.private` que pkg-config NO propaga ──────────────────── +# Al enlazar salían **45 símbolos indefinidos, todos `XML_*`** — o sea expat, y sólo expat (medido +# clasificando la lista completa, no adivinando por el primero). sway no usa expat: lo usa +# `fontconfig`, que en el corpus es ESTÁTICO, y `libfontconfig.a` trae las llamadas sin resolver. +# +# `fontconfig.pc` lo declara en `Requires.private`, que es justamente la línea que pkg-config sólo +# expande cuando se le pide resolución ESTÁTICA. meson llama a `dependency('cairo')` en modo normal +# ⇒ la línea privada se ignora y `-lexpat` nunca llega al enlazador. No es un fallo de la receta de +# fontconfig ni de cairo: es el punto donde el modelo de pkg-config y el enlace estático no encajan. +# +# El frente GNOME resolvió esto por otro camino: variantes `-shared` (cairo-shared, +# fontconfig-shared…). Acá no sirven porque viven en `incoming-gnome/` y la resolución es +# hermano→padre. Añadir la biblioteca a mano es la solución local, exacta y verificable — y como la +# lista de indefinidos era de UN solo prefijo, se sabe que no falta nada más. +# +# ── deps: otra vez el grafo de `.pc Requires` ────────────────────────────────────────────────── +# La lista es larga y casi toda es CIERRE de los `.pc`, no uso directo de sway: pango exige glib, +# harfbuzz, fribidi, cairo, fontconfig y freetype; cairo exige pixman, freetype, fontconfig, libpng y +# zlib; gdk-pixbuf exige glib, libpng, libjpeg y libtiff; glib exige libffi, pcre2 y zlib. pkgconf +# resuelve el grafo COMPLETO antes de emitir un cflag, así que omitir un nieto da un error que culpa +# al hijo. Ver `wlr-randr`, donde faltaba `libffi` y el mensaje acusaba a `wayland-client`. + +name = "sway" +version = "1.10" +license = "MIT" + +[source] +tarball = "https://github.com/swaywm/sway/releases/download/1.10/sway-1.10.tar.gz" +sha256 = "7472a7f11150212e0bed0bd0af9f591c9caac9f9ea87c35486e475a21f5ce81f" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "dynamic" +zig_version = "0.13.0" + +[build.phases] +configure = "meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Dwerror=false -Dtray=disabled -Dman-pages=disabled -Dgdk-pixbuf=enabled -Ddefault-wallpaper=false -Dc_link_args=-lexpat" +compile = "ninja -C output" +install = "DESTDIR=/out ninja -C output install" + +[deps] +build = ["meson", "samurai", "python3", "pkgconf", "wlroots", "json-c", "pcre2", "wayland", + "wayland-protocols", "libxkbcommon", "cairo", "pango", "gdk-pixbuf", "pixman", + "libevdev", "libinput", "libdrm", "libudev-zero", "seatd", "mesa", "libdisplay-info", + "hwdata", "glib", "harfbuzz", "fribidi", "fontconfig", "freetype", "libpng", + "libjpeg-turbo", "libtiff", "expat", "libffi", "zlib", "mtdev"] +run = ["wlroots", "mesa", "wayland", "libinput", "seatd", "libxkbcommon", "cairo", "pango"] diff --git a/recipes/json-c.toml b/recipes/json-c.toml index a4daa132..e0ae6586 100644 --- a/recipes/json-c.toml +++ b/recipes/json-c.toml @@ -18,3 +18,22 @@ configure = 'cmake -B build -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=/usr compile = 'cmake --build build' install = 'DESTDIR=/out cmake --install build' + +# ── SIN `[deps]` CONSTRUÍA POR ACCIDENTE ──────────────────────────────────────────────────────── +# Esta receta no declaraba NADA, y aun así sellaba — porque el rootfs del laptop trae `cmake` y +# `make` instalados, así que el sandbox los encontraba «de prestado». En el worker, que no los trae, +# muere con `/bin/sh: cmake: not found` y **exit 127**, el mismo código que engaña en el caso de +# meson: se lee como «cmake no está» y lo que falta es DECLARARLO, no instalarlo. +# +# Salió a la luz construyendo `sway`, que depende de json-c: el fallo no estaba en sway ni en la +# receta que se estaba escribiendo, sino en una dep de tercer nivel que llevaba tiempo mintiendo. +# +# ⇒ El arreglo es declarar la herramienta, **NUNCA engordar el rootfs del worker**: engordarlo haría +# que el build dependa de qué hay instalado en una máquina concreta, que es exactamente lo que +# rompe la reproducibilidad. Y una receta que sólo construye en la máquina del autor es una bomba +# de relojería: funciona hasta que alguien más la toca. +# +# `make` va además de `cmake` porque el generador por defecto de cmake en Unix es «Unix Makefiles» +# ⇒ `cmake --build build` invoca `make` por debajo. +[deps] +build = ["cmake", "make", "pkgconf"]