recipes/pipewire.toml:85-88 afirma que quitando la dep de ncurses «meson saltea pw-top
y el resto construye». ES FALSO, y llevaba así desde al menos el 2026-08-29. Quitar la
dep no desactivó nada: el guardián de upstream es `if ncurses_dep.found()` y meson lo
encontró igual, en el sysroot Alpine DEL LAB. pw-top se construye, se sella y sale con
NEEDED libncursesw.so.6, que ningún artefacto del cierre publica porque el ncurses del
catálogo es --without-shared. Una herramienta rota dentro de las CUATRO imágenes,
invisible para el store porque el lab no entra en hash_inputs.
LA LECCIÓN, que es más grande que pw-top: QUITAR UNA DEP DE [deps] NO APAGA LA FUNCIÓN.
Cambia de dónde sale. Para apagarla de verdad hay que decírselo a la perilla del
proyecto; si no la hay, la dep tiene que estar declarada y satisfecha desde el store.
POR QUÉ UNA RECETA NUEVA Y NO RE-SELLAR PIPEWIRE. El arreglo limpio es declarar la dep y
reconstruir; cuesta 10 dependientes directos y 7 sellados que caen a deuda, entre ellos
xdg-desktop-portal-cosmic y cosmic-settings-daemon, que son Rust —el portal murió por
OOM tres veces y el que selló tardó 48 min con pico de 5,4 GiB de swap—. No se paga eso
hoy por una herramienta de diagnóstico, y menos con otro agente compilando en la misma
máquina. Lo que cruza acá es un SONAME, y para eso el repo ya tiene regla escrita:
enlazar contra una variante y CORRER contra otra es legítimo cuando lo que cruza es un
SONAME. Cero rebuilds.
⚠ QUEDA DEUDA ANOTADA: pipewire sigue enlazando contra el lab en BUILD. El día que se
re-selle por cualquier otro motivo hay que declarar ncurses-shared en sus [deps] y
corregir el comentario mentiroso. Esto tapa el síntoma en runtime, no la causa.
DOS COSAS QUE COSTARON, y están escritas en la receta:
- `-stats` es un flag de GNU ld que lld rechaza, y viene DENTRO del token
`-Wl,-soname,...,-stats,-lc` que arma el configure de ncurses. No se puede pasar por
LDFLAGS ni hay perilla MK_SHARED_LIB, y el patrón .zwrap de poppler tampoco sirve tal
cual porque filtra argumentos completos y acá hay que reescribir uno.
- Quitando `-stats`, el siguiente en caer es el `-lc` del mismo token. El driver de zig
valida lo que va dentro de `-Wl,` y no deja pasar ninguno de los dos; libc la liga él
solo, así que la cola `,-stats,-lc` se va entera. Se quita del Makefile GENERADO, con
un grep previo que FALLA si el configure deja de emitirlo (para no seguir en silencio).
EVIDENCIA, con control discriminante:
sin ncurses-shared -> Error relocating /lib/libncursesw.so.6: __vfprintf_chk: symbol
not found (símbolo de _FORTIFY_SOURCE de glibc que musl no
tiene: la fuga al lab, reproducida)
con ncurses-shared -> carga y corre; sólo falla en el runtime de PipeWire por no haber
demonio ni plugins SPA en la raíz de prueba
vigia-sonames en los cuatro perfiles: libncursesw.so.6 Y libpanelw.so.6 desaparecen.
Lo que queda son herramientas de build (go, python3, perl) más tres de RUNTIME que NO
son de este cambio y quedan anotadas: spidermonkey pide libgcc_s/libstdc++ en gnome,
libadwaita pide liblzma, y sqlite-shared pide libreadline.
Grafos: 820/820, 999/999, 883/883, 856/856, 833/833.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XB2iEmxeLZgzqNfhWChrLo
100 lines
6.2 KiB
TOML
100 lines
6.2 KiB
TOML
# ncurses-shared 6.5 — la MISMA ncurses de `recipes/ncurses.toml` pero `.so`. Existe por una fuga
|
|
# concreta, y conviene contar cuál porque el modo de fallar es de manual.
|
|
#
|
|
# ══ POR QUÉ HACE FALTA: `pw-top` ENLAZA CONTRA EL LAB DESDE AGOSTO ═════════════════════════════
|
|
# `recipes/pipewire.toml:85-88` dice, textualmente, que quitando la dep de ncurses «meson saltea
|
|
# pw-top y el resto construye». **Es falso, y llevaba así desde al menos el 2026-08-29.** Quitar la
|
|
# dep no desactivó nada: el guardián de upstream es `if ncurses_dep.found()`, y meson lo encontró
|
|
# igual — en el **sysroot Alpine DEL LAB**. Resultado: `pw-top` se construye, se sella, y sale con
|
|
#
|
|
# NEEDED libncursesw.so.6
|
|
#
|
|
# que **ningún artefacto del cierre publica**, porque la ncurses del catálogo es `--without-shared`.
|
|
# O sea una herramienta rota dentro de las CUATRO imágenes, invisible para el store porque el lab no
|
|
# entra en `hash_inputs`. Lo reporta `scripts/vigia-sonames.py` en los cuatro perfiles.
|
|
#
|
|
# **La lección, que es más grande que pw-top: quitar una dep de `[deps]` NO apaga la función.**
|
|
# Cambia de dónde sale. Para apagarla de verdad hay que decírselo a la perilla del proyecto; si no
|
|
# la hay, la dep tiene que estar declarada y satisfecha desde el store.
|
|
#
|
|
# ══ POR QUÉ ESTA RECETA Y NO RE-SELLAR pipewire ════════════════════════════════════════════════
|
|
# El arreglo LIMPIO es declarar la dep en pipewire y reconstruir. Cuesta: `yupana radio pipewire` da
|
|
# **10 dependientes directos y 7 sellados que caen a deuda**, y entre ellos están
|
|
# `xdg-desktop-portal-cosmic` y `cosmic-settings-daemon`, que son Rust —el portal murió por OOM tres
|
|
# veces y el que selló tardó 48 min con un pico de 5,4 GiB de swap—. No se paga eso hoy por una
|
|
# herramienta de diagnóstico, y menos con otro agente compilando en la misma máquina.
|
|
#
|
|
# Lo que cruza acá es un **SONAME**, y para eso el repo ya tiene regla escrita:
|
|
#
|
|
# > Enlazar contra una variante y CORRER contra otra es legítimo cuando lo que cruza es un SONAME
|
|
# > (misma ABI). Lo que no se puede es hidratar dos artefactos distintos en la misma ruta.
|
|
#
|
|
# `libncursesw.so.6` es la misma ABI en 6.5 que en la 6.x de Alpine, y pw-top usa un puñado de
|
|
# llamadas de curses. Poniendo esta receta de raíz en los perfiles, la imagen provee el SONAME y
|
|
# pw-top corre. Cero rebuilds.
|
|
#
|
|
# ⚠ **QUEDA DEUDA, y está anotada a propósito:** pipewire sigue enlazando contra el lab en BUILD.
|
|
# El día que pipewire se re-selle por cualquier otro motivo, hay que declarar `ncurses-shared` en
|
|
# sus `[deps]` y corregir el comentario mentiroso. Esto tapa el síntoma en runtime, no la causa.
|
|
#
|
|
# ══ QUÉ CAMBIA RESPECTO DE LA ESTÁTICA ═════════════════════════════════════════════════════════
|
|
# `--with-shared --without-normal` en vez de `--without-shared --with-normal`. TODO lo demás se deja
|
|
# idéntico —widec, los mismos `--with-fallbacks`, sin ada/tests/debug— para que el terminfo empotrado
|
|
# sea el mismo: `install.libs` no instala la base de terminfo, así que lo único que hace funcionar a
|
|
# un binario curses sin `/usr/share/terminfo` son esos fallbacks compilados adentro.
|
|
# No hay colisión con la estática: los ficheros son `libncursesw.so*` frente a `libncursesw.a`.
|
|
# El `.pc` SÍ se llama igual en las dos ⇒ **no declarar las dos en la misma receta**.
|
|
#
|
|
# ══ ⚠ EL `sed` DEL `-stats`, QUE ES POR QUÉ ESTA RECETA NO ES DE TRES LÍNEAS ════════════════════
|
|
# La regla de link compartido que genera el `configure` de ncurses es, literalmente:
|
|
#
|
|
# -Wl,-soname,`basename $@ .6.5`.6,-stats,-lc
|
|
#
|
|
# y `-stats` es de GNU ld: el lld que trae zig lo rechaza con `error: unsupported linker arg:
|
|
# -stats` y la `.so` no se liga. No se puede pasar por `LDFLAGS` porque no es un argumento suelto,
|
|
# viene DENTRO del token `-Wl,...` que el propio Makefile arma, y `MK_SHARED_LIB` no es una perilla
|
|
# de `configure`. Tampoco sirve el patrón `.zwrap` de poppler tal cual, que filtra argumentos
|
|
# COMPLETOS y acá hay que reescribir uno.
|
|
# Y no es sólo `-stats`: quitándolo, el siguiente en caer es el `-lc` del mismo token
|
|
# (`error: unsupported linker arg: -lc`). El driver de zig valida lo que va dentro de `-Wl,` y no
|
|
# deja pasar ninguno de los dos; libc la liga él solo, así que la cola `,-stats,-lc` se va ENTERA.
|
|
# Se quita del Makefile GENERADO, después de configure: es una sustitución exacta, acotada al
|
|
# fichero que la produce, y no toca el árbol de fuentes (no hay `.patch` que mantener contra
|
|
# upstream). El `grep` de antes es la parte que importa: si algún día el `configure` deja de
|
|
# emitirlo o lo emite distinto, esto falla en vez de seguir en silencio.
|
|
name = "ncurses-shared"
|
|
version = "6.5"
|
|
license = "MIT"
|
|
|
|
[source]
|
|
tarball = "https://ftp.gnu.org/gnu/ncurses/ncurses-6.5.tar.gz"
|
|
sha256 = "136d91bc269a9a5785e5f9e980bc76ab57428f604ce3e5a5a90cebc767971cc6"
|
|
|
|
[build]
|
|
compiler = "zig-cc"
|
|
target = "x86_64-linux-musl"
|
|
link = "dynamic"
|
|
|
|
[build.phases]
|
|
configure = '''
|
|
set -e
|
|
./configure --prefix=/usr --with-shared --without-normal --enable-widec --without-debug --without-ada --without-tests --enable-pc-files --with-pkg-config-libdir=/usr/lib/pkgconfig --with-fallbacks=linux,vt100,vt220,xterm,xterm-256color,screen,tmux,tmux-256color,ansi
|
|
# Ver la cabecera: la cola `,-stats,-lc` del token `-Wl,...` la rechaza el driver de zig entera.
|
|
grep -q ',-stats,-lc' ncurses/Makefile || { echo "ERROR: no aparece ',-stats,-lc' — ¿cambió el configure de ncurses?" >&2; exit 1; }
|
|
find . -name Makefile -exec sed -i 's/,-stats,-lc//g' {} +
|
|
'''
|
|
compile = "make"
|
|
install = '''
|
|
set -e
|
|
make install.libs install.includes DESTDIR=/out
|
|
# La receta EXISTE para publicar este SONAME: si no está, el artefacto no sirve para nada y hay que
|
|
# enterarse acá, no en la imagen.
|
|
test -e /out/usr/lib/libncursesw.so.6 || {
|
|
echo "ERROR: no se generó libncursesw.so.6 — ¿--with-shared no tomó?" >&2
|
|
ls -l /out/usr/lib >&2; exit 1
|
|
}
|
|
'''
|
|
|
|
[deps]
|
|
build = ["binutils"]
|