本文来自维基百科:https://en.wikipedia.org/wiki/Gettext
gettext是一种国际化与本地化系统,在类Unix系统中编写多语言程序时经常被使用。gettext的一个常用的实现版本为GNU gettext,1995年发布。
源代码中所有需要多语言支持的(需要翻译的)字符串都修改为使用gettext函数包装起来。为了方便也可以使用下划线 _。比如:
printf(gettext("My name is %s.\n"), my_name);
或
printf(_("My name is %s.\n"), my_name);
gettext函数会使用提供的字符串作为键值去查找当前设置语言对应的翻译版本,如果没有找到则返回原始的字符串。那么怎么制作各种语言的翻译版本呢?xgettext程序基于源代码文件,会识别出所有使用gettext或 _ 标记的字符串,然后生成 .pot 文件(Portable Object Template)。比如:源代码中:
/// TRANSLATORS: Please leave %s as it is, because it is needed by the program.
/// Thank you for contributing to this project.
printf(_("My name is %s.\n"), my_name);
(以///开头的注释会有特殊的作用,之后我们会看到)生成的 .pot 模板文件:
#. TRANSLATORS: Please leave %s as it is, because it is needed by the program.
#. Thank you for contributing to this project.
#: src/name.c:36
msgid "My name is %s.\n"
msgstr ""
仔细观察生成的 .pot 文件我们会发现其中包含了注释、源文件名和字符串所在行数、源字符串和对应的翻译版本(当然现在是空的)。接下来就是翻译工作。
使用msginit程序可以由 .pot 模板文件生成一个 .po 文件(Portable Object)。接下来我们将修改 .po 文件,将翻译的文本填进去。比如一个中文的翻译版本,我们可以运行以下命令:
msginit --locale=zh_CN --input=name.pot
我们将得到一个 zh_CN.po 文件,编辑 .po 文件可以使用任何文本处理程序手动修改,或者使用 Poedit、Emacs。编辑后的效果如下:
#: src/name.c:36
msgid "My name is %s.\n"
msgstr "我的名字是%s。\n"
最后,使用msgfmt程序将 .po 文件编译为二进制的 .mo 文件(Machine Object)。GNU gettext 使用 .gmo 扩展名。接下来就可以使用到我们的程序中了。
Unix中,设置环境变量 LC_MESSAGES。Linux中设置环境变量LANGUAGE,如果存在对应的 .mo 文件,程序将使用对应的语言版本。GNU gettext https://www.gnu.org/software/gettext/gettext.htmlGetText for Windows http://gnuwin32.sourceforge.net/packages/gettext.htm
wxWidgets中通过wxLocale实现了gettext。