promoción + receta: boost al corpus con iostreams, y libime — el chino tiene camino
**`boost` con `iostreams` SELLÓ**, así que la pared que temía no existía: `zig c++` compila Boost.Iostreams. `libboost_iostreams.a` está en el artefacto (181 MB en total, casi todo cabeceras). Cuatro intentos, y los cuatro fueron de INVOCACIÓN, no de compilación — conviene tenerlos juntos porque el patrón es el mismo: `--with-toolset=cc` (nombre supuesto) · `--cxx=` en bootstrap (opción que es del guion del motor, no suya) · `using gcc` para zig (toolset inventado; lo correcto es `clang`, que es lo que zig c++ ES) · y el envoltorio sin reescribir `--target`, **que 30 recetas de este catálogo ya traían resuelto**. Ninguno tocó la pregunta de fondo, y cuando se llegó a ella la respuesta fue sí. **Promoción al corpus verificada en los dos niveles de siempre**: el hash de boost no se movió al pasar de `incoming-kde` a `recipes/`, y `kactivitymanagerd` —su único dependiente, radio 1— conserva el suyo exacto. Cero rebuilds. Y entra `libime`, el motor de pinyin→hanzi: un kenlm recortado más los índices de pinyin y tabla. ⚠ `ENABLE_DATA=Off` **no es un recorte, es que los datos se descargan**: su `data/CMakeLists.txt` hace dos descargas en tiempo de build desde el servidor de fcitx —`lm_sc.arpa` (75 MB, el modelo de lenguaje) y `dict-20260907` (el diccionario)— y el sandbox no tiene red, a propósito: una fuente que se baja al construir no es reproducible ni auditable. Los datos van a recetas hermanas con su tarball pineado, que es el modelo del repo. Upstream incluso publica los sha256 en ese mismo CMakeLists, así que no hay que confiar en nadie para pinearlos. ⚠ Por eso `ENABLE_TOOLS=On` es obligatorio y el guardián lo exige por nombre: las recetas de datos necesitan `libime_slm_build_binary`, `libime_prediction` y `libime_pinyindict` de ESTA para convertir el `.arpa` y el `.txt` en los binarios que el motor lee. Sin ellas, el fallo aparecería dos recetas más tarde con este artefacto ya sellado y pareciendo correcto. ⇒ Y hasta que existan, **libime NO se declara en ningún perfil**: un motor de conversión sin modelo de lenguaje carga y no convierte nada — la misma razón por la que `fcitx5` esperó un día a tener motor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Semántico sayk'uy
Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.
3 qillqakuna · +164 −77
- recipes/boost.toml +77 −0
- recipes/incoming-kde/boost.toml +0 −77
- recipes/libime.toml +87 −0
diff --git a/recipes/incoming-kde/boost.toml b/recipes/boost.toml
similarity index 100%
rename from recipes/incoming-kde/boost.toml
rename to recipes/boost.toml
diff --git a/recipes/libime.toml b/recipes/libime.toml
new file mode 100644
index 00000000..ca21179c
--- /dev/null
+++ b/recipes/libime.toml
@@ -0,0 +1,87 @@
+# libime 1.1.17 — el motor de conversión pinyin→hanzi. La pieza que faltaba para escribir chino.
+#
+# ══ QUÉ ES ═════════════════════════════════════════════════════════════════════════════════════
+# El chino se escribe tecleando la pronunciación en pinyin y eligiendo entre los caracteres que
+# suenan igual. Con decenas de miles de hanzi eso no es una tabla: es un modelo de lenguaje que
+# ordena los candidatos por probabilidad en contexto. libime es ese motor (un kenlm recortado más
+# los índices de pinyin y de tabla), y `fcitx5-chinese-addons` es su cara.
+#
+# ══ ⚠ `ENABLE_DATA=Off`, Y NO ES UN RECORTE: ES QUE LOS DATOS SE DESCARGAN ═════════════════════
+# `data/CMakeLists.txt` hace **dos descargas en tiempo de build** desde el servidor de fcitx:
+# lm_sc.arpa-20260629.tar.zst 75 MB → el modelo de lenguaje
+# dict-20260907.tar.zst → el diccionario de pinyin
+# y el sandbox de takana no tiene red, a propósito: una fuente que se baja al construir no es
+# reproducible ni auditable. ⇒ los datos salen a **recetas hermanas** (`libime-lm`,
+# `libime-dict`) con su tarball pineado por sha256, que es el modelo del repo — y upstream hasta
+# nos da los sha en ese mismo CMakeLists, así que no hay que confiar en nadie para pinearlos.
+#
+# ⚠ **Por eso `ENABLE_TOOLS=On` es obligatorio acá y no adorno.** Las recetas de datos necesitan
+# los ejecutables de ESTA para convertir el `.arpa` y el `.txt` en los binarios que el motor lee:
+# `libime_slm_build_binary` (el modelo), `libime_prediction` y `libime_pinyindict`. Si esta receta
+# se construyera sin herramientas, las otras dos no tendrían con qué trabajar.
+#
+# ⇒ Y hasta que esas dos existan, **libime NO se declara en ningún perfil**: un motor de conversión
+# sin modelo de lenguaje carga y no convierte nada. Es la figura de `crun` sin podman, la misma por
+# la que `fcitx5` esperó un día a tener un motor.
+#
+# ══ LO QUE PIDE, MEDIDO EN SU CMakeLists ═══════════════════════════════════════════════════════
+# ECM · PkgConfig · libzstd · Fcitx5Utils · **Boost 1.61 COMPONENTS iostreams**
+# El último obligó a cambiar `boost`, que en este corpus era headers-only desde hacía un año: ahora
+# compila `libboost_iostreams.a` y está promovido al corpus (radio 1 verificado, `kactivitymanagerd`
+# con el hash intacto).
+#
+# `BUILD_SHARED_LIBS` se deja en On (su default): `fcitx5-chinese-addons` es un addon `.so` y
+# enlazarlo contra una libime estática no-PIC sería el muro del 19-oct otra vez.
+name = "libime"
+version = "1.1.17"
+license = "LGPL-2.1-or-later"
+
+[source]
+tarball = "https://github.com/fcitx/libime/archive/refs/tags/1.1.17/libime-1.1.17.tar.gz"
+sha256 = "6af056717edf99be8d4b83717de01b6404398d2fc47a301b609ca7d31331cafb"
+
+[build]
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "dynamic"
+flags = []
+
+[build.phases]
+configure = '''
+ZW="$PWD/.zwrap"; mkdir -p "$ZW"
+# El envoltorio reescribe `--target`: es el patrón canónico del repo (30 recetas lo traen) y sin él
+# zig rechaza los triples que algunos builds inventan («UnknownOperatingSystem»).
+printf '%s\n' '#!/bin/sh' 'for a do' 'case "$a" in --target=*) a=--target=x86_64-linux-musl ;; esac' 'set -- "$@" "$a"' 'shift' 'done' 'exec /opt/zig/zig cc -mcpu=baseline "$@"' > "$ZW/cc"
+printf '%s\n' '#!/bin/sh' 'for a do' 'case "$a" in --target=*) a=--target=x86_64-linux-musl ;; esac' 'set -- "$@" "$a"' 'shift' 'done' 'exec /opt/zig/zig c++ -mcpu=baseline "$@"' > "$ZW/cxx"
+chmod +x "$ZW/cc" "$ZW/cxx"
+rm -rf build
+cmake -B build -G Ninja -Wno-dev \
+ -DCMAKE_C_COMPILER="$ZW/cc" -DCMAKE_CXX_COMPILER="$ZW/cxx" \
+ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr \
+ -DPKG_CONFIG_ARGN=--static \
+ -DENABLE_DATA=Off -DENABLE_TOOLS=On -DENABLE_TEST=Off -DENABLE_DOC=Off
+'''
+compile = "cmake --build build"
+# El guardián pide las DOS cosas por las que esta receta existe: las bibliotecas y las TRES
+# herramientas. Sin las herramientas, `libime-lm` y `libime-dict` no pueden construirse — y eso se
+# descubriría dos recetas más tarde, con el artefacto ya sellado y pareciendo correcto.
+install = '''
+set -e
+DESTDIR=/out cmake --install build
+n=$(find /out/usr/lib -name 'libIME*.so*' 2>/dev/null | wc -l)
+[ "$n" -gt 0 ] || { echo "libime: no quedó ninguna libIME*.so — NO sello" >&2; ls -R /out/usr/lib 2>/dev/null | head -20 >&2; exit 1; }
+falta=""
+for t in libime_slm_build_binary libime_prediction libime_pinyindict; do
+ [ -x "/out/usr/bin/$t" ] || falta="$falta $t"
+done
+if [ -n "$falta" ]; then
+ echo "libime: faltan herramientas:$falta — sin ellas las recetas de datos no pueden construirse" >&2
+ ls /out/usr/bin 2>/dev/null >&2
+ exit 1
+fi
+echo "libime: $n biblioteca(s) + las 3 herramientas de datos"
+'''
+
+[deps]
+build = ["cmake", "samurai", "extra-cmake-modules", "pkgconf", "fcitx5", "boost", "zstd",
+ "gettext-tiny", "glib", "pcre2", "libffi", "expat", "zlib", "dbus"]