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 1465Shell 173Rust 96Markdown 943319 Definiciones

⎇ 2e4cfcaa6b78066e05fa0d49c8d7c8ebf0a055d6 recipes/libime-lm.toml TOML · 98 líneas · 5.9 KB Historia crudo

libime: estática y PIC, porque había CUATRO libc++ en un proceso bd9c765e1 · Sergio ·

1# libime-lm — el MODELO DE LENGUAJE del chino. Sin esto, el pinyin no convierte.
2#
3# ══ POR QUÉ ES UNA RECETA APARTE Y NO UN `ENABLE_DATA=On` ══════════════════════════════════════
4# El `data/CMakeLists.txt` de libime hace **tres descargas en tiempo de build** desde el servidor de
5# fcitx, y el sandbox de takana no tiene red a propósito: una fuente que se baja al construir no es
6# reproducible ni auditable. Por eso `recipes/libime.toml` va con `ENABLE_DATA=Off` y los datos
7# salen a recetas hermanas — ésta, `libime-dict` y `libime-table` — con su tarball pineado.
8#
9# Y el `[source]` de una receta admite **UNA sola** fuente (`crates/takana-core/src/recipe.rs`:
10# repo+commit, tarball+sha256 o dir, excluyentes). Tres tarballs ⇒ tres recetas. No es una
11# limitación molesta: cada dato se sella por separado y se puede rehacer sin tocar los otros.
12#
13# **El sha256 lo declara upstream en su propio CMakeLists**, así que no hay que confiar en el
14# servidor para pinearlo — se compara contra lo que el proyecto afirma. Comprobado: el fichero que
15# baja hoy de `download.fcitx-im.org` tiene exactamente ese sha.
16#
17# ══ QUÉ HACE: COMPILAR, NO COPIAR ══════════════════════════════════════════════════════════════
18# El tarball trae `lm_sc.arpa` — un modelo n-grama en texto, 77 MB comprimidos. De ahí salen DOS
19# binarios con las herramientas de `libime`, y los comandos son los de upstream, literales:
20#
21#     libime_slm_build_binary -s -a 22 -q 4 trie  lm_sc.arpa  sc.lm
22#     libime_prediction  sc.lm  lm_sc.arpa  sc.lm.predict
23#
24# Las banderas no se tocan: `-a 22` son los bits de compresión de punteros y `-q 4` los de
25# cuantización del trie de kenlm, o sea que **cambian el tamaño y la precisión del modelo**. Copiar
26# los valores de upstream es la única forma de que esto rinda como rinde en cualquier otra distro.
27#
28# ⇒ Por eso `libime` necesita `ENABLE_TOOLS=On`: sin esos dos ejecutables esta receta no tiene con
29# qué trabajar. Su guardián los exige por nombre, precisamente para que el fallo salga allá y no acá.
30#
31# ══ DÓNDE CAEN, Y POR QUÉ CON OTRO NOMBRE ══════════════════════════════════════════════════════
32# `LIBIME_INSTALL_LIBDATADIR` = `${CMAKE_INSTALL_FULL_LIBDIR}/libime` ⇒ `/usr/lib/libime/`, y
33# upstream los instala **renombrados** a `zh_CN.lm` y `zh_CN.lm.predict`: el motor los busca por
34# locale, no por el nombre del fichero de origen. Instalarlos como `sc.lm` daría un artefacto con
35# contenido que el motor no encuentra — sellado, lleno y mudo.
36name    = "libime-lm"
37version = "20260629"
38license = "LGPL-2.1-or-later"
39
40[source]
41tarball = "https://download.fcitx-im.org/data/lm_sc.arpa-20260629.tar.zst"
42sha256  = "06808333b9173e5374cf2cb5afc12d08f5625bf9abb536489cac376fc05f2e7f"
43# El tarball deja `lm_sc.arpa` en la RAÍZ, sin directorio contenedor (comprobado con `tar -tf`), así
44# que no hay ningún componente que recortar. El default de takana es 1, pensado para los releases
45# GNU; dejarlo recortaría el único fichero que hay.
46strip_components = 0
47
48[build]
49compiler = "zig-cc"
50target   = "x86_64-linux-musl"
51link     = "static"
52flags    = []
53
54[build.phases]
55configure = '''
56set -e
57[ -f lm_sc.arpa ] || { echo "libime-lm: el tarball no dejó lm_sc.arpa en la raíz — ¿cambió strip_components?" >&2; ls -la >&2; exit 1; }
58echo "libime-lm: lm_sc.arpa = $(stat -c%s lm_sc.arpa) bytes"
59'''
60# Las banderas son las de upstream, literales. `-s` deja fuera los avisos de frontera de frase.
61compile = '''
62set -e
63libime_slm_build_binary -s -a 22 -q 4 trie lm_sc.arpa sc.lm
64libime_prediction sc.lm lm_sc.arpa sc.lm.predict
65'''
66# Guardián: los dos ficheros, con un piso de tamaño. Un `.lm` de cero bytes es la figura del
67# artefacto VACÍO que este repo tiene documentada — se sella, es un cache-hit, y el motor carga sin
68# convertir nada. El piso no es un número inventado: el `.arpa` de entrada son decenas de MB y el
69# trie cuantizado de kenlm no baja de unos pocos; 1 MB es holgado y detecta el caso real (fichero
70# creado y no escrito).
71install = '''
72set -e
73mkdir -p /out/usr/lib/libime
74cp sc.lm         /out/usr/lib/libime/zh_CN.lm
75cp sc.lm.predict /out/usr/lib/libime/zh_CN.lm.predict
76for f in zh_CN.lm zh_CN.lm.predict; do
77  t=/out/usr/lib/libime/$f
78  [ -s "$t" ] || { echo "libime-lm: $f quedó vacío o ausente — NO sello un modelo que no convierte" >&2; exit 1; }
79  n=$(stat -c%s "$t")
80  [ "$n" -gt 1048576 ] || { echo "libime-lm: $f son sólo $n bytes — esperaba >1 MiB; el modelo no se escribió" >&2; exit 1; }
81done
82echo "libime-lm: zh_CN.lm $(stat -c%s /out/usr/lib/libime/zh_CN.lm) B + zh_CN.lm.predict $(stat -c%s /out/usr/lib/libime/zh_CN.lm.predict) B"
83'''
84
85[deps]
86# ⚠ **`fcitx5` y `zstd` NO son opcionales acá, y el fallo NO dice que falten.** Las herramientas de
87# libime son binarios DINÁMICOS: `libime_pinyindict` declara
88# `NEEDED libIMEPinyin.so.0 libIMECore.so.0 libFcitx5Utils.so.2`. El sandbox sólo monta lo
89# declarado, así que con `libime` a secas el cargador no encuentra `libFcitx5Utils.so.2` y la fase
90# muere con **`exit 127`** — que se lee como «no existe el ejecutable» y es «no existe una de sus
91# bibliotecas». Cuesta un rato porque el ejecutable SÍ está.
92#
93# La lista no se adivinó: se recorrió el `NEEDED` recursivamente desde los tres binarios contra los
94# artefactos del store. Clausura completa = `libime` + `fcitx5` + `zstd`, cero sonames huérfanos.
95# Es la misma figura que la cadena de tres saltos de `espeak-ng`, con una diferencia: allá el `.a`
96# del medio CORTABA la propagación; acá todo es `.so` y propaga, pero **declarar sigue siendo
97# manual** porque el sandbox es hermético a propósito.
98build = ["libime", "fcitx5", "zstd"]