2014年7月28日月曜日

autoconf と automake その2

前回のautoconfとautomakeのその2です。前回よりもう少しだけ難しいことをしてみます。
  • フォルダの階層分けをする
  • GTKを使う
  • 国際化(言語によって、文字列を切り替える)を行う

まずソースコードをsrcフォルダに入れて、src/main.c, src/func.h, src/func.cのフォルダに入れます。プログラムは以前にGTK+3.0用に書いたサンプルとほぼ同じです。ENABLE_NLSの部分が国際化の部分です

src/main.c
#include "config.h"
#include "func.h"
#include <gtk/gtk.h>
#include <glib/gi18n.h>

int main(int argc, char *argv[])
{
#ifdef ENABLE_NLS
        bindtextdomain(PACKAGE, LOCALEDIR);
        bind_textdomain_codeset(PACKAGE, "UTF-8");
        textdomain(PACKAGE);
#endif
        gtk_init(&argc, &argv);
        func();
        return 0;
}


src/func.h
void func.c();


src/func.c
#include "config.h"
#include <gtk/gtk.h>
#include <glib/gi18n.h>

void func()
{
        GtkWidget *dialog;

        dialog = gtk_message_dialog_new(NULL, 
                                GTK_DIALOG_DESTROY_WITH_PARENT, 
                                GTK_MESSAGE_OTHER,
                                GTK_BUTTONS_OK,
                                _("Hello!")
                                );
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
}

この場合、Makefile.amを直下とsrc以下に2つ作成する必要があります。

Makefile.amでは、makeを行うサブディレクトリの指定をしています。またACLOCAL_AMFLAGSはaclocalを再実行するときの m4フォルダ(後述)を指定しています。

src/Makefile.amでは、AM_CPPFLAGSで、コンパイル時に渡すオプションの指定をしています。-DLOCALEDIRは国際化のためのディレクトリの指定で、@GTK_CFLAGS@はGTKを使うためのpkg-config --cflagsと同等です。amtest_LDADDはリンクするライブラリの指定です。@GTK_LIBS@はpkg-config --libsと同等になります。

Makefile.am
ACLOCAL_AMFLAGS = -I ./m4
SUBDIRS = src po


src/Makefile.am
AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" @GTK_CFLAGS@
bin_PROGRAMS = amtest
amtest_SOURCES = main.c func.c func.h
amtest_LDADD = @GTK_LIBS@


configure.acは以下のように書き換えます。青色の部分が前回と違う部分です。AC_CONFIG_AUX_DIR(config)では、install-sh等のサポートスクリプトをconfigディレクトリに置くための指定です。IT_PROG_INTLTOOLからAM_GLIB_GNU_GETTEXTまでは、国際化のためです。PKG_PROG_PKG_CONFG, PKG_CHECK_MODULESはpkg-configを使用するための設定です。AC_CONFIG_FILESには、サブディレクトリのMakefileの作成を指示します。

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.68])
AC_INIT([Automake Test], 1.1, foo@example.com, amtest)
AC_CONFIG_AUX_DIR(config)
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([src/func.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL

# Checks for libraries.
IT_PROG_INTLTOOL
GETTEXT_PACKAGE=amtest
AC_SUBST(GETTEXT_PACKAGE)
AM_GLIB_GNU_GETTEXT
PKG_PROG_PKG_CONFIG
PKG_CHECK_MODULES(GTK, gtk+-3.0)
# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

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



AM_GLIB_GNU_GETTEXT等は、これだけでは使用できません。m4フォルダにこれらを使うためのマクロを置く必要があります。以下を実行してください。これでGLIB_GNU_GETTEXTを使用するための準備となります。po/Makefile.in.inも作成されます。必要なm4ファイルが表示されるので、/usr/share/aclocal/フォルダからm4フォルダにコピーしてください(無くても良いようですが)

$ glib-gettextize -c -f

同様にして、pkg.m4, glib-gettext.m4 もコピーしてください。

また各国語用のファイルとして、po/POTFILES.inとpo/LINGUASのファイルを作成します。それぞれ、翻訳する文字列が入っているソースコードと、翻訳する言語を指定します。

po/POTFILES.in
# List of source files which contain translatable strings.
src/func.c

po/LINGUAS
ja

ただ、このままだとpo/LINGUASファイルを参照しないようなので、intltoolも入れます。これで、再度po/Makefile.in.inが書き換わります。MinGWの場合は、このサイトからintltool_0.40.4-1_win32.zipをダウンロードし、解凍したものをmsysのフォルダに上書きしました。ただし、Makefile.in.inのコピーには失敗するので、手動でコピーしています。

$ intltoolize -c -f --automake

ここまで、終われば、後はほぼ従来通りに、以下を行えば良いです。ただし、aclocale実行時には、m4フォルダを指定するようにします。

$ aclocal -I ./m4
$ automake -a -c
$ autoconfig
$ ./cofigure


日本語化に関しては、以下の作業を行います。ja.poで"Hello!"に対応する日本語を設定すれば良いです。

$ cd po
$ make amtest.pot
$ cp amest.pot ja.po
$ vi ja.po


実はMinGW環境で、poフォルダのmake update-poがエラーになる問題が残っているのですが、とりあえずはこれで説明を終わりたいと思います。

世の中には色々なOSがありますが、一つのOSだけで動くソフトウェアを作るよりも多くのOSで動くソフトウェアの方を作るほうが面白いと思っています。その中でC言語を使った場合には、Javaと違いビルドの問題があるのですが、それをautotoolsは解決する仕組みとなっています。

なお、このautotoolsについては以下の書籍を参考にさせていただきました(前回の例はそのまま)。


私の説明は簡単な物でしたが、各コマンドの役割、各ファイルの役割、configure.acでのチェックの指令方法など、更に詳しく書かれています(詳しい分、少しとっつきにくい点もありますが)。他にもLinuxでのプログラム作成に役立つことが色々と書かれており、勉強になりました。Linuxのプログラミングに興味を持つ方は読む価値があるかと思います。

0 件のコメント:

コメントを投稿