初心者への GNU autoconf のススメ
Lynx Optimized Pages!
This page is written in Japanese.
145585 accesses since 2001/07/27.
17 accesses per day.
[ TOP ]
このドキュメントは、初心者とはいえ C プログラミングができて Makefile を記述することが 可能な人を対象にしています。
「使ってみたいけど、とっかかりがわからない」という人に読んでほしいです。
GNU の autoconf の使い方を知らなくても、GNU のツールを インストールするときに
% ./configure % make % su $ make install
とするのがほとんどでしょう。この簡便さをすべてのソフトウエアのコンパイルでも享受したい とは思いませんか。そんなあなたのために「どのようにすれば ./configure; make 一発でコンパイルが 終わるパッケージを書けるようになるか」を書いていきます。導入ガイドみたいなもんです。
次のアーカイブを用意します。
ほとんどが perl スクリプトなので perl が必須です。また、一部のスクリプトで awk を使っているので awk も必須です。
dejagnu-1.3 は入れても入れなくてもいいです。厳密な動作チェックをしたい人は入れましょう。
各プログラムのインストールは通常の GNU パッケージをインストールするときと同じです。
まずは試しに、こんなソースを書いてみました。
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { char pathname[1024], *envname; getwd(pathname); if (argc == 1) { if ((envname = getenv("HOME")) != NULL) { if (strncmp(pathname, envname, strlen(envname)) == 0) { *pathname = '~'; strcpy(pathname + 1, (char *)(pathname + strlen(envname))); } } } else if ((argc != 2) || (*argv[1] != '-') || (*(argv[1] + 1) != 'l') || (*(argv[1] + 2) != '\0')) { puts("usage: pwd [-l]"); return 1; } puts(pathname); return 0; }
C 入門のようなソースですが、このままではコンパイルできない OS がまだまだ世の中にはあります。 このソースをいじりながら configure を作成するためのテンプレート configure.in と Makefile のテンプレート Makefile.in を作っていきます。
ひとまずこのソースのあるディレクトリで Makefile.in を作成しておきます。
% touch Makefile.in
今はこれでじゅうぶんです。そして autoscan を実行すると、configure.scan が作成されます。これが configure.in の雛型になります。 あくまでも雛型なので、さまざまな条件が足りません。
configure.scan を configure.in にコピーして configure.in をいじります。
% cp configure.scan configure.in
C でプログラムを組むので、Checks for programs. のところに AC_PROG_CC を付け加えて (dnl は m4 マクロのコメントです)
dnl Checks for programs. AC_PROG_CC
autoconf を実行すると、configure が作成されます。さっそく実行してみましょう。
% ./configure
Makefile はできたけど空です。このままでは始まらないので、Makefile を書くように Makefile.in を 書いてみましょう。
# # Makefile for autoconf tutorial # CC = @CC@ DEFS = @DEFS@ LIBS = @LIBS@ SRCS = pwd.c OBJS = $(SRCS:.c=.o) PROG = pwd all: $(PROG) $(PROG): $(OBJS) $(CC) -o $@ $(OBJS) $(LIBS) .c.o: $(CC) $(DEFS) -c -o $@ $< clean: rm -f $(OBJS)
@CC@ とか @DEFS@ などとなっているところがミソです。さっき configure.in に付け加えた AC_PROG_CC で検出された C コンパイラが @CC@ と置き換わります。@DEFS@ はあとで述べるシンボルに、@LIBS@ は検出されたライブラリに置換されます。
できあがった Makefile を使って make してみると、うまくいくシステムと warning を吐いたりして うまくいかないシステムがあると思います。
configure.in を改めて見ると AC_ で始まるマクロがいくつか定義されています。 AC_CHECK_FUNCS に羅列されている関数を持っていないシステムでは、このままではコンパイル できないので修正する必要があります。カレントディレクトリを取得する関数が getcwd() しかないシステムのために、getcwd() も使って書き直します。
dnl Checks for library functions. AC_CHECK_FUNCS(getcwd getwd)
このとき、どの関数を持っているかを判別するためのシンボルが HAVE_関数名 というように定義されるので、それを利用します。関数名はすべて大文字に変換されて定義されます。 Makefile を見てみると、@DEFS@ が置き換わっているのでわかるでしょう。
#ifdef HAVE_GETCWD getcwd(pathname, sizeof(pathname)); #else # ifdef HAVE_GETWD getwd(pathname); # endif #endif
■
デフォルトでリンクされる libc.a 以外のライブラリに含まれている関数を使っている場合には AC_CHECK_LIB を使います。第一引数がライブラリ名、第二引数が関数名です。
たとえば socket() が libsocket.a に含まれている OS では AC_CHECK_FUNCS(socket) で失敗し、LIBS に -lsocket が追加されないのでリンク時にエラーになって しまいます。これを避けるには configure.in に
dnl Checks for libraries. AC_CHECK_LIB(socket, socket)
と書きます。
中級者向け:
ネットワーク周りのライブラリのチェックには AC_PATH_XTRA を使って @X_EXTRA_LIBS@ を追加すると
いう手もありますが、X 使わないのに…という向きには CF_NETLIBS
というものがあります。これを aclocal.m4 に書いておいて AC_FOOBAR と同じ感じで
CF_NETLIBS と書いておけばチェックしてくれます。
(Lynx current の aclocal.m4 からのパクり。 AC_HAVE_LIBRARY で warning が出るけど無視してかまいません)
■
configure.in を修正したら autoconf の実行からやり直しです。
GNU のソースを見ると、@DEFS@ が -DHAVE_CONFIG_H になっていて、-D... の羅列になっていたものが config.h にまとめて定義されているものがあります。Make 時のだらだらと長いコマンド行が嫌いな人、 ファイルの依存関係をきちんと記述する人にはこちらのほうが向いていると思います。
config.h を作るためには configure.in に AC_CONFIG_HEADER(config.h) を追加(AC_INIT の直後がいいかも)して、autoheader を実行して config.h.in を作る必要があります。 AC_CONFIG_HEADER(conf.h) にすると、conf.h.in が生成されます。
ここで注意。
#ifdef HAVE_CONFIG_H # include "config.h" #endif
とソースに書くのを忘れると、かなりマヌケです。
また、AC_CONFIG_HEADER で指定したヘッダももちろん configure.in に依存しているので、依存関係を 反映させるために Makefile.in も修正しましょう。
config.h.in: configure.in autoheader
以上のループの繰り返しで autoconf を利用したプログラミングが終わります。だいたいの感じは つかめたでしょうか?
実際にはいろいろな OS の上でコンパイルしてみるのが一番ですが、なかなかそうもいきません。 autoconf を使うのだから、いろんなところにばらまいて試してもらって feedback をもらうのが楽です :-) 経験を積むうちに、だんだんとコツがつかめてくるので、がんばりましょう。
とかいうわたしも附属の info をまったく読まないで GNU パッケージについてくるソースを読んで 使い方を覚えたので、まだまだ修行中です。ツッコミや使ってみて詰まったところなどがありましたらメイルください。
このページを作るきっかけを与えてくださり、autoconf ぼくらの約束、もっと使おう autoconf: tips 集を 開示してやる気を出させてくれた いとぢゅんさん。 これらのページが表に出なかったら、まだまだできてませんでした。本当にありがとうございます。
$Id: autoconf.html,v 1.16 1999/09/30 01:45:42 sharl Exp sharl $