Autotoolsについてのメモ

このメモはGNU Autotoolsのautoconfとautomakeとを使って フリーソフトウェアの配布用パッケージを作る方法を解説している。 FortranのプロジェクトにAutotoolsを使う場合の注意点も書いてある。


Table of Contents:

はじめに

たいていのGNUのフリーソフトウェアは次のようにtar ballを展開して、 ./configure && make && make installとすることで簡単にソースからインストールすることができる。

$ tar xf feram-X.YY.ZZ.tar.xz
$ cd feram-X.YY.ZZ
$ mkdir build   # Use build directory.
$ cd build
$ ../configure --help
$ ../configure
$ make
$ make check
$ sudo make install
$ make installcheck

AutotoolsはそんなGNU流のフリーソフトウェアパッケージの 構築を半自動化するための開発者用のツールである。最終目的はmake distcheck で foo-1.2.tar.gzなどという[パッケージ名]-[version].tar.gz 形式のパッケージが自動生成できるようになること。

注意: Autotoolsは開発者用のツールである。パッケージfoo-1.2.tar.gzのユーザは そのマシンにAutotoolsをインストールする必要はないし、Autotoolsについて知っている必要もない。

必要なもの

GNUの2つのパッケージautoconfとautomakeとを開発用のマシン にインストールしておく必要がある。また、GNU makeやbashそして GNU M4も最新のものを用意したほうがよい。

たいていのLinuxディストリビューションにはこれらのツールの パッケージがある。たとえばDebianやUbuntuなら

$ sudo apt-get install autoconf automake libtool autoconf-doc libtool-doc

でインストールできる。Mac OS X で Mac Ports https://www.macports.org を使っているなら

$ sudo port install automake autoconf

でインストールできる。

コマンドとファイル

Autotools (autoconf and automake) では Fig. 1 に示すとおり いくつかのコマンドとファイルとによって処理が進む。 前半の茶色の太い破線で囲まれた部分をautoreconfが自動的にやってくれる。 以下に関連すコマンドとファイルを列挙した。

