glib-gettext と intltool

glib-gettextとintltoolでメッセージを日本語化してみる。面倒なので、コンソールアプリにする。しかも、Hello, World!アプリである。

はじめに、プロジェクト用のディレクトリを作る。

$ mkdir glib-hello
$ cd glib-hello/

ソース作成。

$ cat glib-hello.c 
#include <config.h>
#include <stdio.h>
#include <glib.h>
#include <glib/gi18n.h>

int
main (int argc, char* argv[])
{
	setlocale (LC_ALL, "");

	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	printf (_("Hello, World!\n"));
	return 0;
}

ここでのミソは、以下の4点。

  • #include でglibのi18nヘッダを読み込んでいること
  • setlocale (LC_ALL, "");でlocaleを環境変数で指定されているものにしていること
  • bindtextdomain() bind_textdomain_codeset() textdomain()を使っていること
  • 翻訳する文字列を_()で囲っていること

bindtextdomain()関数は、メッセージドメイン(第1引数)と、翻訳ファイルがインストールされているディレクトリ(第2引数)と、を結びつける関数。今回はGETTEXT_PACKAGEというメッセージドメインを、後ほどconfigure.acで設定する。LOCALEDIRは"*/share/locale"にするけど、インストール時に指定できるようにconfigureスクリプトで決まるようにする。そして、GETTEXT_PACKAGE と LOCALEDIR はCPPFLAGSを使って、後ほどMakefile.amでmake時に-Dオプションで指定する。

Makefile.amを作る

$ cat Makefile.am
SUBDIRS = po

bin_PROGRAMS = glib-hello
glib_hello_SOURCES = glib-hello.c
glib_hello_LDADD = $(GH_LIBS)
glib_hello_CFLAGS = $(GH_CFLAGS)
glib_hello_CPPFLAGS =  -DLOCALEDIR=\""$(localedir)"\" \
		       -DGETTEXT_PACKAGE=\""$(GETTEXT_PACKAGE)"\"

ここでのミソは以下の3点

  • poディレクトリを追加。
  • glib_hello_CPPFLAGSでLOCALEDIRとGETTEXT_PACKAGEを指定する
  • glib_hello_LDDADD と glib_hello_CFLAGS を指定する

GH_LIBSとGH_CFLAGSは、pkgconfigを用いて、後ほどconfigure.acで指定する。

現在の状況は、

$ ls
Makefile.am  glib-hello.c

の二つのファイルが存在している。これからコマンドを実行するたびにファイルが増える。

まずは、configue.acの雛形を作るためにautoscanを実行する。

$ autoscan
$ ls
Makefile.am  autoscan.log  configure.scan  glib-hello.c

ファイルが増えた。そして、configure.scanをconfigure.acにコピーして、編集する。

$ cp configure.scan configure.ac
$ gedit configure.ac &
$ diff configure.scan configure.ac 
5c5
< AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
---
> AC_INIT([glib-hello], [0.0.1], [futoshi _at_ momonga-linux.org])
8a9,10
> AM_INIT_AUTOMAKE([foreign 1.11])
> 
10a13,16
> AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
> IT_PROG_INTLTOOL
> GETTEXT_PACKAGE=$PACKAGE
> AC_SUBST(GETTEXT_PACKAGE)
12a19
> PKG_CHECK_MODULES([GH], [glib-2.0])
21c28
< AC_CONFIG_FILES([Makefile])
---
> AC_CONFIG_FILES([Makefile po/Makefile.in])

ここでのポイントは7点。

  • AC_INITを適切に設定する(メールアドレスは変えてね)
  • AM_INIT_AUTOMAKE([foreign 1.11])を書く
  • AC_PATH_PROG(PKG_CONFIG, pkg-config, no)で、pkg-configコマンドの調査
  • IT_PROG_INTLTOOLでintltoolの調査
  • GETTEXT_PACKAGEの指定
  • PKG_CHECK_MODULES([GH], [glib-2.0])でglib-2.0の調査とCFLAGSとLIBSの設定
  • po/Makefile.inをAC_CONFIG_FILESに追加

AM_INIT_AUTOMAKEではforeignを指定しないと、touchでファイルを作るなんて卑怯な手を使うことになるので、面倒な場合はforeignを必ず指定すること。

pkgconfigは、
http://openseminar.okaya.ma/2009/wiki.cgi?page=%B8%F8%B3%AB%BB%F1%CE%C1&file=20090530%2Dnishio%2Epdf&action=ATTACH
ここで書いたので省略。

intltoolはメッセージの多言語化で使うツールで、後ほど利用する。

ここまでで、

$ ls
Makefile.am  autoscan.log  configure.ac  configure.scan  glib-hello.c

になっている。

ここから、glib-gettextize intltoolize autoreconf を使ってパッケージを作る。

$ glib-gettextize -f
Creating po/ subdirectory
Symlinking file mkinstalldirs
Symlinking file po/Makefile.in.in

Please add the files
  codeset.m4 gettext.m4 glibc21.m4 iconv.m4 isc-posix.m4 lcmessage.m4
  progtest.m4
from the /usr/share/aclocal directory to your autoconf macro directory
or directly to your aclocal.m4 file.
You will also need config.guess and config.sub, which you can get from
ftp://ftp.gnu.org/pub/gnu/config/.

$ intltoolize -f
You should add the contents of '/usr/share/aclocal/intltool.m4' to 'aclocal.m4'.

$ autoreconf -i
configure.ac:9: installing `./install-sh'
configure.ac:9: installing `./missing'
Makefile.am: installing `./depcomp'

次に、翻訳するファイルや、言語を記述するファイルを作成する。

$ echo glib-hello.c > po/POTFILES.in
$ echo ja > po/LINGUAS

POTFILES.inには、翻訳するファイルを列挙する。本当はエディタなどで編集すべきだけど、ファイル1つで面倒なのでechoで作成。
LINGUASには、翻訳する言語を列挙する。本当は(以下略)。

後は翻訳作業に入る。今回は、$HOMEにインストールするため、configureで--prefixを用いて指定する。

$ ./configure --prefix=$HOME
…
config.status: executing po/stamp-it commands

次に、翻訳する元となるファイルを作り編集する。

$ cd po
$ make glib-hello.pot
INTLTOOL_EXTRACT=/usr/bin/intltool-extract srcdir=. /usr/bin/intltool-update --gettext-package glib-hello --pot
$ cp glib-hello.pot ja.po
$ gedit ja.po &
$ diff glib-hello.pot ja.po 
16c16
< "Content-Type: text/plain; charset=CHARSET\n"
---
> "Content-Type: text/plain; charset=utf-8\n"
22c22
< msgstr ""
---
> msgstr "今日は、世界!\n"

本当は、きちんと編集しないといけないのですが、今回は文字セットと翻訳のみにします。後は、configure & make & make install

$ cd ..
$ ./configure --prefix=$HOME
…
config.status: executing po/stamp-it commands
$ make
make  all-recursive
…
$ make install
Making install in po
…

うまく行っていると、

$ glib-hello 
今日は、世界!

となる。パッケージを作るなら

$ make distcheck
{ test ! -d "glib-hello-0.0.1" || { find "glib-hello-0.0.1" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "glib-hello-0.0.1"; }; }
…
==================================================
glib-hello-0.0.1 archives ready for distribution: 
glib-hello-0.0.1.tar.gz
==================================================

こんな感じでパッケージが完成する。

急ぎ足で、glib-gettextとintltool等を説明したけど、今日はここでおしまい。