こ ん に ち は, o buenas tardes en japonés.
No importa lo popular que sea el idioma inglés, los usuarios se sienten más cómodos y familiarizados en su entorno de lengua materna.
Por lo tanto, a continuación, analizaremos paso a paso el proceso de adaptación de una aplicación de consola para Linux en Kotlin / Native a las configuraciones regionales en ruso e inglés.
El viejo gettext de GNU nos ayudará con esto .
Como resultado, nos aseguraremos de que esto no dé miedo en absoluto.
Al mismo tiempo, veamos la integración con las bibliotecas C, que expande significativamente las capacidades de Kotlin / Native.
Lo que escribimos: un traductor de números cardinales al japonés.
Lo que se espera del lector: conocimiento de los lenguajes de programación Kotlin, C, un nivel básico de familiaridad con el sistema operativo Linux (en particular Bash).
Lo que necesita en el proceso: cualquier distribución de Linux, cualquier versión de IntelliJ IDEA, gettext-devel instalado o similar.
Motivación
En realidad, ¿por qué Kotlin / Native y qué tiene que ver el japonés con eso?
Durante aproximadamente medio año, aprendo lento y tristemente japonés del libro de texto “Minna no Nihongo”: en parte por la traducción de la letra, en parte solo por interés en la cultura.
Más tarde decidí pasar del desarrollo de sistemas al desarrollo de aplicaciones, de plataformas de escritorio a móviles, respectivamente, de C ++ / Qt / STL a Kotlin / JVM / Android SDK.
, . , , NIH- - , ?
Qt/QML/C++: - .
Kotlin Kotlin/Native.
, - .
Kotlin/Native
Kotlin " " () Java, JVM.
JetBrains, Kotlin, .
, (Kotlin/JS) "" (Kotlin/Native).
Kotlin LLVM, JVM .
, .
:
(Apache-2.0 license)
LLVM , iOS
"" Kotlin
interop C
: low-level , POSIX
:
Kotlin/Native , Github.
(i18n): , .
(l18n): , .
: "" , , , . .
GNU gettext
, .
:
runtime
GNU gettext
Kotlin/JVM Android Android SDK, , JVM.
Kotlin/Native .
Qt , Qt, C++ .
GNU gettext:
: Linux, .
: stdin, .
, .
Github IntelliJ IDEA.
: ~18 Ryzen 3900X + 32GB DDR4-3600 + NVM-E SSD. .
, .
:
$ file build/bin/native/debugExecutable/JapaneseNumeralTranslator.kexe
build/bin/native/debugExecutable/JapaneseNumeralTranslator.kexe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.16, BuildID[xxHash]=a0971dbf76e9db60, with debug_info, not stripped
$ ldd build/bin/native/debugExecutable/JapaneseNumeralTranslator.kexe
linux-vdso.so.1 (0x00007fff890d7000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f348e47a000)
libm.so.6 => /lib64/libm.so.6 (0x00007f348e334000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f348e312000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f348e2f7000)
libc.so.6 => /lib64/libc.so.6 (0x00007f348e12c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f348e4a0000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f348e112000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007f348e10b000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f348e0d1000)
librt.so.1 => /lib64/librt.so.1 (0x00007f348e0c6000)
$ file build/bin/native/releaseExecutable/JapaneseNumeralTranslator.kexe
build/bin/native/releaseExecutable/JapaneseNumeralTranslator.kexe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.16, BuildID[xxHash]=c76aff5e0db3fdae, not stripped
$ ldd build/bin/native/releaseExecutable/JapaneseNumeralTranslator.kexe
linux-vdso.so.1 (0x00007ffff69c2000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f41ad9dd000)
libm.so.6 => /lib64/libm.so.6 (0x00007f41ad897000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f41ad875000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f41ad85a000)
libc.so.6 => /lib64/libc.so.6 (0x00007f41ad68f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f41ada03000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f41ad675000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007f41ad66e000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f41ad634000)
librt.so.1 => /lib64/librt.so.1 (0x00007f41ad629000)
$ ls -lh build/bin/native/debugExecutable/JapaneseNumeralTranslator.kexe
-rwxr-xr-x. 1 eraxillan eraxillan 1.8M Mar 7 13:24 build/bin/native/debugExecutable/JapaneseNumeralTranslator.kexe
$ ls -lh build/bin/native/releaseExecutable/JapaneseNumeralTranslator.kexe
-rwxr-xr-x. 1 eraxillan eraxillan 529K Mar 7 13:24 build/bin/native/releaseExecutable/JapaneseNumeralTranslator.kexe
, - .
, Community Edition.
, file .
, IDE, .
, .
printf-driven , Android AOSP.
"" gettext().
, tr(), .
import kotlinx.cinterop.*
import platform.linux.*
import platform.posix.*
fun tr(key: String): String = gettext(key)?.toKString() ?: ""
POSIX-, Locale.kt.
: , .
, locale -a.
Bash- gettext:
, .
pot- (""), .
# Extract all tr() wrapped strings to po/jnt.pot file
xgettext --keyword=tr --language=java \
--add-comments --sort-output \
--copyright-holder='Alexander Kamyshnikov <axill777@gmail.com>' \
--package-name='Japanese numeral translator' \
--package-version='1.0' \
--msgid-bugs-address='axill777@gmail.com' \
-o po/jnt.pot --files-from=KT_FILES
po- ( ):
# Generate locale sources
# NOTE: --no-translator option is a workaround to supress email input request
msginit --no-translator --input=po/jnt.pot --locale=en_US.UTF-8 --output po/en_US/jnt.po
msginit --no-translator --input=po/jnt.pot --locale=ru_RU.UTF-8 --output po/ru_RU/jnt.po
mo- ( ):
# Generate locale binary files
msgfmt --output-file=po/en_US/jnt.mo po/en_US/jnt.po
msgfmt --output-file=po/ru_RU/jnt.mo po/ru_RU/jnt.po
, Kotlin/Native , "" mo- .
, Gradle, .
mo- , gettext .
RPM/DEB-, mo- /usr/share/locale
.
, , .
Durante el desarrollo, solo necesita llamar periódicamente a update_localization.sh , traducir nuevas líneas y volver a llamar a este script para generar archivos mo.
あ り が と う ご ざ い ま す, ¡o gracias por su atención!
Fuentes de
Definiciones tomadas de la documentación de Django
Por qué son importantes la internacionalización y la localización
Kotlin Native: mira tus archivos
DxGetText - GNU Gettext para Delphi y C ++ Builder
PD : planeo usar Kotlin / Native más dentro del marco de las bibliotecas multiplataforma. Si hay interés, puedo modificar la demostración, por ejemplo, portarla a Windows.