doc/figures/autoreconf-automake-process.svg
Figure 1: Autotools(autoconf と automake)による作業の流れ。 実際は茶色の太い破線で囲まれた部分をautoreconfが自動でやってくれる。 (この図はクリエイティブコモンズライセンス[CC-BY-SA-3.0]の下に http://commons.wikimedia.org/wiki/File:Autoconf-automake-process.svg として配布されているJdthoodによるオリジナルに Takeshi Nishimatsuが茶色の太い破線と"autoreconf"の文字を描き加えたもの。 ファイル名はautoreconf-automake-process.svgとした。)

関連コマンド

autoscan       Autotoolsの利用を開始するときに1回だけ実行するコマンド。
               configure.acの雛形configure.scanを生成してくれる。
autoreconf     定番。-vオプションを付けて実行すれば何をしているのかがわかる。
               以下のコマンド自動的に再実行してくれる。
autoconf       configure.ac を元に configure を生成。
automake       Makefile.amからMakefile.inを生成。
               オプション --add-missing を付けて実行すると install-sh, missing, test-driver
               などの必要なスクリプトを /usr/share/automake-1.14/ からシンボリックリンクしてくれる。
autoheader     config.h.in を作ってくれる。
aclocal        aclocal.m4を作ってくれる。

関連するファイルとディレクトリ

configure.ac   configureの雛型。自分で書く。
Makefile.am    Makefileの雛型のMakefile.inの雛型。自分で書く。
config/gnu/    ファイルがごちゃごちゃ出来てイヤな場合はMakefile.amに
               AC_CONFIG_AUX_DIR(config/gnu)と指定するとmissing等がそこに置かれる。
config.guess   Makefile.amにAC_CANONICAL_TARGETなどと書くとautomake --add-missingが
               用意してくれるOSやCPUの自動判別をしてくれるスクリプト。
config.h.in    config.hの雛型。autoheaderによりMakefile.amやconfigure.acから自動的に作られる。
config.h       configure.acにAC_CONFIG_HEADERS([config.h])と指定。
               ないとコンパイルオプションが長くややこしくなるので、使ったほうがよい。
config.log     configure の実行時のログ。問題が起きたら読む。
config.status  configure を実行すると出来るスクリプト。foo.in から foo を作るのは実はこいつ。
install-sh     automake --add-missing が用意してくれるスクリプト。make installのときに使われることがある。
missing        automake --add-missing が用意してくれるスクリプト。忘れ物を教えてくれる。
depcomp        automake --add-missing が用意してくれることのあるスクリプト。ファイルの依存関係を自動的に調べてくれる。
test-driver    Makefile.amにTESTSの項目がある場合、automake --add-missing が用意するスクリプト。
               make checkのときに使われ、カラフルな表示やログファイルの書き出しをしてくれる。

使用方法

メモ

Fortranについてのメモ

手順

configure.ac, Makefile.am, src/Makefile.amを書いて、

$ autoreconf -v
$ automake --add-missing   # 初回にautoreconfで実行を要求されたとき
$ autoreconf -v            # ☆
$ ./configure
$ make                     # ソースの編集など開発を進め、最後にmakeでコンパイルできることを確認
$ make distclean           # Makefileなどをきれいさっぱり消す
$ ./configure
$ make distcheck           # 配布用パッケージをテストしてから作成(オプションは DISTCHECK_CONFIGURE_FLAGS で指定できる)
$ make dist                # 配布用パッケージの作成

新たにconfigure.ac, Makefile.am, src/Makefile.amを書き変えたら☆からやり直す。 他に

$ make clean               # makeでできたファイルを消去
$ make check               # コンパイルしたバイナリをテスト(後述)
$ sudo make install
$ make installcheck        # インストールしたバイナリをテスト(後述)
$ sudo make uninstall      # make installしたファイルの消去

などが便利。

make checkでテストの自動化

src/Makefile.amに

TESTS=foo.sh bar baz

と書いておけば

$ make check

でsrc/の中でfoo.shとbarとbazとがテストとして実行される。 ソフトウェアのテストを自動化できる。 foo.shとbarとbazとはカレントディレクトリになければsrcdirの中も探されるので、 build directoryの中でもテストができる。 ただし、foo.shは自動的にパッケージに入れてくれるわけではないので、 Makefile.amの中のEXTRA_DISTに次のように加えておく必要がある。

EXTRA_DIST = README foo.sh

テストのログがfoo.sh.logとbar.logとbaz.logとに、 テストの結果がfoo.sh.trsとbar.trsとbaz.trsとに保存される。 テスト全体のまとめがtest-suite.logに保存される。

一部のテストだけを選択的に行いたい場合は

$ make check TESTS='foo.sh bar'

とTESTS変数で指定するする。

テストスクリプトの中でsrcdirを明示的に参照する必要がある場合は$srcdirを用いる。

make distcheck とすると、上記テストとさらにファイルの過不足のチェックして、最終的にパッケージを作ることができる。 make distcheck で作るパッケージは、簡単かつ自動的に in-source build, out-of-source build のどちらも可能になる。

automakeのオプション

automakeのオプションはconfigure.acの中にAM_INIT_AUTOMAKEで指定する。例えば

AM_INIT_AUTOMAKE([1.14.1 no-dist-gzip dist-xz tar-pax foreign])

では、automakeのバージョン1.14.1以上を使用することを強制し、 パッケージをtar.gzでなくtar.xzで作るように指定している。 また、長いディレクトリ名/ファイル名でもパッケージに入るようなtarのオプションを指定している。 foreignを指定しておけば、NEWS, COPYING, AUTHORS, ChangeLog, READMEのファイルが勝手に作られるのを防ぐことができる。 ライセンスとしてGLPを採用するとしても、ここにforeignを指定して、 パッケージに含めたいファイルはMakefile.amのEXTRA_DISTに明示的にリストアップするのがよいだろう。

Autotools Mythbuster の該当ページ https://autotools.io/automake/options.html が詳しい。

インストールしたバイナリのテスト make installcheck

さらにAM_INIT_AUTOMAKEにstd-optionsを加えておけば

$ sudo make install

でバイナリをインストールした後に

$ make installcheck

とすると、そのインストールしたバイナリで GNU的なコマンドラインオプションの--helpと--versionとをテストできる。 エラーが起きればログが残こされ、テストが成功したなら何も残らない。

Makefile.amの中にinstallcheck-local:ルールを書いておけばそれも実行される。

installcheckは一般的なテストではないので、make installcheckとしても何も実行されないパッケージも多い。

コンパイラとコンパイラオプションの設定と決定

C, Fortran, C++コンパイラとそのオプションはそれぞれ AC_PROG_CC(), AC_PROG_FC(), AC_PROG_CXX() が configure.ac の中で決定する。コンパイラは CC, FC, CXX に、 コンパイラオプションは CFLAGS, FCFLAGS, CXXFLAGS に セットされる。 コンパイラオプションのデフォルトはたいてい -g -O2 または -O2 である。configure.ac の中で デフォルト以外に独自に設定したい場合には

cflags_save="$CFLAGS"
AC_PROG_CC()
CFLAGS="$cflags_save"
test -n "$CFLAGS" || CFLAGS="-g -Wall -O3"

などとAC_PROG_*()の前後でsave/restoreし、その後に独自設定をする。

configureにオプションや変数を与える方法

configureにオプションや変数を与える方法は

$ ./configure --help

で表示されるように、

$ ./configure --enable-openmp --with-lapack=mkl CPPFLAGS=-I/home/t-nissie/include

などと

の3つがある。それぞれconfigure.acの中で

と設定する。

configureに与えられた引数はconfig.logの先頭に記録されるので、後々の再確認に便利である。 ただし、''や""のクォーテイションは消えてしまう。

Manpage

パッケージにUNIXのmanシステムの流儀に則って書いたmanpageを同梱する場合は、Makefile.amに

man_MANS = xtalgrowth.1 crystal_growth.7
EXTRA_DIST = README COPYING $(man_MANS)

などと書く。ここで数字の1や7はmanpageのセクション番号で1〜9の値をとり、 その番号にしたがってmanpageは/usr/local/share/man/man1/などにmake installでインストールされる。 manpageはデフォルトでパッケージに同梱されないのでEXTRA_DISTに加えておく。

Autotoolsの使用方法として参考になるパッケージ

LHa for Unix

シンプル。 http://www2m.biglobe.ne.jp/~dolphin/lha/lha-unix.htm

ntp

大規模。libtoolも使われている。 http://support.ntp.org/bin/view/Main/WebHome

xtalgrowth

小規模。Cで書かれたX Window Systemのアプリケーション。 http://loto.sourceforge.net/xtalgrowth/

feram

小規模。Fortranで書かれている。 http://loto.sourceforge.net/feram/

Ruby

Rubyは独特で高度な方法でconfigureを生成している。安易に真似すべきではないかもしれない。 configure.inとMakefile.inそしていくつかのツールが独自に書かれていて、autoconfのみを使う。 configureでGNU makeでもBSD makeでもnmakeでも有効なポータブルなMakefile(とGNUmakefile)が生成される。 ソースは、src/サブディレクトリではなく、メインディレクトリに置かれている。 make V=1とverbosityを指定することで、makeの実行するコマンドの詳細が表示されるようになっている。 https://github.com/ruby/ruby

Autotoolsトラブルシューティング

Autotoolsは強力なツールで、make distcheckが動くようになればほぼすべてがうまく進むようになる。 しかしながら、トラブルに遭遇する場合もある。 Autotoolsやconfigure, makeに関連するバグの発見方法をいくつか紹介する。

configureとmakeとの高速化

大規模なプロジェクトではconfigureとmakeとにかかる時間が増大し、開発者をイライラさせる。 特にconfigureスクリプトは並列化が難しく、簡単には高速化できない。 以下にconfigureとmakeとの高速化の手法とそれらを解説しているページへのリンクを揚げた。

configureの高速化

makeの高速化

Autotoolsの代わりになるもの

改良版のAutotoolsやより高速なmakeを目指していくつかのパッケージングツール/ビルドツールが開発されている。 CMake, SCons, MesonではFortranのプロジェクトもサポートされている。

新しいもの

古いもの

libtoolとは

Autotoolsの仲間には他に libtool http://www.gnu.org/software/libtool/ がある。 共有ライブラリをビルドするときにautoconfとautomakeとともに使ってマシン依存性を解決する。 参考: http://klabgames.tech.blog.jp.klab.com/archives/1047107113.html

まとめ

autoconfとautomakeとの使い方を説明した。 configure.acとMakefile.amとを書くことによりパッケージの自動生成が可能になる。 複数のプラットフォームでMakefileを共通化できる。 これらGNU Autotoolsを活用すれば、簡単に配布用のフリーソフトウェアパッケージを作ることができる。

著者

西松 毅 (t_nissie{at}yahoo.co.jp)


Copyright © 2017 Takeshi Nishimatsu