sergio/takana
> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…
gnome-keyring necesita la API VIEJA de gcr, y vte destapó un -c que gana sobre un -E
1# vte 0.80.5 — el widget de terminal de GNOME: el emulador de verdad (parser de secuencias de
2# escape, scrollback, selección) que gnome-console dibuja alrededor. `gnome-console/meson.build:155`
3# la pide como `vte-2.91-gtk4 >= 0.77.0`, sin perilla.
4#
5# ⚠ Esta receta es C++20, no C. Es la primera de la isla de GNOME que lo es a esta escala.
6#
7# ── LAS PERILLAS, y tres de ellas son bloqueantes, no ahorros ───────────────────────────────────
8# -D_b_symbolic_functions=false (default TRUE) → **BLOQUEANTE**. Es `-Bsymbolic`, que el lld de
9# zig no soporta. Ya está documentado en esta misma cola: es uno de los 13 muros que costó
10# `gjs` ([[gnome-introspection-dinamica]]). Dejarlo en su default rompe el link, no degrada.
11# -Dgnutls=false (default TRUE) → **BLOQUEANTE**: `gnutls` no existe en el
12# catálogo. Lo que apaga es el borrado seguro de la memoria del scrollback (`vte_secure_
13# memset`). Vale decirlo: el historial de la terminal se libera sin sobreescribir.
14# -D_systemd=false (default TRUE) → **BLOQUEANTE**: pide `libsystemd`, y acá no hay
15# (ADR 0007). Apaga el registro de cada terminal como scope de systemd, que no tiene sentido
16# sin systemd.
17# -Dgtk3=false → GTK3 aparcado por diseño en este frente. gnome-console pide la
18# variante `-gtk4`, que es la que queda encendida.
19# -Dglade=false → sólo instala el catálogo XML del diseñador Glade, que no está.
20# -Dgir=false / -Dvapi=false / -Ddocs=false → typelib, bindings de Vala y gi-docgen; el consumidor
21# de hoy es C. ⚠ `vapi` NO se puede omitir cuando se apaga `gir`, y el fallo es un ASSERT, no
22# una dep faltante: `bindings/vala/meson.build:17` ⇒ `Assert failed: gir is required for vala
23# support`. Costó la primera corrida de esta receta. Las dos vienen en `true` de fábrica, así
24# que apagar una sola deja el proyecto en un estado que él mismo declara imposible.
25# -Dicu=true / -Dfribidi=true / -Da11y=true → ENCENDIDAS y no es el default por casualidad: icu4c
26# y fribidi ya están selladas. icu da las codificaciones heredadas (un `ssh` a una máquina en
27# latin-1 deja de ser basura) y fribidi el bidireccional (árabe, hebreo). a11y es el árbol de
28# accesibilidad: sin él un lector de pantalla no ve NADA de lo que pasa en la terminal.
29#
30# ── EL `sed` DEL `-nostdlib`: UNA BANDERA DE ENLACE PUESTA EN LAS DE COMPILAR ──────────────────
31# `src/meson.build:594-603` construye `vte-urlencode-cwd` —el ayudante de 100 líneas que codifica el
32# directorio actual para la integración con la shell— con `cpp_args: ['-nostdlib']`. La intención de
33# upstream es no arrastrar la stdlib de C++ al enlazar un binario diminuto, y con gcc/clang de
34# sistema eso es inocuo en la fase de compilar (`-nostdlib` es del enlazador). **Con `zig c++` no lo
35# es**: la bandera le hace omitir también los `-isystem` de libc++, y el fichero muere en su primer
36# `#include`:
37#
38# ../src/urlencode.cc:22:10: fatal error: 'cstdio' file not found
39#
40# Y el resto del proyecto compila: los otros 200 `.cc` pasan sin ruido, así que el log NO se lee
41# como «falta el compilador de C++», se lee como un fichero roto. Costó una corrida.
42# El sed borra esa línea sola (aparece UNA vez en todo el fichero, comprobado). Lo que cambia es que
43# ese ayudante enlaza la libc++ de zig como todo lo demás: unos KB más en un binario de `libexec`.
44#
45# ══ `W_EXITCODE`: UN MACRO DE GLIBC QUE MUSL NO TIENE ══════════════════════════════════════════
46# `src/widget.cc:929` hace `int status = W_EXITCODE(0, SIGKILL);` para fabricar el estado de salida
47# del hijo cuando vte lo mata ella misma. Upstream sabe de dónde sale y lo escribe en el include:
48#
49# src/widget.cc:23 #include <sys/wait.h> // for W_EXITCODE
50#
51# Sólo que **ese macro es de glibc**, no de POSIX: glibc lo define en `sys/wait.h` como
52# `__W_EXITCODE(ret, sig)`, y musl no lo define en ninguna parte. El error —`use of undeclared
53# identifier 'W_EXITCODE'`— es la primera cosa de esta receta que es un problema de la DISTRO y no
54# de nuestras herramientas.
55#
56# El sed añade el fallback justo después del include, con la definición de glibc literal
57# (`((ret) << 8 | (sig))`: el código de salida en el byte alto, la señal en el bajo — el formato que
58# `waitpid` devuelve), guardado por `#ifndef` para que en una libc que sí lo traiga no cambie nada.
59# Y borra el comentario `// for W_EXITCODE` del include, que dejaría de ser cierto.
60#
61# ══ EL MURO DE `minifont.cc`: UN `-c` QUE GANA SOBRE UN `-E` ═══════════════════════════════════
62# Éste costó tres corridas y las dos primeras hipótesis eran falsas, así que va entero.
63#
64# **El síntoma**: `../src/minifont.cc:42:9: error: unknown type name 'gunichar'`, y 30 más iguales,
65# en el paso `[156/232] Compiling C++ object src/preprocessor_0.p/minifont.cc.i`. Los otros ~200
66# `.cc` del proyecto compilan sin ruido, así que se lee como un fuente roto.
67#
68# **Lo que realmente pasa**: ese fichero NO SE COMPILA NUNCA, por diseño de upstream. Sus `#include`
69# están dentro de `#ifndef MINIFONT_COVERAGE` (`minifont.cc:21-36`), y el paso lo invoca justamente
70# con `-DMINIFONT_COVERAGE`. La razón es que `minifont-coverage.py` sólo quiere las etiquetas
71# `case 0x2500 ... 0x257f:` del fuente —de ahí saca qué glifos dibuja vte a mano— y para eso le basta
72# el texto con las directivas resueltas. De ahí `cxx.preprocess()` con `-fdirectives-only`.
73#
74# **Por qué se compila igual**: la regla que meson emite es
75#
76# rule cpp_PREPROCESSOR
77# command = hammer-zig-cxx -E -P -xc++ $ARGS … -o $out -c $in
78# ↑ preprocesar ↑ …y compilar
79#
80# Con gcc o clang de sistema eso es inocuo: su driver resuelve la fase final y `-E` gana sobre `-c`.
81# **El driver de zig hace lo contrario** y compila. Entonces el fichero se analiza de verdad, sin sus
82# includes (que él mismo se salta), y salen 30 tipos desconocidos.
83#
84# **El arreglo, acotado a esta receta**: quitar el `-c` DE ESA REGLA en el `build.ninja`, después del
85# `meson setup`. El rango del sed (`/^rule cpp_PREPROCESSOR$/,/^$/`) no es cosmético: el mismo
86# `-o $out -c $in` aparece en `cpp_COMPILER`, y un reemplazo global dejaría al proyecto entero sin
87# compilar.
88#
89# ⚠ **LA CAUSA NO ES DE VTE NI DE ESTA RECETA: es del wrapper del compilador.** `hammer-zig-cxx`
90# (`crates/takana-build/src/sandbox.rs::write_cc_wrappers`) ya tiene una rama especial para `-E`
91# —la puso el caso de los generadores de util-linux, que morían con un `-mcpu=` vacío—; lo que le
92# falta es, en ESA misma rama, descartar el `-c`. Arreglarlo ahí lo arregla para cualquier proyecto
93# que use `cxx.preprocess()` de meson, que no va a ser el último. No se toca de paso: es
94# infraestructura compartida y hay otro agente trabajando. Queda escrito acá con nombre y línea.
95#
96# ── LOS `-I` EN `cpp_args`: LA REGLA DE PREPROCESADO NO HEREDA LAS DEPS ────────────────────────
97# `src/meson.build:414` llama a `cxx.preprocess()` sobre `minifont.cc` —para que
98# `minifont-coverage.py` saque de ahí la tabla de glifos que vte dibuja a mano— y le pasa
99# `include_directories: [top_inc]` y NADA MÁS: ni `dependencies:`, que meson acepta y upstream no
100# usa. La regla que sale al ninja lo confirma (leída del `build.ninja` real):
101#
102# build src/preprocessor_0.p/minifont.cc.i: cpp_PREPROCESSOR ../src/minifont.cc
103# ARGS = -Isrc/preprocessor_0.p -Isrc -I../src -I. -I.. … -fdirectives-only -DVTE_GTK=4
104# ↑ ni un -I de glib, gtk, cairo…
105#
106# ⇒ el fichero se preprocesa sin ver `<gdk/gdk.h>` ni `<glib.h>`, y el error NO dice «falta un
107# include»: dice `unknown type name 'gunichar'`, `unknown type name 'GList'`, seis veces seguidas,
108# como si el fuente estuviera roto. Los otros ~200 `.cc` del proyecto compilan bien, que es lo que
109# hace el diagnóstico engañoso.
110#
111# La salida es no tocar el `meson.build` de upstream: `-Dcpp_args` SÍ llega a esa regla (se ve el
112# `-Wno-error=date-time` en el ARGS de arriba), así que se le añaden los `-I` de gtk4 pedidos a
113# pkg-config — que arrastra glib, cairo, pango, gdk-pixbuf, graphene y harfbuzz. Son los mismos
114# directorios que los targets normales ya reciben por sus deps: acá se vuelven globales, que es
115# inocuo, en vez de parchear una llamada de un fichero ajeno.
116# ⚠ El `PKG_CONFIG_PATH` va DENTRO del `$(...)`: un prefijo `VAR=x cmd` no está en vigor durante la
117# sustitución de comandos de esa misma línea.
118# ⚠ Y esto NO era lo que rompía `minifont.cc` —ver el bloque de arriba—, pero hacía falta igual: sin
119# los `-I`, el mismo paso fallaba antes con `'gdk/gdk.h' file not found` en cuanto dejó de compilar.
120#
121# ── `fast-float` NO es una dep opcional disfrazada ──────────────────────────────────────────────
122# `meson.build:694` compila una sonda con `#include <fast_float/fast_float.h>`; si falla, cae a un
123# subproyecto **git** que `--wrap-mode=nodownload` no puede traer. Ver `fast-float.toml`, que existe
124# exactamente para que esa sonda pase.
125#
126# ⚠ `lz4-shared` y no `lz4`: vte produce `libvte-2.91-gtk4.so` y el `liblz4.a` canónico no es PIC
127# (76 reubicaciones `R_X86_64_32` fuera de `.debug`). Que sean pocas no lo salva — una sola rompe
128# el link.
129#
130# ⚠ SIN `sed` del `ar`: medido, `po/ar.po` de este tarball tiene CERO `msgstr[5]` ⇒ el msgfmt de
131# gettext-tiny no se atraganta y no hay por qué perder la traducción.
132name = "vte"
133version = "0.80.5"
134license = "LGPL-3.0-or-later"
135
136[source]
137tarball = "https://download.gnome.org/sources/vte/0.80/vte-0.80.5.tar.xz"
138sha256 = "58a4e00ab5d4a95b4be4dc57b48308deafd72d6839dbbd076648fa353321cc41"
139
140[build]
141compiler = "zig-cc"
142target = "x86_64-linux-musl"
143link = "dynamic"
144
145[build.phases]
146configure = '''sed -i "/^ '-nostdlib',$/d" src/meson.build && sed -i 's@#include <sys/wait.h> // for W_EXITCODE@#include <sys/wait.h>\n#ifndef W_EXITCODE\n#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))\n#endif@' src/widget.cc && 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 -D_b_symbolic_functions=false -Dgtk3=false -Dgtk4=true -Dgnutls=false -Dglade=false -Dgir=false -Dvapi=false -Ddocs=false -D_systemd=false -Dicu=true -Dfribidi=true -Da11y=true -Dc_args=-Wno-error=date-time -Dcpp_args="-Wno-error=date-time $(PKG_CONFIG_PATH=/usr/lib/pkgconfig pkg-config --cflags-only-I gtk4)" && sed -i '/^rule cpp_PREPROCESSOR$/,/^$/ s/ -c [$]in/ $in/' output/build.ninja'''
147compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
148install = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild"
149
150[deps]
151build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "fast-float", "glib", "gtk4", "pango", "cairo-shared", "gdk-pixbuf", "graphene", "pcre2", "lz4-shared", "icu4c", "fribidi", "harfbuzz", "fontconfig-shared", "freetype-shared", "pixman", "libpng-shared", "expat", "libjpeg-turbo-shared", "libtiff-shared", "libepoxy", "wayland", "wayland-protocols", "libxkbcommon", "libdrm", "mesa", "libffi", "zlib-shared"]