要点
- Autotoolは基本的に
autoconf
とautomake
とlibtools
。ただし、libtoolsはそんなに使われない? - autoconfはコンパイルするとき、環境依存になりやすい関数の差分を吸収する設定などを行う
- automakeはmakefileを簡単に作ってくれるツール
- libtoolsはライブラリを作るときに使用するツール。ライブラリはOSによって作られる拡張子などが変わるのでこのツールが使われる
ショートカット
- 何をコンパイルするかというautomake用の入力ファイル
Makefile.am
を作る - 最初に何を生成するかを示す
prefix_PRIMARY = (生成ファイル名)
を書く - 生成するファイルは何からできているかを
生成ファイル名_SOURCES = ソース一覧
を書く- ただし、ここで
.
は_
で置き換える。例えば、libtest.soならlibtest_so_SOURCESのように書く - 同様にコンパイル時のオプションは
生成ファイル名_CFLAGS = オプション
、生成ファイル_LDFLAGS = オプション
のように書く
- ただし、ここで
-
autoreconf --install
を実行する - 色々指示が出るのでconfigure.acを直す
- 例えば、libtoolsを作る場合は
- LT_INITを書く
- AM_PROG_ARを書く
- AC_CONFIG_MACRO_DIRS([m4])を書く
- 他にMakefile.amにACLOCAL_AMFLAGSに-l m4を書く
- さらに動的ライブラリを作りたい場合Makefile.amの
生成ファイル_LDFLAGS
次を追加する- -module
- -export-dynamic
- -shared
- -rpath $(libdir)
-
automake
を実行する
あとはconfigure; make
すれば完成ですが、ライブラリファイル(.a, .soなど)は.libディレクトリ配下に作成されます
動機
以前の記事でAutotoolsから目を逸らしたのですが、なんとなくやっておかねばならない気がしてきたので、チャレンジしてみます。
AutotoolsはGNU Build Systemとも言って、ソースをいろんな環境でコンパイルできるようにするツールのセットのようです。Wikipedia
ツール自体はつぎの3つから成り立っており、これらを組み合わせてconfigureやmakefileを作成するようです。
- autoconf
- automake
- libtools
しかし、日本語Wikipediaを見る限り、スゲェ難しそうです。
確かに環境依存しないコンパイルは大変ですが、どうして3つもツールが必要なのかとか色々考えてしまいます。
結局プログラマである自分は何を書けばいいのか、なぜ書かねばならないのか、その点を中心的に見ていこうと思います。
Step by Step
パッと見た感じ、
まずは次のステップをするようです。
- autoscanを実行し、configure.acを作る
- 1.を基にaclocalを実行し、aclocal.m4を作る
- 1.を基にautoheaderを実行し、config.h.inを作る
・・・と進めて行くようです。が、チュートリアルを見てみるとautoreconfなるコマンドがあり、
‘autoreconf’ Run all tools in the right order.
と書かれているのでとりあえず、コレをしてみます。
$ autoreconf --install
autoreconf: 'configure.ac' or 'configure.in' is required
チッ・・・
autoscanで環境をスキャンする
とりあえず、autoscanをしてみましょう。
マニュアルによると
Examine source files in the directory tree rooted at SRCDIR, or the current directory if none is given. Search the source files for common portability problems, check for incompleteness of `configure.ac', and create a file `configure.scan' which is a preliminary `configure.ac' for that package.
from http://manpages.ubuntu.com/manpages/yakkety/man1/autoscan.1.html
とりあえず実行すればいいのかな?
configure.scanが作られました。
mv configure.scan configure.ac
だけして再度autoreconf --install
を実行。
- autom4te.cache
- autoscan.log
- config.h.in
- configure
- configure.ac
が作られました。あとは、makefile.amを作るのが必要みたいですね。これだけは勉強しないと・・・
makefile.amを作る
チュートリアルとこのサイトに従って
SUBDIRS = src
noinst_LTLIBRARIES = libcheap_csv_reader.la
libcheap_csv_reader_la_SOURCES = record_read.c
で、再度autoreconf --install
実行。特に何も言われなかったのでautomakeを実行。
configure.ac: error: no proper invocation of AM_INIT_AUTOMAKE was found.
configure.ac: You should verify that configure.ac invokes AM_INIT_AUTOMAKE,
configure.ac: that aclocal.m4 is present in the top-level directory,
configure.ac: and that aclocal.m4 was recently regenerated (using aclocal)
automake: error: no 'Makefile.am' found for any configure output
automake: Did you forget AC_CONFIG_FILES([Makefile]) in configure.ac?
ダメ?とりあえずAC_CONFIG_FILES[(Makefile src/Makefile)]
と。チュートリアルにあったAM_INIT_AUTOMAKE([foreign -Wall -Werror])
を追加して再度実行。
configure.ac:11: installing './compile'
configure.ac:6: installing './install-sh'
configure.ac:6: installing './missing'
src/Makefile.am:1: error: Libtool library used but 'LIBTOOL' is undefined
src/Makefile.am:1: The usual way to define 'LIBTOOL' is to add 'LT_INIT'
src/Makefile.am:1: to 'configure.ac' and run 'aclocal' and 'autoconf' again.
src/Makefile.am:1: If 'LT_INIT' is in 'configure.ac', make sure
src/Makefile.am:1: its definition is in aclocal's search path.
automake: warnings are treated as errors
/usr/local/Cellar/automake/1.15.1/share/automake-1.15/am/ltlibrary.am: warning: 'libcheap_csv_reader.la': linking libtool libraries using a non-POSIX
/usr/local/Cellar/automake/1.15.1/share/automake-1.15/am/ltlibrary.am: archiver requires 'AM_PROG_AR' in 'configure.ac'
src/Makefile.am:1: while processing Libtool library 'libcheap_csv_reader.la'
src/Makefile.am: installing './depcomp'
autoreconf: automake failed with exit status: 1
おお、いっぱい出てきた。
とりあえず、1つ1つ潰していきましょう。
libtoolsの設定を修正する
configure.acにLT_INITを追加します。また、AM_PROG_ARも必要らしいので追記します。
再度autoreconf --install
実行。
glibtoolize: putting auxiliary files in '.'.
glibtoolize: copying file './ltmain.sh'
glibtoolize: Consider adding 'AC_CONFIG_MACRO_DIRS([m4])' to configure.ac,
glibtoolize: and rerunning glibtoolize and aclocal.
glibtoolize: Consider adding '-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
configure.ac:9: installing './ar-lib'
configure.ac:10: installing './config.guess'
configure.ac:10: installing './config.sub'
AC_CONFIG_MACRO_DIRS([m4])を追加してみるのを考えて見てと言われたので、追加します。
また、Makefile.amにACLOCAL_AMFLAGSに-l m4を追加してみてと言われたので追加です。
$ autoreconf --install
aclocal: warning: couldn't open directory 'm4': No such file or directory
glibtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
glibtoolize: copying file 'm4/libtool.m4'
glibtoolize: copying file 'm4/ltoptions.m4'
glibtoolize: copying file 'm4/ltsugar.m4'
glibtoolize: copying file 'm4/ltversion.m4'
glibtoolize: copying file 'm4/lt~obsolete.m4'
m4がないと怒られましたが、glibtoolizeが勝手に追加してくれたみたいです。
で、automake
を実行しても何も起きませんでした。
この時点で大量にファイルが作られておりますが、とりあえず、動くか試して見ましょう。
configureで動くか確認
$ ./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
(以下略)
おお、いつものアレが出てきました・・・
で、make
をするとsrcの下にlibcheap_csv_reader.laができています。lib_cheap_csv_reader.loもできています。
・・・ただ、どちらも単なるテキストファイルなんですよね・・・
.aファイルはないのか・・・とfindをかけてみるとsrc配下の.lib
という隠しフォルダに隠されていました。これをリンクすればいいわけですね。
動的ライブラリを作るには?
さて、ここで、動的ライブラリが作りたいなと思ってしまいました。
libtoolのマニュアルを見てみると次のオプションが役に立ちそうです
-module ダイナミックロードできるライブラリを作成する。 モジュール名は
lib' で始まる必要はないが、 名前の衝突を避けるため
libname' と `name' はパッケージの中で 同時に使用すべきではない。
-export-dynamic OUTPUT-FILE のシンボルを dlsym(3) を使って解決できるようにする。
-static OUTPUT-FILE がプログラムの場合、 アンインストールされた共有 libtool ライブラリはリンクしない。 OUTPUT-FILE がライブラリの場合、 静的ライブラリを作成するのみである。
これで、実行・・・あれ?作られない。
色々試行錯誤しているうちに次のオプションが必要なことが判明。
-shared
-rpath $(libdir)
sharedは`cc`のオプションですね。rpathは・・・動的ライブラリに必要なオプションらしいでのすが、動的のクセに自分のパスを知らないといけないのか・・・
ちなみに、`-module`オプションを外すとdylibファイルが作成されました。
# 参考
- [Autotools Tutorial](http://events.linuxfoundation.org/sites/events/files/slides/petazzoni-autotools-tutorial.pdf)
- [automake](http://web.sfc.wide.ad.jp/~sagawa/gnujdoc/automake-1.8/automake-ja_toc.html#SEC_Contents)
- [Makefile.amの編集 / Capm Network](http://capm-network.com/?tag=Makefile.amの編集)
- [即席GNU (autoconf & automake)](http://www.jaist.ac.jp/~kiyoshiy/memo/autoconf.html)
- [Automakeでmakeする / C++で開発](http://www.02.246.ne.jp/~torutk/cxx/automake/automake.html)
- [Autotoolsを使ったライブラリの管理 / Hacking to the Gate](https://sites.google.com/site/programmirovanienotes/home/wxwidgets_autotools)
- [The magic behind configure, make, make install / Giant Robots](https://robots.thoughtbot.com/the-magic-behind-configure-make-make-install)
- [Autotools ( automake, autoconf, libtool ) 使い方まとめ - たまにゃんのメモ帳](http://tamaobject.hatenablog.com/entry/2013/08/01/165119)
- [Autotoolsについてのメモ](http://loto.sourceforge.net/feram/Autotools-memo.ja.html)
- [Autotools(Wikipedia)](https://ja.wikipedia.org/wiki/Autotools)
- [Automake](GNU)(https://www.gnu.org/software/automake/)