8d1efca26e5e3fc4f3ca626e0479be329f3382fb
11
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8d1efca26e |
gnome: GIRepository-2.0 — el typelib que no pide el shell sino gjs
Con los siete de `dependencies.js` cerrados, el arranque avanzó y murió en uno que NO
está en esa lista:
JS ERROR: Requiring GIRepository, version 2.0: Typelib file ... not found
El que lo pide es **gjs**, desde su propio JavaScript embebido: su GResource trae
literalmente `imports.gi.versions.GIRepository = '2.0';` (verificado con strings sobre
libgjs.so.0). Dep de runtime del INTÉRPRETE — invisible al grafo de build Y a la lista
del shell. O sea que `dependencies.js` es necesario pero no suficiente: hay una capa
más abajo.
HAY DOS GIRepository Y NO SON LO MISMO, y los números confunden a propósito:
· GIRepository-3.0 = la API NUEVA, la que GLib absorbió (libgirepository-2.0). La
produce glib-introspected y ya estaba.
· GIRepository-2.0 = la API VIEJA, la de libgirepository-1.0.so.1, contra la que gjs
está enlazado. La produce gobject-introspection, pero sólo con
-Dbuild_introspection_data=true, y el nuestro va con false.
La 2.0 es la vieja porque nombra la librería 1.0; la 3.0 es la nueva porque nombra la 2.0.
Receta aparte en vez de prenderle la opción a g-i: su radio alcanza toda la cadena GNOME
(catorce recetas la declaran para escanear) y además traería de vuelta los typelibs de
X11/cairo que motivaron apagarla. Acá el radio es cero.
Replica el custom_target('gir-girepository') de upstream (gir/meson.build:494) pero
escaneando contra la libgirepository-1.0 ya instalada. **La lista de fuentes va enumerada
a mano y no como glob**, y no es prolijidad: `girepository/*.h` barre también
`gitypelib-internal.h`, que declara G_TYPELIB_ERROR; el scanner emite entonces el stanza
del error-quark y su binario temporal no linkea, porque `g_typelib_error_quark` es LOCAL
en la .so instalada. Upstream nunca lo escanea — el glob era el error.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
bc4d0c8aea |
gnome: los 7 typelibs CERRADOS — librsvg y ibus, y dos deudas viejas pagadas de paso
Rsvg-2.0 librsvg b3:351f4658 IBus-1.0 ibus b3:d4d3750a **1. PERILLA NUEVA DEL LAB: `[source] cargo_vendor`.** `detect_build_system` asume UN sistema de build por árbol, y librsvg genuinamente tiene dos: `configure.ac` gana por precedencia pero su Makefile llama a `cargo build`, que dentro del sandbox hermético no tiene red. La perilla fuerza el vendoreo (que ocurre en el fetch, donde sí hay red) sin tocar la detección. **No entra al ArtifactHash** —decide de dónde salen las deps, no cuáles: eso lo fija el Cargo.lock, ya bajo el sha256 de la fuente— así que se puede prender en una receta ya sellada sin re-hashear nada. Con test, y verificado en vivo: libelogind no movió su hash tras el cambio. **2. LA DEUDA DEL UNWINDER, PAGADA.** librsvg moría en `undefined reference: _Unwind_DeleteException`. No es de librsvg: es de la `std` de rustc, que trae landing pads y espera el runtime que en glibc vive en libgcc_s. Es la deuda que el corpus arrastra desde matar-gcc —«las 12 recetas Rust son UN problema, no 12»— y el remedio estaba a mano: **zig empaqueta la libunwind de LLVM** y exporta los `_Unwind_*` (verificado con nm). Alcanza `LIBS=-lunwind`. Va por LIBS y no por LDFLAGS porque autotools pone LIBS al FINAL de la línea de enlace, que es donde tiene que ir una librería que resuelve símbolos indefinidos. librsvg va en 2.58.5 y no 2.59+: en 2.59 cambió a meson + cargo-c, y cargo-cbuild enlaza el crate `cargo` entero (libgit2, libssh2, libcurl, openssl) — una campaña propia por un binario que sólo corre en el constructor. 2.58.5 produce el mismo Rsvg-2.0. Mismo criterio que gnome-desktop 44.5. **3. `x11-compose-data`, y es una tensión que vale la pena tener escrita.** ibus COMPILA la tabla de teclas muertas de X11 dentro de libibus (Makefile.am:310, incondicional, sin `--disable-`). Sin datos no construye. Los datos viven en el tarball de libX11 por historia, no por necesidad técnica: son 5192 líneas de reglas. La receta extrae SÓLO los ficheros de locale reproduciendo la regla de upstream (`cpprules.in`: cpp crudo + CPP_SED_MAGIC literal) y no compila una línea de X11. Un escritorio Wayland-only sigue necesitando la tabla de composición del mundo Unix. Gotchas de ibus, los tres medidos: su ayuda MIENTE (`--enable-gtk4`/`--enable-wayland` sugieren default apagado; el default es `yes`); `--disable-emoji-dict` NO apaga `--disable-unicode-dict`; y con `--disable-wayland` el build muere igual porque `tools/main.c` llama wl_display_* sin `#ifdef` mientras WAYLAND_LIBS sólo se agrega si la opción está prendida — bug de upstream en su propia configuración sin Wayland. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
fd9f9dff6d |
gnome: libgdm (b3:46fac484) + cairo-1.0.typelib — la capa JS avanza dos muros más
Dos rondas del mismo patrón, las dos destapadas ARRANCANDO: 1. `Requiring Gdk 4.0: Typelib 'cairo' 1.0 not found` ⇒ cairo-1.0 sumado a gi-foreign-typelibs. Necesita el mismo sed que gi-foreign-girs (viene como .gir.in con dos placeholders), para compilar EXACTAMENTE el XML que está instalado: si divergieran, el typelib describiría otra librería. NO segfaultea g-ir-compiler — el crash que motivó -Dbuild_introspection_data=false era del g-i de antes de la isla dinámica. La lista de cinco no se adivinó: sale de leer los <include> de TODOS los .gir del cierre y cruzarlos contra los typelibs existentes. 2. `Requiring Gdm 1.0` ⇒ receta `libgdm`, SÓLO la librería cliente. gnome-shell la importa sin condicional (js/misc/dependencies.js:12), o sea que **la librería cliente de GDM es dep de runtime del SHELL, no del greeter** — y eso no se ve en ningún meson.build. `gdm.toml` (el demonio entero) sigue aparcada por linux-pam, pero PAM es del DEMONIO: libgdm/ no lo toca. La receta corta por ahí; cuando exista linux-pam las dos conviven. Para que libgdm compilara hicieron falta tres símbolos más en libelogind (tawasuyu 9bf977a52, re-pineado a 98db584fd, re-sellado b3:c1fc4bd8): sd_seat_get_sessions, sd_session_get_service y **sd_booted**, éste en una cabecera nueva systemd/sd-daemon.h. sd_booted NO es un stub que devuelve 0: comprueba lo mismo que systemd —que exista /run/systemd/system/— y bajo arje no está, así que responde 0 porque ES 0. gnome-shell re-sellado b3:b2d5919b por la cascada. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
a98267468c |
gnome: gi-foreign-typelibs (b3:a159373c) — un .gir NO es un typelib
Con accountsservice adentro, la capa JS avanzó y murió un paso después: JS ERROR: Requiring Atspi, version 2.0: Typelib file for namespace 'DBus', version '1.0' not found `Atspi-2.0.gir` declara `<include name="DBus" version="1.0"/>`. El `DBus-1.0.gir` YA estaba en /usr/share/gir-1.0 (lo pone gi-foreign-girs), pero gjs resuelve en runtime contra el TYPELIB compilado, no contra el XML — el XML le alcanza al scanner, no al cargador. Receta aparte y no un compile agregado a gi-foreign-girs porque `yupana radio` da **17 sellados cayendo a deuda** ahí (catorce recetas la declaran para escanear, mutter y gnome-shell entre ellas). Compilar cuatro typelibs no justifica reconstruir la cima. No se pisan: una instala sólo en gir-1.0 y la otra sólo en girepository-1.0. Mismo criterio que separó udev-pc de libudev-zero. Se compilan CUATRO nombrados explícitamente —DBus-1.0, DBusGLib-1.0, fontconfig-2.0, freetype2-2.0— y no un glob: los .gir de X11 y cairo arrastran includes que no tenemos y son justamente los que hacían SIGSEGV a g-ir-compiler (la razón de nuestro -Dbuild_introspection_data=false). Además: gnome-start lanza accounts-daemon explícito. Su .service de activación está instalado, pero la activación por bus de sistema pasa por dbus-daemon-launch-helper, que acá no es setuid root; correr como root probablemente alcanzaría, pero depender de eso es depender de un accidente. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
08fc1d4b92 |
gnome: accountsservice SELLA (b3:0328b0d0) — cae la frontera de la C-ABI de logind
Los dos huecos que bloqueaban esta receta estaban medidos desde ayer símbolo por
símbolo, y ninguno era de accountsservice. Los dos cerrados:
1. libelogind pasa de 14 a 22 símbolos (tawasuyu 8d892151b, re-pineado a b56aeff46,
re-sellado b3:9650ee06). Los ocho nuevos son los que usa accountsservice, con
`sd_login_monitor_*` implementado sobre inotify en /run/systemd/{sessions,seats,users}.
2. `fgetspent_r` no existe en musl ⇒ accountsservice-fgetspent_r-musl.patch. NO es
sustituir por `fgetspent()` a secas: daemon.c guarda los buffers en un GHashTable
y `fgetspent()` devuelve un struct estático que se reescribe en cada llamada —
todas las entradas de la tabla apuntarían al último usuario leído. El parche copia
el registro al buffer del llamador, y sigue el patrón que el propio accountsservice
ya usa para /etc/passwd (`src/fgetpwent.c` bajo `#ifndef HAVE_FGETPWENT`).
Produce `AccountsService-1.0.typelib`, que es exactamente lo que la capa JS pedía.
De paso, dos cosas que este frente enseñó y quedan horneadas:
- libelogind necesitaba `cargo_vendor_dir` (el `vendor/` de smithay entró a la rama
selfhost con el merge de main; el mismo choque que ya tenía arje-logind-compat).
- `hydrate-gnome.sh` ahora hidrata DOS raíces por defecto. accountsservice no es dep
de build de nadie: es dep de RUNTIME, resuelta por gjs al arrancar. **El cierre de
build no es el cierre de runtime**, y lo que el shell carga por `imports.gi.*` hay
que nombrarlo a mano o no entra al rootfs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
03bdd41b4a |
gnome: el muro de input NO era libudev-zero — el fd de TakeDevice era bloqueante
Tres cambios de diagnóstico en `gnome-start` que, juntos, dieron el veredicto: 1. SONDA DE INPUT antes de lanzar el shell. `libinput list-devices` hace lo mismo que `init_libinput()` de mutter (udev_new + create_context + assign_seat) pero abriendo el devnode por su cuenta. Volvió con rc=0 y los tres dispositivos listados ⇒ **la hipótesis libudev-zero del runbook queda REFUTADA**: la enumeración por /sys funciona. 2. El volcado POR HILO corría DESPUÉS del `kill -ABRT`, o sea sobre un /proc/<pid>/task que ya no existía: salía vacío. Movido antes. Ahí apareció el dato: `tid 201 [Mutter Input Th] wchan=evdev_read syscall=0`. El hilo de input dormido en un `read()` de evdev dentro del kernel. (El core no servía: gdb no desenrolla a través de musl y devuelve `?? ()` para los 11 hilos no principales.) 3. `MUTTER_DEBUG` es una LISTA DE TÓPICOS (g_parse_debug_string sobre meta_debug_keys), no un booleano: con `1` no encendía nada. Ahora `backend,input,kms`, y el tópico `backend` imprime la última línea antes del cuelgue: «Opening and taking control of device file '/dev/input/event0'». Más: ping D-Bus a login1 en el diagnóstico (el daemon respondía: no estaba tildado) y copia de los logs de /tmp —que es tmpfs— a la raíz ext4 para poder sacarlos con debugfs junto al core. La causa está arreglada en tawasuyu (3dd88f582): `TakeDevice` abría sin `O_NONBLOCK`. Receta re-pineada a 2445fa31c y re-sellada b3:7ffa9256. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
8cf9a87dd2 |
arje-logind-compat: repineado al fix (b3:5e4b8e04) — la cadena vuelve a ser reproducible
Los dos arreglos de arje-logind-compat (sesión eager + object path de Session
escapado como systemd) están commiteados y pusheados en tawasuyu, así que la
imagen ya NO corre un binario compilado a mano: corre el artefacto sellado, y se
verificó que da EXACTAMENTE el mismo resultado (mismo `Added virtual monitor
Meta-0` → `Using Wayland display name 'wayland-0'` → mismo muro en el typelib de
AccountsService).
El pin va a la rama selfhost, no a main: esa rama existe para que hammer pueda
construir con --locked de forma hermética (el monorepo gitignora el Cargo.lock).
Estaba MUY atrás — el artefacto viejo ni siquiera tenía el objeto Session que
mutter necesita —, así que se le mergeó main y se regeneró el Cargo.lock, que con
main al día había quedado viejo y habría hecho fallar el --locked.
Y ahí apareció una colisión ya conocida pero no aplicada acá: el monorepo COMMITEA
su propio `vendor/` (`[patch.crates-io] smithay = { path = "vendor/smithay" }`, la
copia parcheada que mirada usa para el tearing) y `cargo vendor` de hammer escribe
en `vendor/` por defecto, pisándolo. El build moría con
`failed to read /src/vendor/smithay/.cargo-checksum.json`. Se resuelve con el
campo que ya existía para esto: cargo_vendor_dir = ".hammer-cargo-vendor".
De paso, el script de imagen elige el artefacto por `hammer hash` sobre la receta
—el que corresponde a la receta de HOY— en vez de por el más reciente del store:
con dos artefactos del mismo paquete conviviendo, la fecha no dice cuál es el
vigente. Mismo criterio que hydrate-gnome.sh.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
f56bab72f5 |
gnome: el compositor SUBE ENTERO en headless — el muro DRM es libinput, y aparece accountsservice
Experimento decisivo: `gnome-shell --headless --virtual-monitor 1280x800`. El
backend headless crea el seat con META_SEAT_NATIVE_FLAG_NO_LIBINPUT, o sea que
saltea init_libinput() — justo el último paso del hilo de input antes de señalar
`input_thread_initialized` (meta-seat-impl.c:3098). Resultado:
libmutter-Message: Added virtual monitor Meta-0
libmutter-Message: Using Wayland display name 'wayland-0'
== compositor OK (wayland-0) — el shell ES el display server
⇒ **CONFIRMADO: el bloqueo del camino DRM está en libinput/udev, no en el resto
del arranque.** Todo lo demás de mutter funciona. Primer sospechoso libudev-zero.
Y con el compositor arriba aparece el muro siguiente, que es de otra naturaleza:
Gjs-CRITICAL: JS ERROR: Requiring AccountsService, version 1.0:
Typelib file for namespace 'AccountsService' not found
LA LECCIÓN DE MÉTODO: gnome-shell selló con su cierre de build COMPLETO (108/108)
y aun así la sesión muere pidiendo este typelib. **El cierre de build no es el
cierre de runtime**: todo lo que el shell carga por `imports.gi.*` desde
JavaScript es invisible al grafo de deps. Se encuentra ARRANCANDO, no compilando.
Se autoró recipes/incoming-gnome/accountsservice.toml. El configure pasa entero
—tres seds verificados contra el build real: generate-version.sh (deriva la
versión del nombre del DIRECTORIO, que en el sandbox es /src, y la rama git usa
`date`, o sea no-determinista), la aserción de wtmp (musl no define WTMPX_FILENAME
ni _PATH_WTMPX) y subdir('tests') (arrastra mocklibc, que llama fgetgrent, ausente
en musl)—. Ojo: -Dsystemdsystemunitdir tiene que ser literalmente `no`; con la
cadena vacía el meson interpreta "averiguá el directorio" y aserta pidiendo
systemd.pc.
NO SELLA todavía, y la frontera está contada símbolo por símbolo, no estimada:
· libelogind exporta 14 símbolos (los que pedía mutter) y accountsservice usa
OCHO que faltan: sd_get_sessions, sd_seat_can_multi_session,
sd_session_get_display y los cinco de sd_login_monitor_*. Estos últimos son
la parte con enjundia: no son getters sino una API de NOTIFICACIÓN (un fd
poll-able). Sobre el diseño actual el camino natural es inotify sobre
/run/systemd/{sessions,seats,users}.
· fgetspent_r no existe en musl (extensión glibc de /etc/shadow, usada en
src/daemon.c:265): necesita shim o parche a la variante no-reentrante.
Ninguno de los dos es de accountsservice: son huecos de NUESTRA capa de compat.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
34c7962b29 |
gnome: cae el SIGSEGV — el shell toma DRM master e input; muro nuevo en la hebra de input
Dos bugs REALES de arje-logind-compat, encontrados arrancando la imagen y
arreglados (con test) en el árbol de tawasuyu — todavía LOCALES, sin pushear:
1. La sesión se creaba PEREZOSAMENTE. `ensure_user` sólo corría dentro de un
método del Manager, y `write_login_state` vive adentro. Pero mutter no
empieza por D-Bus: lo primero que hace es sd_pid_get_session(), que
arje-sdlogin-compat resuelve LEYENDO /run/systemd/sessions. Huevo y gallina:
el estado en disco sólo se escribía después de un pedido que sólo ocurre si
el estado ya existe. Ahora se crea al arrancar (eager_session).
2. El object path de la Session estaba MAL ESCAPADO: era `/session/_1`. La
convención de systemd (bus_label_escape) codifica `_<hex>` todo lo que no sea
[A-Za-z0-9] **y también el primer carácter si es dígito** ⇒ el id "1" da
`_31`. Importa porque el cliente calcula el path por su cuenta y NO pregunta:
mutter reimplementa la misma regla en meta-dbus-utils.c. Con `_1` no había
nadie sirviendo ahí, la propiedad `Seat` volvía NULL y mutter —que no
chequea— moría de SIGSEGV en get_seat_proxy. Los objetos User NO usan este
escapado (systemd hardcodea `_<uid>`), así que user_path() queda igual.
Y ARJE_LOGIN_STATE=1 YA EXISTÍA: el comentario del daemon dice literalmente "en
arje (sin systemd) el launcher de sesión lo prende. Default off" — y el launcher
es gnome-start. El puente que escribía /run/systemd/ a mano era reinventar esa
perilla; queda de fallback inerte.
Resultado: el shell ya no crashea. Corre con 12 hilos, /dev/dri/card0 abierto
tres veces y /dev/input/event0 abierto — el TakeDevice de logind funciona y el
compositor tiene DRM master e input. Queda bloqueado en
meta_seat_impl_initable_init (meta-seat-impl.c:3154): espera en un condvar a que
la "Mutter Input Thread" avise que inicializó, y nunca avisa. Hipótesis principal
libudev-zero, que ya dio un episodio idéntico en el frente de la USB nvidia.
El gnome-start ahora le fuerza un core con SIGABRT al proceso colgado: sin gdb en
la imagen es la única forma de ver dónde está parado.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
5295aa35c6 |
gnome: la cima ARRANCA en QEMU — muere en meta_launcher_new, causa localizada
gnome-shell bootea, compila sus esquemas, toma el DRM de virtio-gpu y se declara Wayland display server. Después SIGSEGV. El backtrace del core no deja dudas: #4 g_variant_get (value=0x0, "(s&o)") ← GVariant NULO #5 get_seat_proxy src/backends/meta-launcher.c:407 #6 meta_launcher_new (META_LAUNCHER_FLAG_TAKE_CONTROL) Mutter pide la propiedad `Seat` del objeto **Session** de logind — `(s&o)` es su firma estándar (nombre_del_seat, object_path). arje-logind-compat adquiere org.freedesktop.login1 y sirve el Manager, pero NO expone un objeto Session con esa propiedad ⇒ la lectura devuelve NULL y mutter desreferencia sin chequear. Que mutter no valide es fragilidad suya; el hueco es nuestro. Cinco eslabones hubo que armar antes de llegar a ese muro, ninguno anotado: 1. gschemas.compiled NO se genera con DESTDIR seteado (meson lo dice en el log del build) ⇒ GSettings abortaba en el primer g_settings_new(). 2. GI_TYPELIB_PATH tiene que incluir /usr/lib/gnome-shell: St/Shell/Gvc/Shew se instalan aparte por ser privados del shell. Es el env sin análogo en KDE. 3. /var/run no existía en la base metal; arje-logind-compat busca el bus en la ruta legacy y sin el symlink se iba a "modo idle". 4. La política D-Bus de login1 faltaba (system.conf trae <deny own="*"/> y normalmente la instala systemd). PERTENECE al artefacto de arje: está en el script de imagen sólo para dejar visible qué falta empaquetar. 5. /run/systemd/{sessions,seats,users} vacíos — libelogind resuelve la C-ABI sd-login LEYÉNDOLOS y nadie los escribe (el Announce de arje-logind-compat al bus del fractal falla con "identity mismatch"). gnome-start los escribe A MANO y está MARCADO COMO ANDAMIO. Con ese puente desaparece el "Failed to find any matching session". Gotcha que costó una iteración: `kill -0` TIENE ÉXITO sobre un zombi (el padre no lo cosechó todavía), así que el script reportaba "sin wayland-0 tras 45s" cuando el shell había muerto en el primer segundo. Mirando State: de /proc/<pid>/status sale el código real, 139. Todo el ciclo (hidratar → imagen → bootear → sacar el core con debugfs → gdb) y la lista de lo que falta quedan en docs/runbooks/gnome-qemu-desktop.md. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
f6734d6ce6 |
gnome: hydrate-gnome.sh — el cierre de runtime de la cima CIERRA 108/108
Proyecta al FHS el cierre de una receta GNOME desde artefactos SELLADOS, sin
rebuild. Resultado sobre gnome-shell: **108 recetas, 0 faltantes** — 614
binarios, 455 .so, 49 typelibs.
Diferencia con scripts/kde/hydrate-from-store.sh, y por qué importa: aquél
resuelve el cierre desde un index.json de repo y elige el artefacto por MTIME con
un CUTOFF. Eso es una heurística — si dos artefactos del mismo paquete conviven
en el store, la fecha no dice cuál corresponde a la receta VIGENTE. Acá el cierre
sale del GRAFO REAL de recetas (deps.build, resolución hermano→padre, la misma
que usa hammer) y el artefacto se elige por `hammer hash`. Cero ambigüedad, y si
falta algo el reporte dice qué receta y con qué hash lo buscaba.
Auditado además el cierre DINÁMICO del rootfs (452 ELF, 104 librerías NEEDED).
Sin resolver quedan cuatro, y sólo dos son hallazgos:
libc.so 359 consumidores — es el propio musl (en musl el loader
ES libc); lo aporta la base metal, no es hueco.
libc.musl-x86_64.so.1 17 artefactos (nss + spidermonkey) piden ESTE soname en
vez de libc.so. Es la MISMA libc: los construidos con el
gcc/clang de Alpine emiten un soname distinto al de
zig-cc. No rompe si el rootfs trae los dos nombres, pero
es una fisura de consistencia a documentar.
libstdc++.so.6 + SÓLO libmozjs-128.so y js128 ⇒ **la sesión GNOME arrastra
libgcc_s.so.1 el runtime C++ de Alpine por la cadena
gnome-shell → libgjs → libmozjs**. Es exactamente la
"última milla" de matar-gcc que se cerró para cmake con
-static-libstdc++ y que spidermonkey no cubrió. Radio
medido: 2 sellados (gjs, gnome-shell). Pendiente, y
conviene en el worker: el compile de mozjs come ~8GB+.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|