From 741a5d767c52fcc05b7526fb20b78413a76b9a4b Mon Sep 17 00:00:00 2001 From: Sergio Date: Sun, 13 Sep 2026 01:15:40 +0000 Subject: [PATCH] =?UTF-8?q?receta:=20bluez=20est=C3=A1tico=20de=20verdad?= =?UTF-8?q?=20=E2=80=94=20el=20audit=20del=20cron=20vuelve=20a=20verde?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bluez b3:6036ab1585ce2af12e7596edd16709d1baa906f8c0ca816aed44957a038fbd66 11/11 ejecutables `statically linked` · `bluetoothctl: 5.87` corre · 31 ficheros (no se perdió nada) El sello de ayer decía `static` y salía con los ONCE ejecutables dinámicos; el audit del cron lo marcó esa misma noche (docs/state/static-audit.txt, 2026-09-12T21:04Z) y dejó el veredicto global en rojo: 715 honestas y las dos nuevas mintiendo. Acá se puede ser estático de verdad —el artefacto NO trae ningún plugin .so, o sea que nadie hace dlopen (a diferencia de cmus)— así que el arreglo es el arreglo, no una re-declaración. Dos mitades, y la segunda no se ve venir: 1. `LDFLAGS=-all-static` en compile **Y** en install: bluez enlaza con libtool, que lee el `-static` del lab como «preferí los .a de libtool» y además RELINKEA al instalar. 2. `LIBS=-lncursesw`. Con -all-static el enlace de bluetoothctl corta con `undefined symbol: tgoto ... in archive /usr/lib/libreadline.a`: readline usa termcap y su readline.pc lo declara en `Requires.private: ncurses`, que **sólo se expande con `pkg-config --static`**. El configure de bluez busca readline con AC_CHECK_LIB, no con pkg-config ⇒ la transitiva nunca entra. En dinámico no se nota: la resuelve el loader. Y se QUITA el `runtime = ["readline-shared"]` que se había añadido horas antes: hacía falta mientras bluetoothctl era dinámico, y con el estático pasó a ser la mentira simétrica —declarar una dep que no se usa—. No mueve el hash (las deps de runtime no entran en hash_inputs). --- recipes/bluez.toml | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/recipes/bluez.toml b/recipes/bluez.toml index 7aa337cf..3a5b5dd5 100644 --- a/recipes/bluez.toml +++ b/recipes/bluez.toml @@ -37,8 +37,20 @@ link = "static" [build.phases] configure = './configure --build=$CBUILD --host=$CHOST --prefix=/usr --sysconfdir=/etc --localstatedir=/var --libexecdir=/usr/lib --disable-shared --enable-static --enable-library --enable-threads --disable-systemd --disable-obex --disable-manpages --disable-cups --disable-udev --with-dbusconfdir=/usr/share' -compile = 'make' -install = 'make DESTDIR=/out install' +# ⚠ `LDFLAGS=-all-static` EN COMPILE **Y** EN INSTALL. bluez enlaza con libtool, y libtool lee el +# `-static` que exporta el lab como «preferí los .a de libtool», no como flag al linker ⇒ el primer +# sello salió con los 11 ejecutables DINÁMICOS y `scripts/static-audit.sh` lo marcó. Lo de *install* +# no es redundancia: **libtool RELINKEA al instalar** y sin el flag ahí devuelve el binario a +# dinámico. Se puede hacer estático porque el artefacto NO trae ningún plugin `.so` —comprobado, +# 0 ficheros— o sea que nadie hace `dlopen` (a diferencia de `cmus`, que por eso va dinámico). +# ⚠ Y `LIBS=-lncursesw`, que es la segunda mitad y no se ve venir. Con `-all-static` el enlace de +# `bluetoothctl` corta con `undefined symbol: tgoto ... in archive /usr/lib/libreadline.a`: readline +# usa termcap y su `readline.pc` lo declara en **`Requires.private: ncurses`**, que sólo se expande +# con `pkg-config --static`. El configure de bluez busca readline con `AC_CHECK_LIB`, no con +# pkg-config ⇒ la transitiva nunca entra. En dinámico no se nota (la resuelve el loader); en +# estático hay que nombrarla. Misma familia que las transitivas del `.pc` de glib en `[deps]`. +compile = 'make LDFLAGS=-all-static LIBS=-lncursesw' +install = 'make LDFLAGS=-all-static LIBS=-lncursesw DESTDIR=/out install' [[service]] label = "bluetoothd" @@ -54,8 +66,9 @@ restart = { initial_ms = 500, max_ms = 20000 } # cairo, appstream y adwaita-hello. `expat` entra por el `.pc` de dbus. [deps] build = ["glib", "dbus", "readline", "ncurses", "pkgconf", "pcre2", "libffi", "zlib", "expat"] -# ⚠ `readline-shared` EN RUNTIME, descubierto corriendo el binario y no auditando la receta: -# `bluetoothctl` sale `NEEDED libreadline.so.8` y la `readline` canónica del corpus es sólo `.a`. -# `bluetoothd` no lo pide (sale con `libc.so` a secas), así que el demonio arrancaría y la -# herramienta con la que se emparejan los dispositivos NO — el peor reparto posible. -runtime = ["readline-shared"] +# (Hubo aquí un `runtime = ["readline-shared"]`, y se quitó el mismo día: hacía falta mientras +# `bluetoothctl` salía DINÁMICO pidiendo `libreadline.so.8`. Con el enlace estático de arriba el +# artefacto no pide ni un soname —los 11 ejecutables salen `statically linked`, comprobado— así que +# esa dep pasó a ser una mentira en la otra dirección: declarar lo que no se usa. Queda la nota +# porque el reparto era el peor posible y conviene recordarlo: `bluetoothd` salía con `libc.so` a +# secas y habría arrancado, y la herramienta con la que se emparejan los dispositivos NO.)