autoconf/automake を使ってみる
先日 autoconf/automake を使ってみたのだが、ドキュメントもろくに読まずにやったら当然ながらうまくいかなくてかなり試行錯誤するはめになった。復習を兼ねてその時の作業をメモしてみる。あ、今もちゃんと理解してる訳ではないので「こうやったらうまくいった(っぽい)」というだけで、間違ってることを言ってる可能性は大です。そのあたりはご注意を。
まずは作業前の状態。
% ls CVS/ ChangeLog README.bhl xmessage+.c
ソース xmessage+.c から xmessage+ というバイナリを作ってみます。ソースの中身は先日のポップアップウィンドウそのままですが、諸般の事情で名前を変えてみてます。ヘッダファイルもないし GTK+ を使っていること以外は "Hello world!!" と大して変わりません。README.bhl は xmessage+ の説明を BHL で書いたもの。最終的にはこいつを変換して README を作りますが、とりあえずは気にしなくていいです。
Makefile.am を作る
さて、まず最初に Makefile.am を作ります。内容はこんなん。
bin_PROGRAMS=xmessage+ xmessage__SOURCES=xmessage+.c INCLUDES=$(XMESSAGE__CFLAGS) xmessage__LDADD=$(XMESSAGE__LIBS)
一行目で「xmessage+ というバイナリを作る」ことを宣言します。二行目がその元となるソースファイル (xmessage+.c) の指定。素直にやると
xmessage+_SOURCES=xmessage+.c
とするところなんですが、変数名に使える記号はアンダースコアだけなので xmessage__SOURCES= にしてやります。更に GTK+ が必要とするフラグやライブラリを三行目と四行目で参照しています。このあたりの話はこちらが参考になります。
configure.in を作る
Makefile.am ができたら autoscan を実行して configure.in の雛形となる configure.scan を作ります。
% autoscan autom4te: configure.ac: no such file or directory autoscan: /usr/bin/autom4te failed with exit status: 1 zsh: exit 1 autoscan
なんかエラーが出ちゃいますが
% ls CVS/ Makefile.am autoscan.log xmessage+.c ChangeLog README.bhl configure.scan
configure.scan は無事できているのでこいつを編集していきます。いきなり最終形と diff るとこんなん。
% diff configure.scan configure.in --- configure.scan 2006-02-19 10:20:10.263352824 +0900 +++ configure.in 2006-02-19 10:27:03.575519824 +0900 @@ -2,14 +2,18 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) +AC_INIT(xmessage+, 0.1, foo@example.com) +AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) AC_CONFIG_SRCDIR([xmessage+.c]) -AC_CONFIG_HEADER([config.h]) +AM_CONFIG_HEADER(config.h) # Checks for programs. AC_PROG_CC # Checks for libraries. +PKG_CHECK_MODULES(XMESSAGE_, gtk+-2.0) +AC_SUBST(XMESSAGE__CFLAGS) +AC_SUBST(XMESSAGE__LIBS) # Checks for header files. AC_HEADER_STDC zsh: exit 1 diff -u configure.scan configure.in
AC_INIT() の行はそのまま FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS を書き直し、AC_CONFIG_HEADER() を AM_CONFIG_HEADER() に変更します。それと AM_INIT_AUTOMAKE() の行を追加。ここいらはこうするもんのようです。
更に GTK+ 絡みは先のページを参考に PKG_CHECK_MODULES(), AC_SUBST() を追加します。PKG_CHECK_MODULES マクロはライブラリの依存関係を指定します。今回の場合は gtk+-2.0 を指定しています。AC_SUBST は必要となるフラグやライブラリを収集してくれます。これは先程作った Makefile.am の中で参照しています。
これでほぼ準備は整いましたが、automake は NEWS, README, AUTHORS, ChangeLog の有無をチェックするので空ファイルでいいのでとりあえずこれらを作っときます。
% touch NEWS README AUTHORS ChangeLog % ls AUTHORS ChangeLog NEWS README.bhl configure.in CVS/ Makefile.am README autoscan.log xmessage+.c
automake する
最後に下記コマンドで configure や Makefile.in を生成します。
% aclocal && autoheader && autoconf && automake --add-missing automake: configure.in: installing `./install-sh' automake: configure.in: installing `./mkinstalldirs' automake: configure.in: installing `./missing' automake: configure.in: installing `./config.guess' automake: configure.in: installing `./config.sub' automake: Makefile.am: installing `./INSTALL' automake: Makefile.am: installing `./COPYING' % ls AUTHORS Makefile.am aclocal.m4 config.sub@ mkinstalldirs@ COPYING@ Makefile.in autom4te.cache/ configure* stamp-h.in CVS/ NEWS autoscan.log configure.in xmessage+.c ChangeLog README config.guess@ install-sh@ INSTALL@ README.bhl config.h.in missing@
これで ./configure && make できる状態になりました。
% ./configure && make checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking whether make sets $(MAKE)... yes (中略) gcc -DHAVE_CONFIG_H -I. -I. -I. -DXTHREADS -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/X11R6/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/include/freetype2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -g -O2 -c xmessage+.c gcc -g -O2 -o xmessage+ xmessage+.o -Wl,--export-dynamic -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangoxft-1.0 -lpangox-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 % ls xmessage+ xmessage+*
ちゃんとバイナリ xmessage+ が出来てました。ふぅ。
この automake で作った Makefile には distcheck ってターゲットがあって、make distcheck すると tar ball でパッケージを作ったうえでいろいろテストをやってくれます。便利。
% make distcheck rm -rf xmessage+-0.1 mkdir xmessage+-0.1 chmod 777 xmessage+-0.1 (中略) rm -rf xmessage+-0.1 ============================================== xmessage+-0.1.tar.gz is ready for distribution ============================================== % ls *.tar.gz xmessage+-0.1.tar.gz
おまけ
実はこの時点で README は touch で作っただけなので内容が空です。tar ball にまとめる際に README.bhl -> README に変換してやる必要があります。このようなパッケージ作成時に追加したい処理には dist-hook ターゲットを使います。今回の場合は Makefile.am に以下を追加。
dist-hook: -test -e $(srcdir)/README.bhl \ && bhl2txt -f $(srcdir)/README.bhl -o $(srcdir)/README test -e $(distdir)/README || cp $(srcdir)/README $(distdir)
パッケージには README.bhl は含まずに、生成した README だけを同梱したいのでちょっと小細工してますが、まぁこんなかんじです。
それと、コンパイラが gcc の時には -Wall オプションを追加したい、といった場合には
% diff configure.in.old configure.in --- configure.in.old 2006-02-19 10:59:24.007791000 +0900 +++ configure.in 2006-02-19 12:35:32.712815048 +0900 @@ -9,6 +9,9 @@ # Checks for programs. AC_PROG_CC +if test "$GCC" = "yes"; then + CFLAGS="$CFLAGS -Wall" +fi # Checks for libraries. PKG_CHECK_MODULES(XMESSAGE_, gtk+-2.0) zsh: exit 1 diff -u configure.in.old configure.in
こんなんを configure.in に加えとくといいようです。
いろいろ書いてみたけど合ってるのかなあ。なんか嘘いっぱいな予感がしないでもなかったり。