gioser

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…

TOML 1572Shell 203Rust 109Markdown 993728 Definiciones

⎇ main recipes/bluez.toml TOML · 102 líneas · 7.3 KB Historia crudo

bluez + pipewire: bluez5 encendido, y el bluetooth SUENA 271d22804 · Sergio ·

1# BlueZ 5.87 — la pila Bluetooth de Linux (`bluetoothd` + `bluetoothctl`). El otro pendiente del
2# punto 8 de PUBLICABLE, junto con `cups`.
3#
4# ── QUÉ ENTRA Y QUÉ NO, Y POR QUÉ ─────────────────────────────────────────────────────────────
5# Todas las perillas salen del `configure --help` del tarball PINEADO, no de un APKBUILD ajeno:
6#
7#   --disable-obex      obexd (transferencia de ficheros) pide `libical`, y libical existe SÓLO en
8#                       `incoming-gnome`. Una receta del corpus resuelve sibling-first y después el
9#                       catálogo PADRE, **nunca una cola hermana** ⇒ desde acá no se alcanza.
10#                       Encenderlo exigiría promover libical al corpus, que es otra unidad de
11#                       trabajo. Se apaga por declaración para que el configure no la busque y la
12#                       tome del sysroot del lab (el lab NO entra en `hash_inputs`).
13#   --disable-manpages  las man pages se generan con `rst2man` (docutils, Python). No es receta.
14#   --disable-systemd   el init es arje.
15#   --disable-udev      sólo afecta a `hid2hci` y a las reglas; `bluetoothd` no lo necesita.
16#   --disable-cups      el backend de impresión por Bluetooth. `cups` YA es receta del corpus, así
17#                       que esto se puede encender — pero acopla las dos recetas y la primera
18#                       versión de cada una conviene tenerla sellada por separado. Queda anotado
19#                       como lo próximo, no como olvido.
20#   --disable-shared    el lab exporta LDFLAGS=-static: un .so no cierra el enlace.
21#
22# ⚠ ESTO NO ENCIENDE EL BLUETOOTH DE NADIE. `bluetoothd` necesita el bus de sistema (dbus) vivo y
23# el perfil que lo habilite (SDD 30), y el kernel con BT compilado. La receta es la pieza, no la
24# capacidad — la distinción que este repo ya pagó con `foot` y con las fuentes.
25name    = "bluez"
26version = "5.87"
27license = "GPL-2.0-or-later AND LGPL-2.1-or-later"
28
29[source]
30tarball = "https://www.kernel.org/pub/linux/bluetooth/bluez-5.87.tar.xz"
31sha256  = "26bdcf2cebd7310c6f598850606b037ef0c515fe6608ebc54d22c50c4c32b35f"
32
33[build]
34compiler = "zig-cc"
35target   = "x86_64-linux-musl"
36link     = "static"
37
38[build.phases]
39# ⚠ **`--with-pic` + `CFLAGS=-fPIC` desde el 2026-10-21, y NO es cosmético.** `libbluetooth.a`
40# tiene un consumidor nuevo: `libspa-bluez5.so`, el plugin que PipeWire carga con `dlopen` para
41# hablar A2DP. Una `.a` sin PIC no entra en una `.so`, y el enlace de pipewire moría así:
42#     ld.lld: error: relocation R_X86_64_64 cannot be used against local symbol; recompile with -fPIC
43#     >>> defined in /usr/lib/libbluetooth.a(bluetooth.o)
44#     >>> referenced by bluetooth.o:(.rodata.bt_compidtostr+0x4ab8)
45#
46# Se arregla ACÁ y no en el consumidor porque **el radio de bluez es 1** —`pipewire` es su único
47# consumidor, medido— y la regla del repo es que el radio decide de qué lado se toca (igual que
48# `libuv` radio 1 frente a `util-linux` radio 79). Y no añade cascada: pipewire ya se rearma por
49# el `-Dbluez5=enabled`.
50#
51# Hacen falta LOS DOS flags: `--with-pic` solo no basta con `--disable-shared`, porque libtool lo
52# aplica a los objetos de la `.so` que no se construye. Mismo caso que en `sbc`.
53configure = './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 --with-pic CFLAGS="$CFLAGS -fPIC"'
54# ⚠ `LDFLAGS=-all-static` EN COMPILE **Y** EN INSTALL. bluez enlaza con libtool, y libtool lee el
55# `-static` que exporta el lab como «preferí los .a de libtool», no como flag al linker ⇒ el primer
56# sello salió con los 11 ejecutables DINÁMICOS y `scripts/static-audit.sh` lo marcó. Lo de *install*
57# no es redundancia: **libtool RELINKEA al instalar** y sin el flag ahí devuelve el binario a
58# dinámico. Se puede hacer estático porque el artefacto NO trae ningún plugin `.so` —comprobado,
59# 0 ficheros— o sea que nadie hace `dlopen` (a diferencia de `cmus`, que por eso va dinámico).
60# ⚠ Y `LIBS=-lncursesw`, que es la segunda mitad y no se ve venir. Con `-all-static` el enlace de
61# `bluetoothctl` corta con `undefined symbol: tgoto ... in archive /usr/lib/libreadline.a`: readline
62# usa termcap y su `readline.pc` lo declara en **`Requires.private: ncurses`**, que sólo se expande
63# con `pkg-config --static`. El configure de bluez busca readline con `AC_CHECK_LIB`, no con
64# pkg-config ⇒ la transitiva nunca entra. En dinámico no se nota (la resuelve el loader); en
65# estático hay que nombrarla. Misma familia que las transitivas del `.pc` de glib en `[deps]`.
66compile   = 'make LDFLAGS=-all-static LIBS=-lncursesw'
67install = '''
68set -e
69make LDFLAGS=-all-static LIBS=-lncursesw DESTDIR=/out install
70
71# ⚠ GUARDIÁN DE PIC — prueba AUTORITATIVA, no recuento de reubicaciones.
72# Contar `R_X86_64_32/32S` en el `.o` da falsos positivos: las secciones `.debug_*` llevan
73# reubicaciones absolutas SIEMPRE y no se cargan en ejecución (ese control me rechazó un build
74# CORRECTO de `sbc` por 321 de ésas, el mismo día). Lo que importa es si el consumidor puede
75# enlazarla, así que se hace exactamente eso: meter `libbluetooth.a` dentro de una `.so`.
76[ -f /out/usr/lib/libbluetooth.a ] || { echo "bluez: no quedó libbluetooth.a — --enable-library debería publicarla" >&2; exit 1; }
77printf 'extern int bt_bacmp(const void*,const void*);\nint envoltura(const void*a,const void*b){return bt_bacmp(a,b);}\n' > /tmp/bt.c
78/opt/zig/zig cc -mcpu=baseline -shared -fPIC -o /tmp/libbt.so /tmp/bt.c /out/usr/lib/libbluetooth.a 2>/tmp/bt.err \
79  || { echo "bluez: libbluetooth.a NO entra en una .so ⇒ libspa-bluez5.so de PipeWire no podría enlazarla y el bluetooth no sonaría" >&2; tail -8 /tmp/bt.err >&2; exit 1; }
80echo "bluez: libbluetooth.a es PIC (entra en una .so)"
81'''
82
83[[service]]
84label   = "bluetoothd"
85id      = "01HQAR53D4M2NBV8KZTYXFQA2A"
86exec    = "/usr/lib/bluetooth/bluetoothd --nodetach"
87scope   = "system"
88restart = { initial_ms = 500, max_ms = 20000 }
89
90# ⚠ `pcre2`/`libffi`/`zlib` NO son caprichos ni deps de bluez: son lo que pide el `.pc` de glib.
91# Con `glib` a secas el configure corta con «Package 'libpcre2-8', required by 'glib-2.0', not
92# found» — un enlace estático resuelve la cadena ENTERA en el punto de enlace, así que las
93# transitivas de pkg-config hay que materializarlas igual. Es el mismo juego de cuatro que declaran
94# cairo, appstream y adwaita-hello. `expat` entra por el `.pc` de dbus.
95[deps]
96build   = ["glib", "dbus", "readline", "ncurses", "pkgconf", "pcre2", "libffi", "zlib", "expat"]
97# (Hubo aquí un `runtime = ["readline-shared"]`, y se quitó el mismo día: hacía falta mientras
98# `bluetoothctl` salía DINÁMICO pidiendo `libreadline.so.8`. Con el enlace estático de arriba el
99# artefacto no pide ni un soname —los 11 ejecutables salen `statically linked`, comprobado— así que
100# esa dep pasó a ser una mentira en la otra dirección: declarar lo que no se usa. Queda la nota
101# porque el reparto era el peor posible y conviene recordarlo: `bluetoothd` salía con `libc.so` a
102# secas y habría arrancado, y la herramienta con la que se emparejan los dispositivos NO.)