tawasuyu

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 Sutichaykuna

⎇ 87b6c3020a5285cf1d41ccdf1c8070b53adbcb98 recipes/pamixer.toml TOML · 93 siq'ikuna · 5.5 KB Ñawpa willay ch'uya

reparación: pisé la receta de swayimg de otro agente — y el volumen 487507969 · Sergio ·

1# pamixer 1.6 — subirle y bajarle el volumen desde la línea de comandos.
2#
3# ══ POR QUÉ ENTRA ══════════════════════════════════════════════════════════════════════════════
4# `censo-distro.py` marca «audio de escritorio» **5 de 5 ausente**, con el comentario exacto del
5# problema: «PipeWire suena y no hay con qué subirle el volumen desde una ventana». O sea que la
6# distro reproduce audio y **no tiene ningún control de volumen**: ni gráfico, ni de consola, ni
7# atajo de teclado posible — porque un atajo de teclado llama a un comando, y el comando no existía.
8#
9# `pamixer` es el más pequeño que cierra eso: un binario que sube, baja, silencia y lista fuentes y
10# sumideros. Es lo que un compositor engancha a las teclas de volumen.
11#
12# ══ ⚠ HABLA EL PROTOCOLO DE PULSEAUDIO, Y ACÁ EL SERVIDOR ES PIPEWIRE ══════════════════════════
13# Eso NO es un desajuste: la decisión del repo es PipeWire, y PipeWire expone la capa de
14# compatibilidad de PulseAudio (`pipewire-pulse`). `pamixer` se conecta por ahí, igual que lo hacen
15# `mpv` y el resto del corpus que enlaza `libpulse`.
16#
17# ⇒ **Pero la dependencia de RUNTIME es esa capa, no sólo la biblioteca**: `pamixer` enlazado y sin
18# `pipewire-pulse` corriendo arranca y falla al conectar. Es la figura de «el motor sin su driver»;
19# queda dicho acá porque el síntoma («no se conecta») no nombra la causa.
20#
21# Sus únicas deps son `libpulse` —que ya está— y `cxxopts`, su parser de argumentos, que es una
22# cabecera y entró como `recipes/cxxopts.toml`.
23name    = "pamixer"
24version = "1.6"
25license = "GPL-3.0-or-later"
26
27[source]
28tarball = "https://github.com/cdemoulins/pamixer/archive/refs/tags/1.6/pamixer-1.6.tar.gz"
29sha256  = "8b7199e495dc19b190f8f02ace8782f533266a4bd7c7d3cf6f4cf09b2de13e71"
30
31[build]
32compiler = "zig-cc"
33target   = "x86_64-linux-musl"
34link     = "dynamic"
35flags    = []
36
37[build.phases]
38# `--prefer-static` para que pkg-config entregue los `Requires.private`: el corpus es
39# estático-primero y sin eso el enlace puede no cerrar (lección de `swayimg`, donde
40# `libfontconfig.a` dejaba 11 símbolos de expat sin resolver).
41configure = 'PKG_CONFIG_PATH=/usr/lib/pkgconfig meson setup output --prefix=/usr --buildtype=release --prefer-static'
42compile   = 'meson compile -C output'
43# El guardián comprueba por SÍMBOLO DEFINIDO y no por `NEEDED`: con `--prefer-static` casi nada
44# queda en NEEDED, y pedirlo ahí rechazaría un build correcto — es el error que cometí cinco veces
45# el 20-oct, incluido en esta misma campaña con `swayimg`.
46install = '''
47set -e
48DESTDIR=/out meson install -C output
49[ -x /out/usr/bin/pamixer ] || { echo "pamixer: no quedó el binario — NO sello" >&2; exit 1; }
50definido() {
51  readelf -sW "$1" 2>/dev/null | awk -v s="$2" '$8==s && $7!="UND" {f=1} END{exit !f}'
52}
53# `pa_context_connect` es lo que hace que esto sirva de algo: sin la biblioteca de PulseAudio
54# dentro, el binario existe y no puede hablar con el servidor.
55definido /out/usr/bin/pamixer pa_context_connect || readelf -d /out/usr/bin/pamixer 2>/dev/null | grep -q 'libpulse' || {
56  echo "pamixer: ni símbolo pa_context_connect definido ni NEEDED a libpulse — no podría conectarse al servidor de audio" >&2
57  readelf -d /out/usr/bin/pamixer 2>/dev/null | grep NEEDED >&2
58  exit 1
59}
60# Y que ARRANQUE. Ejecución y truncado separados: el estado de una tubería es el del último comando.
61sal=$(/out/usr/bin/pamixer --help 2>&1) || true
62printf '%s\n' "$sal" | grep -qiE 'usage|--get-volume|--increase' || {
63  echo "pamixer: --help no muestra su uso; el binario no arranca bien" >&2
64  printf '%s\n' "$sal" | head -5 >&2
65  exit 1
66}
67echo "pamixer: binario + libpulse · controla volumen, mute y fuentes"
68'''
69
70[deps]
71# ⚠ `python3` NO es opcional aunque pamixer no lo use: **meson es un script de Python**, y sin él
72# `meson setup` muere con `exit 127` — «comando no encontrado» — que no menciona a python. Está
73# documentado en la memoria del repo (`receta-meson-exige-python3`) y aun así me lo salté acá.
74build = ["meson", "samurai", "pkgconf", "pulseaudio", "cxxopts", "binutils", "python3",
75         # ⚠ **LA CADENA DE PULSEAUDIO BAJA TRES NIVELES, Y YA ESTABA DOCUMENTADA EN ESTE REPO.**
76         # `pamixer` no nombra ninguna de estas, pero el cargador sí:
77         #
78         #     Error loading shared library libsndfile.so.1: No such file or directory
79         #       (needed by /usr/lib/pulseaudio/libpulsecommon-17.0.so)
80         #     Error relocating libpulsecommon-17.0.so: sf_command: symbol not found
81         #
82         # O sea: pamixer → libpulse.so → libpulsecommon.so → **libsndfile.so.1**. Tres saltos, y el
83         # sandbox sólo monta lo DECLARADO, así que hay que nombrarlas aunque pamixer no las
84         # mencione nunca. `glib`, `libffi` y `pcre2` son las deps de runtime de pulseaudio por el
85         # mismo motivo.
86         #
87         # ⚠ Esto es **literalmente** lo que escribí hoy en `recipes/espeak-ng.toml`, con los mismos
88         # símbolos (`sf_command`, `sf_error_number`) y la cadena dibujada — y no lo apliqué acá. La
89         # nota estaba en mi propio repo y la volví a pagar.
90         "libsndfile", "glib", "libffi", "pcre2"]
91# ⚠ Lo que de verdad necesita en EJECUCIÓN es la capa de compatibilidad de PulseAudio que publica
92# PipeWire: sin ella arranca y no se conecta. Ver la nota de arriba.
93runtime = ["pipewire", "pulseaudio", "libsndfile", "glib", "libffi", "pcre2"]