非標準ライブラリを要求するApache moduleの配布とビルドに便利なconfigureスクリプトを添付しよう。MySQLやPostgreSQLのライブラリを自動検索していい塩梅なMakefileを作るためのautoconfの使い方。
外部ライブラリを要求するmoduleのビルド
libmysqlclientやlibpgなど、システムによってパスが異なるライブラリやヘッダを要求するApache moduleはどうビルドさせればスマートか?Apache moduleを書く場合Apacheのapxsコマンドでとりあえずいい塩梅のMakefileとスケルトンコードを得ることができる。通常このMakefileを使えばそのままモジュールをビルドすることができるのだが、非標準ライブラリにリンクするモジュールはそのMakefileを次のように書き換える必要がある
#DEF=-Dmy_define=my_value #INC=-Imy/include/dir INC=-I/usr/local/mysql/include/mysql LIB=-L/usr/local/mysql/lib/mysql -lmysqlclientこのマクロはビルドするApache moduleにMySQLのヘッダをインクルードし、さらにクライアントライブラリにリンクする場合の例。別の方法としてはMySQL付属のmysql_configコマンドでこれらのパスを得ることができる。例えば次のように
INC=`/usr/local/mysql/bin/mysql_config --cflags` LIB=`/usr/local/mysql/bin/mysql_config --libs`どちらにせよシステム固有のパスを指定する必要があり、別のホストでは正しくビルドできない可能性がある。つまりホストの環境に合わせてこれらのパスを書き換える必要がある。
さて、このモジュールをダウンロードしてくれた利用者はどうすればモジュールをビルドできるだろう?自分のシステムにあったパスにMakefileを書き換えるのは当然のお作法なのだが、イマドキは中々許容してもらえないのが現実かもしれない。そんなときはホスト上で必要なファイルのパスを検出していい塩梅のMakefileを出力するconfigureスクリプトを添付すればよい。
configureの作り方 - autoconfの使い方
configureスクリプトは、ビルドに必要なチェック事項をconfigure.inファイルで定義してautoconfコマンドで変換し作成する。configure.inでは様々なチェック - 主に互換性を保つためのチェック - を行うことができるが、ここでは単に必要なファイルを検索して、いい塩梅のMakefileにすうるための例をあげる。まずはMySQLのlibmysqlclientにリンクするモジュールの雛型をapxsコマンドで作成しよう
% apxs -g -n acdemo reating [DIR] acdemo Creating [FILE] acdemo/Makefile Creating [FILE] acdemo/mod_acdemo.cこれでMakefileとモジュールの雛型mod_acdemo.cが出来上がる。次に以下のようなconfigure.inファイルを用意する
AC_INIT(mod_acdemo, 0.01, user@example.jp) AC_PATH_PROG(MYSQLCFG, mysql_config, no, /usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin) AC_OUTPUT(Makefile)configure.inが用意できたらautoconfコマンドを実行してconfigureスクリプトに変換する。
% autoconf Makefile autom4te.cache configure configure.in mod_acdemo.c最後にいい塩梅のMakefileの元となるMakefile.inを用意する。Makefile.inは最終的に出力するMakefileの雛型で、configureスクリプトによって置換されMakefileとして出力される。apxsが出力したMakefileをMakefile.inにリネームして次のように編集する。
#INC=-Imy/include/dir #LIB=-Lmy/lib/dir -lmylib INC=`@MYSQLCFG@ --cflags` LIB=`@MYSQLCFG@ --libs`以上で準備完了。この状態でconfigureスクリプトを実行してみよう。
Makefile.in autom4te.cache configure configure.i mod_acdemo.c % ./configure checking for mysql_config... /usr/local/mysql/bin/mysql_config configure: creating ./config.status config.status: creating Makefileここで出来上がったMakefileを見ると @MYSQLCFG@ が /usr/local/mysql/bin/mysql_config に書き換わっていることを確認できる。あとはいつもどおりmake; make installすれば気持ちよくビルド&インストールできるはず。
先ほどのconfigure.inから生成したconfigureスクリプトは、AC_PATH_PROG()マクロで指定したパスからmysql_configプログラムを検索して、見つかったパスをMYSQLCFG変数に格納する。そしてその変数を元にAC_OUTPUT()で指定されたファイルMakefileをMakefile.inを元に置換・生成するというカラクリ。
configure.in側の変数MYSQLCFGを使ってMakefile.inの @MYSQLCFG@ を置き換えている。
エラー処理の追加
ただし、このconfigureスクリプトには不備がある。指定されたパス/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/local/mysql/binにmysql_configコマンドが無かった場合でも何事も無かったようにMakefileを生成してしまうのだ。もちろんMYSQLCFG変数は空なので生成されるMakefileもおかしなことになってしまう。これを防ぐためにはconfigure.inでチェック処理を追加する。mysql_configに関するAC_PATH_PROG()マクロの後に次のようなチェック用shellスクリプトを書き加える。
if test "$MYSQLCFG" = no; then AC_MSG_ERROR([mysql_config not found.]) fi書き換えたconfigure.inから再びconfigureスクリプトを生成し実行すると、mysql_configコマンドを見つけられなかった場合は次のような出力を得ることができる
% ./configure checking for mysql_config... no configure: error: mysql_config not found.先ほどconfigure.inに追加した処理は、AC_PATH_PROG()でコマンドを検出できなかった場合は、AC_MSG_ERROR()を使ってconfigureスクリプトを中断する処理。これでなんとかなるでしょう。
まとめ
本来configureスクリプトでは必要なコマンドだけではなく、ライブラリを実際にリンクできるか否か、必要なヘッダがあるか否か、必要な関数や変数型などが利用できるか否かをチェックするのが本筋なのだが、このように簡易的な置換エンジン(?)として使うのも中々便利ではないだろうか。利用者にMakefileを編集させるのはもう古い。イマドキの配布物は
こんふぃぐれ、めけめけいんすとーるできなければ房なユーザからソッポを向かれること必須なのだ。
房なんかに使われたくねーよってんなら別にいいけど。
最後の一行。
参考文献
- MySQLのビルド用パラメータの取得にはmysql_configコマンドが利用できる
- PostgreSQLのビルド用パラメータの取得にはpg_configコマンドが利用できる
- Perlのビルド用パラメータの取得にはExtUtils::Embedモジュールの出力が利用できる
- 唯一(?)の書籍として GNU Autoconf/Automake/Libtool が参考になる。かも。ビミョーにポイントがずれてるから決して使いやすくは無いが、理解にはとても役立つ。
- とりあえず試してみたいなら AUTOCONF, AUTOMAKEをつかってみよう!が参考になるかも