nullnull7の日記

プログラミング、写真、旅、その他日常について。

autoconfを使ってconfigureを作って配布

「./configure, make, make installってよくやるけど、あれ何やってるの?」
っていうレベルから始まるautoconfを使ったconfigureの作り方&配布の仕方
(自分無知すぎて怖い



■やりたいこと
作ったcppファイルを、配布のために「./configure, make, make install」っていう呪文を唱えて簡単にインストールできるようしたい
つまりはconfigureを作成したい。

■makeってなに?
まずはここから。
makeは、同ディレクトリ内にあるmakefileを参照して、書かれた通りにコンパイルするコマンド。
コンパイルに最適化されたシェルスクリプトみたいなイメージ。
普通にコンパイルを行うmakefileの書き方の例は以下。

test.o : test.cpp
        g++ test.cpp -o test.o

単に1つのファイルをコンパイルするだけならmakeする必要はないけれど、複雑な依存関係をもっている複数のファイルを使ってコンパイルするとき、手作業でこれをやるといちいち面倒なので、makeを使う。makefileを一度作れば、その後はmake一発で複数ファイルをコンパイルできる。
依存関係にあるファイルの実行ファイルが既にできている時は、(タイムスタンプを見たりしつつ)コンパイルはしないで無駄な処理をしない…とか、そういう最適化も自動でしてくれる。
make installするとコンパイルされた実行ファイルがインストールされる。

makefileの詳しい作り方は以下のURLで
http://x68000.q-e-d.net/~68user/unix/pickup?makehttp://www.creatology.jp/unix/make.html


■じゃあconfigureってなに?
上に書いたように、他人にソースを配布するときは、お手軽にコンパイルができるmakefileを配布してやりたいところ。
しかし、相手の環境によってコンパイルの仕方が変わってしまうかもしれないので(ライブラリが見つからない〜とか)、単にmakefileを配布しても上手くいかない。
そこで登場するのがconfigure。configureは実行すると実行した環境に合ったmakefileを生成してくれるシェルスクリプト
これをソースコードと一緒に配布することで、「./configure, make, make install」で一発インストールが可能になる。

configureを手作業で書いてもいいのかもしれませんが(書けるのかよくわからない)
世の中にはconfigureを自動で生成してくれるツール(autoconf)があるので、それを使ってconfigureを作成していきます。


■autoconfの使い方
(autoconfのインストールとかは省略します)
基本的に、以下URLに書いてある通りに進めれば、とりあえず作れる。
http://yosilove.blog.shinobi.jp/Entry/866/
もう少し詳しい説明
http://www.spa.is.uec.ac.jp/~kinuko/slidemaker/autotools/
以下で処理の流れを概説します。

1. configure.inを生成する

$autoscan
$mv configure.scan configure.in
$emacs configure.in

(説明)

  • configure.inは生成するconfigureの大元となる設定ファイル。このファイルの指示通りに、autoconfがconfigureを生成してくれる。
  • configure.inを手打ちしてもいいが、autoscanで雛形が作れるのでこれを使う(生成ファイルはconfigure.scanなのでリネームする)
  • autoscanのバージョンその他の条件で生成される雛形が違ってくるが、とりあえずリンク先通りに打てばOK
  • マクロの意味は2番目のサイトに書いてあります

2. Makefile.inを生成する

$emacs Makefile.am
$aclocal
$autoheader
$touch NEWS README AUTHORS ChangeLog
$automake -a -c

(説明)

  • Makefile.inは生成するMakefileの大元と(ry
  • これもautomakeを使って自動で作れるので、automakeの設定ファイルとしてMakefile.amを作る
    • Makefile.amの書き方は上記サイト参照。
    • 必要なソースコードは半角スペース区切りで_SOURCESに、その他必要なファイル(ディレクトリもOK)はEXTRA_DISTと打って、その後に半角スペース区切りで記入
  • その他、もろもろコマンド打つと必要なファイルが自動で作成され、最後にautomakeするとMakefile.inが生成されます。
    • -a (--add-missing)オプションは足りないファイルを 勝手に生成してくれるオプション。-c (--copy)は、 足りないファイルを生成する時に リンクではなくコピーしてくれるオプション。配布を考えるなら-a -cで。

3. configureを生成する

$autoconf

これで終わり。


4. 配布したいとき
make distとすると、必要なファイル(Makefile.amに書き込んだもの&その他)が自動的に圧縮されます。
バージョン情報などは、configure.inのAM_INIT_AUTOMAKE。
エンドユーザーが利用する際は

% (配布パッケージを入手)
% tar zxf hoge-0.1.0.tar.gz
% cd hoge-0.1.0
% ./configure
% make
% (rootユーザに変更)
% make install

となります。


■発展 mecabのライブラリをリンクさせてコンパイルする
まず、CFLAGSやLIBSを指定(コンパイルオプションの-l、-I、-Lを指定)する方法を紹介します。
これは、単純にconfigure.inでLIBSとCFLAGSを書き換えるだけでokです。

LIBS="$LIBS -L/hoge/hooge/"
CFLAGS="$CFLAGS -I/foge/"

※=との間にスペースいれちゃダメ。

さて、mecabを使用するコードをコンソール上でコンパイルする際は、以下のように書いていました。

g++ main.cpp  `mecab-config --cflags` `mecab-config --libs`

mecab-configの内容を反映させるためには、configure.inを以下のように書きます。

# Checks for libraries. 
AC_PATH_PROG(MECAB_CONFIG, mecab-config, "none")
if test x"$MECAB_CONFIG" = x"none"; then
mecab_exists=no                                                                       
MECAB_LIBS=""
MECAB_CFLAGS=""
else
mecab_exists=yes
MECAB_LIBS=`$MECAB_CONFIG --libs`
MECAB_CFLAGS=`$MECAB_CONFIG --cflags`
fi
AC_SUBST([MECAB_CFLAGS])
AC_SUBST([MECAB_LIBS])
LIBS="$LIBS $MECAB_LIBS"
#CFLAGS="$CFLAGS $MECAB_CFLAGS" ※cflagsじゃないよ
CXXFLAGS-"$CXXFLAGS $MECAB_CFLAGS"

AC_PATH_PROGで、mecab-configというというコマンドが存在したらそのパスがMECAB_CONFIGという変数に格納されます。
そして、AC_SUBSTでシェル変数を出力変数に変換します。以上のように、自分で定義した変数をmakefile内で使いたい時は、これをしておきます。
mecab-config --cflagsを参照するのでついついCFLAGSを書き換えようとしてましたが、g++を使うので当然CXXFLAGSを書き換えます……自分の環境では-Iオプションをつける必要がなかったので、他人の環境でやるまでこのミスに気付かなかったorz


ここまでたどり着くのにめちゃ時間かかった……。
他人のconfigure.inを見て勉強するのがオススメです。

まとめ:
実行ファイルを簡単に作ってくれるのがmake + makefileで、
makefileを環境にあわせて作ってくれるのがconfigureで、
configureを自動で作ってくれるのがautoconf + configure.in, makefile.inで、
この2つを半自動で作ってくれるのがautoscan, automake。