本文将讲解如何将一个使用Makefile的Hello world程序国际化以及如何采用autotools进行配置和编译。
下面是大家所熟知的Hello world程序,将其命名为helloworld.c:
#include <stdio.h> int main (void) { printf ("Hello, world!\n"); }
1.首先我们创建源代码目录树:
/ 这是顶层目录
/src 这是放置源代码的目录
将helloworld.c放入src/目录中。
2.如果你的程序还没有启用autoconf,你可以先创建configure.scan文件(),将其重命名为configure.ac:
autoscan mv configure.scan configure.ac
编辑configure.ac,进行一些修改。你可以删除AC_INIT后面的所有内容。我们将采用AM_INIT_AUTOMAKE来传递变量。在AC_INIT后添加如下几行:
PACKAGE=helloworld
VERSION=0.0.1
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
并将AC_CONFIG_HEADER改变为AM_CONFIG_HEADER。如果你有一个空的AC_CONFIG_FILES 宏,注释掉它,否则下一步会出现错误。最后添加Makefile到AC_OUTPUT宏:
AC_OUTPUT(Makefile)
注释:configure.ac以前叫configure.in
3.添加一些额外的文件:NEWS、README、AUTHORS、Changelog,这些文件不是automake工具所需要的,这是为了遵循GNU标准。在新建另外两个文件:config.h.in、Makefile.am,这两个文件是automake工具所必须的。我们将稍后创建Makefile.am。
4.添加GNU所要求但还不存在的文件(如CONPING、INSTALL等):
automake --add-missing --gnu
5.接下来,我们将添加国际化支持。同样,在顶层目录运行下面的命令:
intltoolize
6.运行autoheader来创建config.h.in:
autoheader
7.打开configu.in进行一些修改:
IT_PROG_INTLTOOL(0.26) AM_GNU_GETTEXT([external]) # 我们只需要这两个 AM_GLIB_GNU_GETTEXT # 宏中的一个 ALL_LINGUAS="da nl" # 国际化,意味着将为danish和dutch语言创建.po文件 AC_OUTPUT( Makefile src/Makefile intl/Makefile po/Makefile.in )
IT_PROG_INTLTOOL将检查intltool工具的版本是否符合标准。
AM_GNU_GETTEXT添加本地语言支持到Makefile,同时带有一个编译选项。AM_GNU_GETTEXT将检查额外需要的函数和程序,并在configure过程中创建po/POTFILES。除了使用AM_GNU_GETTEXT,你也可以使用AM_GLIB_GNU_GETTEXT, which will do a few less things than AM_GNU_GETTEXT, but does more than enough for what intltool needs to work.你只需要使用这两个宏其中任一个就可以。
文本域通过PACKAGE来识别,我们将在helloworld.c添加一些函数,函数将使用这些预定义的变量。同样,这将是你翻译文件的基本文件名,确定你选择了一个独一的名称。
8.现在,添加所支持的语言到po/LINGUAS:
da nl
注释:过去,这个功能是通过configure.{in,ac}文件中的ALL_LINGUAS变量实现的,从gettext 0.11废弃。
9.运行
aclocal
来检查autoconf和automake所必要的宏是否插入到aclocal.m4。
运行
autoconf
来创建configure脚本。
10.安装gettext.h头文件,并在程序中包含进去,我们定义了一个简单的宏_()来代替gettext():
#include "gettext.h" #define _(String) gettext (String)
11.现在添加下列代码到helloworld.c中:
#include <locale.h> #include "gettext.h" #define _(String) gettext (String) /* includes used by original program here */ int main (void) { setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); /* Original Helloworld code here */ }
如果你使用的是gnome或是gtk+,那么我们不需要setlocale这条语句。现在我们将要被进行翻译的字符创替换为(“字符串”),那么printf(“Hello world”)将变成printf((“Hello world!\n”))。
12.创建src/Makefile.am(Makefile.in和Makefile文件将会基于Makefile.am产生):
INCLUDES = -I$(top_srcdir) -I$(includedir) -DLOCALEDIR=\””$(datadir)/locale”\”
bin_PROGRAMS = helloworld
helloworld_SOURCES = helloworld.c
noinst_HEADERS = i18n-support.h
- Now we create the following toplevel Makefile.am
SUBDIRS = src po -
Go into the directory po/ and create POTFILES.in
This file should contain a list of all the files in your distribution
(starting from the top, one level above the po dir) that contain
strings to be internationalized.
For the helloworld sample, it would contain
src/helloworld.c
Run
intltool-update –pot
Run
intltool-update –maintain
to see if you are missing files that contain marked strings.
You should consider adding these to POTFILES.in
- Now we start making a Danish and Dutch translation
msginit –locale=da
msginit –locale=nl
intltool-update da
intltool-update nl
edit and update da.po and nl.po
(The respective translations are “Hej verden” and “Hallo wereld”)
- Now we can compile. We will test it later, so we will install it in
a temporary location.
Close your eyes and type
./configure –prefix=/tmp/helloworld && make
in the toplevel directory. 🙂
- To test if it works, you have to install the package.
Run
make install
in the toplevel directory.
- Now set the environment variable LC_ALL to your preferred language :
export LC_ALL=nl_NL
/tmp/helloworld/bin/helloworld
export LC_ALL=da_DK
/tmp/helloworld/bin/helloworld
And if all goes well, the string should be translated in the two languages.
- To finish it all up, run
make dist
to create a distributable tarball containing your internationalized
program.
- Exercises :
– add another language