はじめに
自前で編集したconfigureパッケージにスクリプトを導入し、C言語のプログラムからフルパスで実行しようとしていました。
この時にinstall先のprefixをconfigure.ac経由で設定出来れば、どこにインストールされても動作するんだけどな~と色々弄ってたら出来たので紹介します。
実際にやろうとしていたことが無いとイメージ付きにくいと思うので、やったことを一連の流れで記載しています。
上記方法だけ知りたい方はコマンドのインストール先をconfig.hに追加を参照ください。
動作環境のautoconfのバージョンは2.69です。
やったことの流れ
今回は手元のパッケージにこのような実装修正を行いました。
- pythonのコマンド実行サーバープログラムを既存C言語処理に追加
- 今までforkとpipeで頑張って実現していたコマンド実行処理を、1のコマンド実行サーバーに任せるよう修正。
全部Cで頑張って書いていた箇所のスクリプト実行はスクリプト言語に任せようという風に改良しました。
上記をconfigure目線で書き直すと以下のような感じです。
- パッケージにpythonのコマンド実行サーバープログラムを追加
- Cで1が呼べるよう、コマンドのインストール先をconfig.hに追加
パッケージにpythonのコマンド実行サーバープログラムを追加
プログラムのインストール指定についてはsbin_PROGRAMS
でいいんですが、この指定だとコンパイルしようとしちゃうんですよね。
なんかいい手ないかなといくつかOSSのMakefile.amを見てると、どうもsbin_PROGRAMS
等の記載はこんなルールらしいということがわかりました。
- パス名_オプション
オプションは対象がなんなのかによって変わります。
見つけたオプション:
- コンパイルするもの⇒PROGRAMS
- ヘッダー⇒HEADERS
- manページ⇒MANS。
- じゃあスクリプト⇒SCRIPTSかな?
と思って試したらビンゴ!ちょっとテンション上がりました。
Makefile.am内記述を抜粋するとこんな感じ
# コンパイルするバイナリの場合。インストール先はprefix/sbin
sbin_PROGRAMS=lighttpd lighttpd-angel
# ライブラリの場合。インストール先はprefix/lib
lib_LTLIBRARIES = libevent_threadpool.la
# ヘッダーの場合。インストール先はprefix/include
include_HEADERS = event_threadpool_data.h event_threadpool.h
# manページの場合。インストール先はprefix/share/man/man8/。これだけパスが謎
dist_man8_MANS=lighttpd.8 lighttpd-angel.8
# スクリプト、スクリプト言語の場合。インストール先はprefix/sbin
sbin_SCRIPTS=CommandClient.py CommandServer.py CommandService.py
ちなみにインストールしない場合:パス名にno_instを指定です。
noinst_PROGRAMS = test
コマンドのインストール先をconfig.hに追加
さて、configureでpythonコードをインストールできるようにしたのはいいんですが、インストール先はconfigureのオプションで変わるのでC言語にパスべた書きはダサいので避けたい。
ただ、基本はAC_DEFINEで値を渡すとconfig.hに定義が追加されるんですが、configure.ac内でprefixの参照が出来ないみたいなんですよね。どうしたもんかと出力されたconfigureを見てると1つ発見しました。
- configure.ac内でシェルの処理を書くと、configure内にそのまま反映される!
というわけで、config.hに定義を書き込むための処理をそのままconfigure.acに記載しました。こんな感じ
# add CommandServicePath
AC_DEFINE([CGI_COMMAND_SERVICE_PATH], ["dummy"], ["Define CGI CommandService path"])
case ${prefix} in
NONE) $as_echo "#define CGI_COMMAND_SERVICE_PATH \"${ac_default_prefix}/sbin\"" >>confdefs.h;;
*) $as_echo "#define CGI_COMMAND_SERVICE_PATH \"${prefix}/sbin\"" >>confdefs.h;;
esac
ac_default_prefix
はprefix指定なしの場合に利用される変数、prefix
はprefix指定時の変数です。
ほんとはsbinだけ指定するオプションもあるんですが自分は使わないので省略。
$as_echo~の行は、AC_DEFINEを利用した際にconfigureに追加されるものを流用したらうまく動作してくれました。
configure.ac編集後はautoreconfでconfigureを更新。./configure prefix="/usr/local/www/"
で出力されたconfig.hはこうなります。
想定通り"/usr/local/www/sbin"になってくれました。
/* "Define CGI CommandService path" */
# define CGI_COMMAND_SERVICE_PATH "/usr/local/www/sbin"
また、configure.acに以下行を記載しているのは、config.hに定義を追加するためには、AC_DEFINEの記載も必要だったからです。
AC_DEFINE([CGI_COMMAND_SERVICE_PATH], ["dummy"], ["Define CGI CommandService path"])
confdefs.hへの出力 + config.h.inに定義が書いてないとconfig.hに反映してくれないらしく、このconfig.h.inに定義を追加する為にはAC_DEFINEが必要って感じです。
最後に
今回はprefixの指定でしたが、configure.ac内でシェルの処理を書くと、configure内にそのまま反映される!
という特性を利用すれば、configure内で何か特定のチェック処理を行いたいとか、シェルで出来ることをconfigure.acに書いてあげることで、configureを好きに拡張できる可能性があります。
特に用途がないので実際色々試したってわけではないですが、ちょっと夢が広がる発見でした。