使用 gettext

使用 gettext

參考網路上許多文章與自己測試的結果 :

GettextLog

假設在還沒加入 LC_MESSAGES 支援之前, prog.c 長得像這樣:

#include <stdio.h>

main()

{

printf("This is a test string.\n");

}

現在我們要用 gettext 來加入支援,則程式只要改成:

#include <stdio.h>

#include <libintl.h>

#include <locale.h> // for setlocale

#define _(STRING) gettext(STRING)

#define PACKAGE "prog"

main()

{

setlocale(LC_MESSAGES, "");

textdomain(PACKAGE);

/* 這裏就是指定用

/usr/share/locale/\$LOC/LC_MESSAGES/prog.mo

作為訊息檔。其中 \$LOC 是在 setlocale 中設定的 */

printf(_("This is a test string.\n"));

/* 使用 gettext 來抓出訊息,再交給 printf 來印 */

}

如果在指定的 locale 下找不到 prog.mo 檔,則程式就直接以原英文訊息印出。因此,加入 LC_MESSAGES 的支援,原 source code 修改並不多,其實相當方便。

比較麻煩的是各 locale 下的訊息檔製作,而這些步驟可以經由 GNU gettext 套件很容易地達成,其步驟簡述如下 (詳見 info gettext):

xgettext editor msgfmt (install)

source code --> .pot --> .pox --> .gmo --> .mo -->

(節錄自 Platin.bbs@csie.nctu.edu.tw 的文章:

[REF] 關於 gettext (一、簡介))

  • 使用 xgettext 產生 .pot 檔:

xgettext -a -o prog.pot prog.c

而 prog.pot 檔的內容如下:

# SOME DESCRIPTIVE TITLE.

# Copyright (C) YEAR Free Software Foundation, Inc.

# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.

#

#: prog.c:8

#, fuzzy

msgid ""

msgstr ""

"Project-Id-Version: PACKAGE VERSION\n"

"POT-Creation-Date: 1999-02-28 19:18+0800\n"

"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"

"Language-Team: LANGUAGE &lt;LL@li.org>\n"

"MIME-Version: 1.0\n"

"Content-Type: text/plain; charset=CHARSET\n"

"Content-Transfer-Encoding: ENCODING\n"

#: prog.c:10

msgid "This is a test string.\n"

msgstr ""

各位可以注意到倒數兩行, msgid 就是原來 source 裏頭的英文訊息,而我 們可以直接在 msgstr 中將原訊息翻譯成中文。所以,接下來的工作其實就 是翻譯,我們可以用任意的編輯器編輯這個檔案,並將翻譯好的檔案存成 prog.pox 檔。

  • 將 prog.pox 編譯成 prog.gmo:

msgfmt -o prog.gmo prog.pox

其中 prog.gmo。就是我們要的訊息檔,等到我們把它安裝到

/usr/share/locale/..../LC_MESSAGES/

之後,就名改為 prog.mo 。在此, .pot, pox, gmo 等附檔名是 info gettext 中建議的,分別代表未翻譯前的訊息原始檔、翻譯後的訊息原始檔、 經 GNU gettext 套件編譯後的訊息檔。

--以上多是複製於網路上的howto--

如果與autotools整合

  1. 修改 configure.ac

AM_GNU_GETTEXT_VERSION([0.14.5])

AM_GNU_GETTEXT([external])

  1. 執行

gettextize //第一次

gettextize --copy --no-changelog //之後

儘量用最新版的automake (automake-1.9)

  1. copy

cp /usr/share/gettext/gettext.h src

  1. 確認 configure.ac, Makefile.am, src/Makefile.am

configure.ac

AC_CONFIG_FILES([Makefile src/Makefile po/Makefile.in])

Makefile.am

SUBDIRS = po src

ACLOCAL_AMFLAGS = -I m4

EXTRA_DIST = ...

src/Makefile.am

bin_PROGRAMS = hello

hello_SOURCES = main.c say.c say.h

  1. Makevars

mv po/Makevars.template po/Makevars

DOMAIN = \$(PACKAGE)

subdir = po

top_builddir = ..

XGETTEXT_OPTIONS = --keyword=_ --keyword=N_

COPYRIGHT_HOLDER = Your Name or Your Employer

MSGID_BUGS_ADDRESS = \$(PACKAGE BUGREPORT)

EXTRA_LOCALE_CATEGORIES =

  1. po/ POTFILES.in

src/main.c

src/say.c

  1. src/Makefile.am

AM_CPPFLAGS = -DLOCALEDIR="\$(localedir)"

bin_PROGRAMS = hello

hello_SOURCES = main.c say.c say.h gettext.h

LDADD = \$(LIBINTL)

  1. 先不翻譯

autoreconf --install

configure

make

.

.

.

Making all in po....

.

.

  1. 翻譯

cd po

msginit -l zh_TW

編輯檔案 zh_TW.po

note: "Content-Type: text/plain; charset=UTF-8\n"

檢查 zh_TW.po

msgfmt --statistics --check zh-TW.po

echo zh_TW >> LINGUAS

  1. 編譯

./configure --prefix \~/test

make

cd po

make update-po

cd ..

make install

  1. 管理更新與重建語系檔

重建

cd po

make clean

make

更新

cd po

make update-po

homas@thomas-laptop:\~/work_house/partclone/partclone/trunk\$ svn propdel svn:eol-style po/zh_TW.gmo

property 'svn:eol-style' deleted from 'po/zh_TW.gmo'.

svn gmo 如果遇到

就這樣

svn propdel svn:eol-style po/zh_TW.gmo

就可以了!

ref.1 http://cle.linux.org.tw/xcin/i18n/pc2000/p5/gettext.html

ref.2 http://www.linux.org.tw/CLDP/OLD/doc/i18n-introduction.html

ref.3 http://www.lrde.epita.fr/\~adl/autotools.html

convert from Thomas blog post id 197 old convert log: ./015710/tag%3E2008%2001%20linux)

@2008 @01 @linux

Comments