Internasionalisasi dan pelokalan aplikasi Kotlin / Native

こ ん に ち は, atau selamat siang dalam bahasa Jepang.





Tidak peduli seberapa populer bahasa Inggris, pengguna tetap lebih nyaman dan akrab dengan lingkungan bahasa asli mereka.





Oleh karena itu, di bawah ini kita akan melihat langkah demi langkah proses mengadaptasi aplikasi konsol untuk Linux di Kotlin / Native ke bahasa Rusia dan Inggris.





Gettext GNU lama yang bagus akan membantu kita dalam hal ini .





Oleh karena itu, kami akan memastikan bahwa ini tidak menakutkan sama sekali.





Pada saat yang sama, mari kita lihat integrasi dengan library C, yang secara signifikan memperluas kapabilitas Kotlin / Native.





Apa yang kami tulis: penerjemah dari bilangan pokok ke dalam bahasa Jepang.





Apa yang diharapkan dari pembaca: pengetahuan tentang bahasa pemrograman Kotlin, C, tingkat keakraban dasar dengan OS Linux (khususnya Bash).





Yang Anda perlukan dalam proses: distribusi Linux apa pun, versi IntelliJ IDEA apa pun, gettext-devel diinstal, atau serupa.





Motivasi

Sebenarnya mengapa Kotlin / Native dan apa hubungannya bahasa Jepang dengan itu?

Selama sekitar setengah tahun, saya perlahan dan sedih belajar bahasa Jepang dari buku teks "Minna no Nihongo": sebagian untuk terjemahan lirik, sebagian hanya karena minat pada budaya.





Kemudian saya memutuskan untuk beralih dari pengembangan sistem ke pengembangan aplikasi, dari desktop ke platform seluler, dari C ++ / Qt / STL ke Kotlin / JVM / Android SDK.





, . , , NIH- - , ?





Qt/QML/C++: - .





Qt Open Source, - .





Kotlin Kotlin/Native.





, - .





Kotlin/Native

Kotlin " " () Java, JVM.





JetBrains, Kotlin, .





, (Kotlin/JS) "" (Kotlin/Native).





Kotlin/Native 2017 , .





Kotlin LLVM, JVM .





, .





:





  • (Apache-2.0 license)





  • LLVM , iOS













  • "" Kotlin





  • interop C





  • : low-level , POSIX





:





  • JVM, (: Native )





  • GUI, C interop (GTK, libui)





  • Android Studio,









Kotlin/Native , Github.





(i18n): , .





(l18n): , .





: "" , , , . .





GNU gettext

, .





GNU Translation Project.





:













  • runtime









GNU gettext

Kotlin/JVM Android Android SDK, , JVM.  





Kotlin/Native .





Qt , Qt, C++ .





GNU gettext:





  • ( )





  • (Win/Mac/Linux, Android/iOS )

















: 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:





  • create_localization.sh





  • update_localization.sh





, .





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



.





, , .





Selama pengembangan, Anda hanya perlu memanggil update_localization.sh secara berkala , menerjemahkan baris baru, dan memanggil skrip ini lagi untuk menghasilkan file mo.





あ り が と う ご ざ い ま す, atau terima kasih atas perhatiannya!





Sumber dari

Definisi diambil dari dokumentasi Django 





Mengapa internasionalisasi dan lokalisasi penting





Kotlin Native: perhatikan file Anda





DxGetText - GNU Gettext untuk Delphi dan C ++ Builder





PS : Saya berencana untuk menggunakan Kotlin / Native lebih jauh dalam kerangka pustaka lintas platform. Jika ada minat, saya bisa memodifikasi demo, misalnya port ke Windows.








All Articles