Files
Sergio 741a5d767c receta: bluez estático de verdad — el audit del cron vuelve a verde
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).
2026-09-13 01:15:40 +00:00

75 lines
5.2 KiB
TOML

# BlueZ 5.87 — la pila Bluetooth de Linux (`bluetoothd` + `bluetoothctl`). El otro pendiente del
# punto 8 de PUBLICABLE, junto con `cups`.
#
# ── QUÉ ENTRA Y QUÉ NO, Y POR QUÉ ─────────────────────────────────────────────────────────────
# Todas las perillas salen del `configure --help` del tarball PINEADO, no de un APKBUILD ajeno:
#
# --disable-obex obexd (transferencia de ficheros) pide `libical`, y libical existe SÓLO en
# `incoming-gnome`. Una receta del corpus resuelve sibling-first y después el
# catálogo PADRE, **nunca una cola hermana** ⇒ desde acá no se alcanza.
# Encenderlo exigiría promover libical al corpus, que es otra unidad de
# trabajo. Se apaga por declaración para que el configure no la busque y la
# tome del sysroot del lab (el lab NO entra en `hash_inputs`).
# --disable-manpages las man pages se generan con `rst2man` (docutils, Python). No es receta.
# --disable-systemd el init es arje.
# --disable-udev sólo afecta a `hid2hci` y a las reglas; `bluetoothd` no lo necesita.
# --disable-cups el backend de impresión por Bluetooth. `cups` YA es receta del corpus, así
# que esto se puede encender — pero acopla las dos recetas y la primera
# versión de cada una conviene tenerla sellada por separado. Queda anotado
# como lo próximo, no como olvido.
# --disable-shared el lab exporta LDFLAGS=-static: un .so no cierra el enlace.
#
# ⚠ ESTO NO ENCIENDE EL BLUETOOTH DE NADIE. `bluetoothd` necesita el bus de sistema (dbus) vivo y
# el perfil que lo habilite (SDD 30), y el kernel con BT compilado. La receta es la pieza, no la
# capacidad — la distinción que este repo ya pagó con `foot` y con las fuentes.
name = "bluez"
version = "5.87"
license = "GPL-2.0-or-later AND LGPL-2.1-or-later"
[source]
tarball = "https://www.kernel.org/pub/linux/bluetooth/bluez-5.87.tar.xz"
sha256 = "26bdcf2cebd7310c6f598850606b037ef0c515fe6608ebc54d22c50c4c32b35f"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
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'
# ⚠ `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"
id = "01HQAR53D4M2NBV8KZTYXFQA2A"
exec = "/usr/lib/bluetooth/bluetoothd --nodetach"
scope = "system"
restart = { initial_ms = 500, max_ms = 20000 }
# ⚠ `pcre2`/`libffi`/`zlib` NO son caprichos ni deps de bluez: son lo que pide el `.pc` de glib.
# Con `glib` a secas el configure corta con «Package 'libpcre2-8', required by 'glib-2.0', not
# found» — un enlace estático resuelve la cadena ENTERA en el punto de enlace, así que las
# transitivas de pkg-config hay que materializarlas igual. Es el mismo juego de cuatro que declaran
# cairo, appstream y adwaita-hello. `expat` entra por el `.pc` de dbus.
[deps]
build = ["glib", "dbus", "readline", "ncurses", "pkgconf", "pcre2", "libffi", "zlib", "expat"]
# (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.)