第六回 GNU Autoconf (1)

Autoconf とは

おそらく読者は GNU Autoconf が大体どんなものか知っているだろう。 そう、configure を作って、簡単にコンパイルできる環境を作ってくれるものだ。 ときどきある誤解に、Autoconf を採用すれば、それだけでどこでもコンパイルできるようになる、というものがある。 これは大きな間違いであり、あくまで Autoconf はその助けになってくれるだけだ。 本当に移植性に優れたソフトウェアを作るには、それ相応の努力が必要である。 むしろ、Autoconf の利点は一貫したインターフェースで、よく確立した方法でソフトウェアを設定できることにある。

世の中にはいろんな種類の設定方法がある。例えば、

これを見て、うんざりする人は五万と居ることだろう。 これに対して、何らかの設定手段を提供しているものもある。 代表的なものは、Autoconf、Imake、Metaconfig だろう。 (ここでは、*BSD の ports のような移植性のないものは無視する。) なぜ Autoconf が Imake や Metaconfig より優れているかは、 Autoconf のマニュアル に書かれているが、筆者なりの見解を述べたい。

まず、Perl などで使われている Metaconfig だが、これの良くないところはユーザに意味の分からないことを大量に訊いてくることだ。 -d を付ければデフォルトで済ませることも出来るが、それではデフォルト以外の設定を行うのが極めて困難になる。 この「ユーザに理解できない答を求める設定」ほど邪悪なものはない。 だから、Metaconfig は絶対採用すべきでない。

また、(以前の) X 上でよく使われている Imake は、常にデフォルト状態でシステムを運用していると仮定しているところが悪い。 例えば、あなたは普通に付いているコンパイラとは違うコンパイラをインストールし、それを使ってコンパイルしたいとする。 果たして、Imake はこれに対応できるだろうか。 いや、できない。 なぜなら、Imake は設定情報を詰めこんだデータベースを使って、 Makefile を生成しているからだ。 そのため、そのデータベースと実際に使用するものが完全に一致しないと、破綻を来してしまうのだ。 また、変更を行うには Imakefile を手動で書き換えることが要求される。 非常によろしくない。

configure の仕組

まずユーザの視点から見た Autoconf の仕組について述べる。 一般的なやり方は、単に ./configure である。 これによって、Makefile や (場合によっては) config.h などが生成され、 後は make するのみである。 設定方法はいたって簡単であり、ある機能を有効にするには、--enable-feature とし、無効にするには、--disable-feature とする。 外部パッケージに関しては、--with-package とし、使いたくないなら、--without-package である。 実に簡単、エディタを起動する必要など全くない。 その他、インストールする場所を換えたければ、--prefix=dir で良いし、他にもたくさんのオプションを指定可能で、指定しなければデフォルトで済ませてくれる。 ユーザに理解し難い質問は、configure 自身が解決してくれる。

さて、このときに起きていることをもう少し詳しく見てみよう。 configure の実体は単なるシェル・スクリプトであり、移植性に優れた方法で書かれている。 このシェル・スクリプトはコマンド・ラインで指定されたオプションを解析し、もし指定されていなければデフォルトのままにしておく。 --with-package に対しては、with_package という変数に yes が設定され、--without-package に対しては、no となる。 同様に、--enable-feature の場合、 enable_featureyes が、 --disable-feature では no が入れられる。

こうしたユーザの設定を処理した後、その設定を考慮した上で、様々なテストを行い、その結果から最終的な設定を導き出していく。 最後にそれらの結果を示す変数の値で、Makefile.in などを置き換えて、 Makefile などを出力する。具体的には、

AC_SUBST(CFLAGS)

と指定していた場合、Makefile.in 中の

CFLAGS = @CFLAGS@

が置き換えられ、例えば、CFLAGS-O2 -g だったとすると、Makefile には、

CFLAGS = -O2 -g

と出力される。要するに、「オプションの解析 → テスト → 置換」という流れになっているのだ。

configure の生成

では、開発者側から見た Autoconf の仕組はどうなのか。 当然我々は configure を何らかの方法で生成しなればならない。 また、置換される前のテンプレートとなる、Makefile.inconfig.h.in (最後に .in を付けるのは Autoconf の流儀) も書かなければならない。

configure を生成するには、Autoconf のスクリプトで書いた、 configure.ac を用意する。そして、

$ autoconf

を実行すると、その configure.ac に対応した configure スクリプトが生成される。 しかし、いきなり configure.ac を書くのは大変なので、普通は autoscan を利用する。 これを実行すると、見付けられたファイル (Makefile など)を元に、テンプレートとなる configure.scan というファイルを作ってくれる。 だから、これを configure.ac に改名して、適宜編集すれば良い。 また、config.h.inautoheader を使うと勝手に作ってくれる。

Makefile.in などは残念ながら自分で書かざるを得ない。 これは Autoconf しかなかった頃はどうしようもないことだった。 しかし、しかしである。 我々はすでに Automake を持っていることを忘れてはならない! だからこそ、Automake を使いましょう、とこの連載で言い続けてきたのだ。 しかし、それはちょっと脱線になってしまうので、当面は Makefile.in のことは考えないことにする。

Autoconf のスクリプトとは一体?

configure.ac には Autoconf のスクリプトを書く、と上で言ったが、それはどのようなものなのだろうか。 その実体は、 M4 である。 M4 というのはマクロ・プリプロセッサであり、非常に強力なマクロ処理系なのである。 M4 そのものはあくまで言語としての環境を提供するだけなので、 Autoconf は数多くのマクロをあらかじめ用意しており、通常はそれらのマクロを使って書くことになる。 所詮人の書いたものを適当に組み合わせればいいだけなので、 M4 がどんな言語であるかは、実は知らなくてもほとんど(全く、とは言わないが)問題ない。

しかし非常に初歩的な部分だけ、ちょっぴり説明しておく。 マクロというのはあるトークンを展開するものである、というのが大前提となる知識だ。 そこで、どこを展開して、どこは展開しないで欲しいのか指定する必要性がある。 (これは変更可能だが) M4 では 「[」 と 「]」 で括ると、クウォートされることになっている。だから、

AC_CONFIG_FILES(Makefile)

とあった場合、AC_CONFIG_FILES はマクロの名前で、 Makefile はその引数となっているのだが、 Makefile をマクロとして展開すべきなのかどうか、これでは良く分からない。 もし Makefile というマクロが存在すれば展開されるだろう。 そのため、こういうときは次のように書く方が良い。

AC_CONFIG_FILES([Makefile])

これで AC_CONFIG_FILESMakefile がそのまま渡されることが保証される。 また、dnl から改行までがコメントとなる (configure には出力されない) ことも覚えていて欲しい。

dnl Output the result to Makefiles.
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile])

とりあえずはこの程度の知識で十分だろう。

まとめ

今回は Autoconf の全体像を掴み取った。 これでおそらく 前回の例 も多少は理解できるようになっただろう。 また、M4 については説明するつもりはないので、気になる人は自分でマニュアルを見て欲しい。 次回はこの続きで、Automake を前提とした configure.ac の書き方を説明するつもりである。 いつもの通り、質問、意見、批判などは okuji at enbug dot org まで送って欲しい。


次の回 / 前の回 / はっきんぐ・うぃず・ぐにゅー に戻る。


Copyright © 1999,2000,2007 Yoshinori K. Okuji

Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.

HackingWithGnu/GnuAutoconfPartOne (last edited 2007-03-15 13:41:41 by YoshinoriOkuji)