configureファイルの書き方

C言語のプロジェクトでautoconfやらautomakeやら使ってconfigureスクリプトつくる手順を勉強したのでメモっときます。
なお、MacOSX "Mountain Lion"では、たとえXcodeを入れてあっても下記で使用するautoconfやautomakeがないようです。以下のサイトに従ってこれらをインストールする必要があります。
Autoconf and Automake on Mac OS X Mountain Lion

MacOSX Mountain Lion での下準備

一応説明抜きで実行する内容を抜粋して記録
MacOSX Mountain Linon用。Linux等の場合はそれぞれのパッケージ管理ツールから入れるのがよいと思います。

$ curl -OL http://ftpmirror.gnu.org/autoconf/autoconf-2.68.tar.gz
$ tar xzf autoconf-2.68.tar.gz
$ cd autoconf-2.68
$ ./configure --prefix=/usr/local/my_build_tools
$ make
$ make install
$ export PATH=/usr/local/my_build_tools/bin:${PATH}

$ cd ..
$ curl -OL http://ftpmirror.gnu.org/automake/automake-1.11.tar.gz
$ tar xzf automake-1.11.tar.gz
$ cd automake-1.11
$ ./configure --prefix=/usr/local/my_build_tools
$ make
$ make install

$ cd ..
$ curl -OL http://ftpmirror.gnu.org/libtool/libtool-2.4.tar.gz
$ tar xzf libtool-2.4.tar.gz
$ cd libtool-2.4
$ ./configure --prefix=/usr/local/my_build_tools
$ make
$ make install

これにより"/usr/local/my_build_tools/bin"以下に各種ツールがインストールされます。
必要に応じてパスを通して使用します。

ソースファイルを生成

とりあえず、test.cにmain()をおいて、print.hとprint.c に print(char *msg) という関数をおくことにします。
ソースファイルの置き場所はトップディレクトリ以下の src 以下。

src/print.h

void print(char *msg);

src/print.c

#include <stdio.h>

void print(char *msg)
{
  printf("say: %s\n", msg);
}

src/test.c

#include <stdio.h>
#include "print.h"

int main()
{
  print("hello configure!");
  return 0;
}

Makefile.amを作る

ここでMakefile.amを作りますが、これはディレクトリごとに必要となります。
このサンプルプログラムの場合は現時点でトップディレクトリと"src"ディレクトリにひとつづつ必要ということになります。

まずはプロジェクトのトップディレクトリに以下のようなMakefile.amというファイルを作ります。
ここでは、トップディレクトリでは特にやることはないのでソースファイルのある"src"ディレクトリをサブディレクトリとして指定しています。

Makefile.am

SUBDIRS = src

続いて以下のようにsrcディレクトリ以下にMakefile.amというファイルを作ります。
src/Makefile.am

bin_PROGRAMS = test
test_SOURCES =  test.c print.h print.c

configure.inの生成、編集

プロジェクトのトップディレクトリでautoscanを実行してconfigure.inのひな形を作ります。

$ autoscan

上記コマンドを実行すると、カレントディレクトリに"configure.scan"というファイルが作られます。ので、これをconfigure.inというファイル名に変更して編集します。

$ mv configure.scan configure.in
$ emacs configure.in &

編集後のconfigure.inは以下の通り。
編集箇所は

  1. AC_INITの引数をプロジェクトにあわせて修正する
  2. AM_INIT_AUTOMAKEを追加
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.68])
AC_INIT([test], [0.1], [hoge_tara@mail.com]) # 各種プロジェクトの情報に修正
AM_INIT_AUTOMAKE                             # AM_INIT_AUTOMAKEを追加
AC_CONFIG_SRCDIR([src/print.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_CONFIG_FILES([Makefile
                 src/Makefile])
AC_OUTPUT

Makefile.in を生成

あとはautoheader, aclocal, automakeを実行して本命のconfigureスクリプトを生成します。

$ autoheader
$ aclocal

続いてautomake

$ automake --add-missing --copy

Useless use of /d modifier in transliteration operator at /usr/local/my_build_tools/share/automake-1.11/Automake/Wrap.pm line 58.
configure.in:6: installing `./install-sh'
configure.in:6: installing `./missing'
src/Makefile.am: installing `./depcomp'
Makefile.am: installing `./INSTALL'
Makefile.am: required file `./NEWS' not found
Makefile.am: required file `./README' not found
Makefile.am: required file `./AUTHORS' not found
Makefile.am: required file `./ChangeLog' not found
Makefile.am: installing `./COPYING' using GNU General Public License v3 file
Makefile.am:     Consider adding the COPYING file to the version control system
Makefile.am:     for your code, to avoid questions about which license your project uses.

おっと、NEWS,README,AUTHORS,ChangeLogが無いぞってしかられてしまいました。
あとでちゃんと作るとして、とりあえず空のファイルを作っておきます。

$ touch NEWS README AUTHORS ChangeLog

再度automakeします

$ automake --add-missing --copy

今度はうまくいきました。カレントディレクトリにMakefile.inが作られたことを確認します。

configure スクリプトを生成

automakeを実行してconfigureスクリプトを生成します。

$ autoconf

カレントディレクトリ以下に"configure"という実行可能ファイルが生成されたことを確認します。

試しにビルドしてみる

早速、生成された./configureスクリプトを使ってMakefileを生成、ビルド、インストールまで一気にやってみます。

$ ./configure

checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... ./install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
....

configureスクリプトによるシステムチェックが走ります。
これが終わるとMakefileがカレントディレクトリにできているはずですので確認します。

makeを実行します。

$ make

make  all-recursive
Making all in src
gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT test.o -MD -MP -MF .deps/test.Tpo -c -o test.o test.c
mv -f .deps/test.Tpo .deps/test.Po
gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT print.o -MD -MP -MF .deps/print.Tpo -c -o print.o print.c
mv -f .deps/print.Tpo .deps/print.Po
gcc  -g -O2   -o test test.o print.o  
make[2]: Nothing to be done for `all-am'.

うまくいったようです。"src"ディレクトリに"test"という実行可能ファイルができていることを確認します。
試しに実行してみます。

./src/test 
say: hello configure!

ちゃんと動作しました。

続いてインストールしてみます。

$ sudo make install

configureにprefixオプションを渡していない場合は/usr/local/bin/test にインストールされます。

$ /usr/local/bin/test
say: hello configure!

ちゃんとインストールされました (ワーイ

おまけ:bootstrapファイル

ファイル追加した場合などはautoheaderから実行する必要があるっぽいので下記のようにスクリプトにしておけば楽かなって。

emacs bootstrap &

./bootstrap

#!/bin/sh

autoheader
aclocal
automake --add-missing --copy

実行権限を与えて実行してみる

$ chmod 755 bootstrap
$ ./bootstrap

ファイルを追加したりしてプロジェクトの構成が変化した場合はMakefile.amにファイル名を追加して./bootstrapを実行すればMakefile.inやconfigureを作り直してくれます。たぶん。