# libhangul 0.2.0 — la biblioteca que convierte pulsaciones en sílabas coreanas. # # ══ PARA QUÉ ═══════════════════════════════════════════════════════════════════════════════════ # El hangul se escribe componiendo: cada sílaba se arma con una inicial, una vocal y a veces una # final, y el teclado manda las piezas por separado. Esto hace esa composición (y la conversión # hanja→hangul). Es la única dep nueva que `fcitx5-hangul` necesita — medido contra el catálogo # el 2026-10-20, y la razón por la que el coreano es el primer motor de IME que entra: el chino # arrastra seis recetas más (`libime`, `libpinyin`, `opencc`, `fcitx5-lua`, `fcitx5-qt`) y # **qt6-qtwebengine**, y el japonés arrastra `anthy` más Qt. # # ══ CMAKE Y NO AUTOTOOLS, AUNQUE TRAE LOS DOS ══════════════════════════════════════════════════ # El tarball trae `CMakeLists.txt` Y `autogen.sh`+`configure.ac`. Se usa cmake porque es lo que usa # su consumidor (`fcitx5-hangul`) y porque el camino autotools de este proyecto exige regenerar con # `autogen.sh`, que mete autoconf/automake/libtool en la cadena para nada. # # ══ ⚠ PIC DESDE EL PRIMER DÍA, Y ESO ES LA LECCIÓN DE AYER APLICADA ════════════════════════════ # `fcitx5-hangul` es un ADDON: un `.so` que el daemon carga con `dlopen`. Un `.a` sin PIC no entra # en un `.so`, y el corpus se construye estático-primero — así que una receta nueva que va a ser # enlazada desde un `.so` tiene que nacer PIC o cuesta un viaje de diagnóstico. # # Eso se pagó ayer: `libpng`, `freetype` y `fontconfig` publicaban su `.a` sin PIC y `fcitx5` murió # con **7365** errores `relocation … recompile with -fPIC`; arreglarlo fue una decisión de # arquitectura con 40 recetas de cascada y las cinco imágenes de escritorio rearmando. Poner # `CMAKE_POSITION_INDEPENDENT_CODE=ON` acá cuesta una línea. # # `BUILD_SHARED_LIBS=OFF` mantiene la convención del corpus (estático) — PIC y estático no son # excluyentes: lo que PIC cambia es cómo se direccionan los globales, no dónde vive el código. # # Las herramientas y los tests quedan fuera: el consumidor usa la biblioteca, no el `hangul` # interactivo de línea de comandos. name = "libhangul" version = "0.2.0" license = "LGPL-2.1-or-later" [source] tarball = "https://github.com/libhangul/libhangul/archive/refs/tags/libhangul-0.2.0/libhangul-0.2.0.tar.gz" sha256 = "db9a256ff1e2c639ea8168f5e8741dae95ad7ea563f257b1dbd098afd8e48487" [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" flags = [] [build.phases] configure = ''' ZW="$PWD/.zwrap"; mkdir -p "$ZW" printf '#!/bin/sh\nexec /opt/zig/zig cc -mcpu=baseline "$@"\n' > "$ZW/cc" printf '#!/bin/sh\nexec /opt/zig/zig c++ -mcpu=baseline "$@"\n' > "$ZW/cxx" chmod +x "$ZW/cc" "$ZW/cxx" # `rm -rf build`: el árbol de fuentes se REUSA entre builds, así que un `build/` de un intento # anterior sobrevive con su `CMakeCache.txt` y los resultados cacheados de `pkg_check_modules` # — un primer fallo envenenaría todos los reintentos. Medido ayer con fcitx5: el build volvía a # morir con el MISMO error en 2 segundos. Toda receta cmake necesita esto. 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 \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_SHARED_LIBS=OFF \ -DENABLE_EXTERNAL_KEYBOARDS=OFF -DENABLE_UNIT_TEST=OFF ''' compile = "cmake --build build" # ⚠ **EL `.pc` LO GENERA EL CAMINO AUTOTOOLS, NO EL DE CMAKE — y el consumidor lo EXIGE.** # Medido: `cmake --install` deja `lib/cmake/libhangul/hangul-config.cmake` y **ningún** # `lib/pkgconfig/libhangul.pc`. Pero `fcitx5-hangul` no usa `find_package`: su CMakeLists:21 hace # pkg_check_modules(Hangul IMPORTED_TARGET "libhangul>=0.0.12" REQUIRED) # o sea que sin el `.pc` el motor no compila. El guardián de abajo lo cazó en el primer build, que # es exactamente para lo que estaba. # # ⇒ Se sustituye **la plantilla de upstream** (`libhangul.pc.in`, que el tarball trae y el camino de # cmake ignora), no un `.pc` inventado. La diferencia importa: los campos —y en particular el # `includedir=.../hangul-1.0`, que es el directorio VERSIONADO donde la cabecera cae de verdad— los # decide upstream, no yo. Un `.pc` escrito a mano se desalinea el día que cambien el prefijo de las # cabeceras, y nadie se enteraría hasta que un consumidor no encuentre `hangul.h`. # # La alternativa era construir por autotools para que el `.pc` saliera solo; se descartó porque # `autogen.sh` mete autoconf/automake/libtool en la cadena para obtener un fichero de diez líneas # cuya plantilla ya está en el árbol. install = ''' set -e DESTDIR=/out cmake --install build [ -f /out/usr/lib/libhangul.a ] || { echo "libhangul: no quedó la .a — NO sello" >&2; exit 1; } [ -f libhangul.pc.in ] || { echo "libhangul: no está libhangul.pc.in — ¿cambió el árbol de upstream? sin su plantilla no genero el .pc" >&2; exit 1; } mkdir -p /out/usr/lib/pkgconfig sed -e 's|@prefix@|/usr|g' \ -e 's|@exec_prefix@|${prefix}|g' \ -e 's|@libdir@|${prefix}/lib|g' \ -e 's|@includedir@|${prefix}/include|g' \ -e 's|@PACKAGE_VERSION@|0.2.0|g' \ libhangul.pc.in > /out/usr/lib/pkgconfig/libhangul.pc # Que no quede ni un `@algo@` sin sustituir: un `.pc` con un marcador crudo resuelve a medias y el # error sale después, en el `-I` del consumidor, sin nombrar este fichero. if grep -q '@[A-Za-z_]*@' /out/usr/lib/pkgconfig/libhangul.pc; then echo "libhangul: quedaron marcadores sin sustituir en el .pc:" >&2 grep -o '@[A-Za-z_]*@' /out/usr/lib/pkgconfig/libhangul.pc | sort -u >&2 exit 1 fi [ -f /out/usr/include/hangul-1.0/hangul.h ] || { echo "libhangul: la cabecera no está donde el .pc dice (include/hangul-1.0) — el -I apuntaría al vacío" >&2; exit 1; } echo "libhangul: .a + .pc generado de su plantilla + cabecera en include/hangul-1.0" ''' [deps] build = ["cmake", "samurai", "pkgconf", "gettext-tiny", "expat"]