インタフェースの表裏を意識する: GNU getopt & autotools

公開しているコードについて問い合わせを受ける機会が増えてきたので,もう少しソフトウェアとして導入・利用し易くしようとインタフェース周りを作り直した.自作の(コマンドライン)オプション解析と手書きの環境依存 Makefile が利便性を損ねているのは明らかだったので,標準的なオプション解析ライブラリとビルドツールに対応することにした.オプション解析を書き換えたのはだいぶ前(自作の学習器が MacPorts から導入可能になっていた - ny23の日記)のことだけど関連するのでまとめてメモしておく.
C++ で使えるオプション解析ライブラリは古典的な GNU getopt を初めとして getoptpp, google-gflags, boost::program_options, cmdline など色々あるが,最近のもので定番と呼べるほどのものはないようだ.

オプション解析のために外部ライブラリをインストールさせるのは嫌だったので,今回は GNU getopt でオプション解析を書くことにした.
オプション解析を書く立場からみた getopt の使い勝手は,ヘルプコマンドで表示するオプションのサマリを自分で書かないといけなかったり,オプション値の型変換を自前でやる必要があったりとあまり良いとは言えないが,getopt が提供するコマンドラインインタフェースは,(UNIX では) 規範として馴染みのあるもので,良くできている.getopt はオプション解析に必要となる最低限の機能しか提供していないため,却って押し付けがましくなく融通がきき(機能は多過ぎるより少し足りないぐらいがちょうど良い; underkill over overkill)これに適当なラッパーを書いて使うのが自分には合っていそうだ.
続いてビルドツール.公開している構文解析器では,ブログコーパスからの学習をサポートしたり,複数の形態素解析器・辞書に対応するようになって学習時の設定項目がやたらと煩雑になり,手書き Makefile を編集するのも億劫になっていたので,ビルドツールへの対応は懸案事項だった.ビルドツールも最近は色々あるようで,古典的な定番である GNU autotools (autoconf/automake/libtool) の他に gypwaf など軽量なビルドツールが色々出てきている.

しかしスクリプト言語で書かれたビルドツールを使う気分にはなれなかったので,定番を経験しておくのも良いかと思って*1,枯れ切っている GNU autoconf/automake に対応させてみた.対応させるにあたって参考にしたのは以下のページ.最新版では obsolete になった m4 マクロを説明しているページもあるので,configure.ac を書いたら autoupdate で更新しておくと良い.autoreconf -i が便利なので,なるべく新しい autotools を使うのが良さそうだ.

やはり configure でコマンドラインから学習するモデルをカスタマイズできるのは便利だ*2.m4 マクロは噂通り気持ち悪かったが,これは m4 がどうこうというよりマクロという存在自体にそもそも(異なる言語を混在させる)気持ち悪さ*3があるので仕方がないのではないかな.
GNU getopt と GNU autotools,どちらも確かにイマイチなところはあるけれど,小規模ソフトウェアで使う分にはそこまで言うほどは悪くないなと思った.取っつきにくさはあるが一日もあればそれなりには書けるようになるし,何より既存ソフトウェアでの採用例が豊富なので,マニュアルを読まなくても(既存ソフトウェアでの利用例を参照しながら書けば)だいたい動くようにはなる.この辺りは普及度の高さからくる強みだと思う.色々なソフトウェアの configure.ac (autoconf) や Makefile.am (automake) を読んで GNU autotools への理解が深まったお陰で,これからは UNIX 系ソフトウェアのインストールする際にハマる機会も減りそうだ.
インタフェースの裏側(ソフトウェアの開発者側)からみれば,後発のオプション解析ライブラリ,ビルドツールの方が利便性は間違いなく良くなっているのだろうけど,インタフェースの表側(ソフトウェアの利用者側)の視点で考えると(自分の利用範囲では*4)敢えて定番を避ける理由は無いように感じた.他のオプション解析ライブラリやビルドツールを試すのは,GNU getopt & autotools で不満が出るようなソフトウェアを書くようになってからでも十分だろう.

*1:自分が今までインストールしてきたソフトウェアのように,自分のライブラリも configure && make && make install でインストールしてみたかった.

*2:configure のオプションが多少複雑でも,コマンドラインで一度叩いておけば zsh なら C-r で履歴として引っ張り出せる.

*3:同じような気持ち悪さは swig などを使っていても感じる.

*4:ソフトウェアが大規模化すればオプション定義を分散させたくなったりして getopt の仕様が問題となるケースはあるだろう.また autotools については,ソフトウェア利用者側の立場からも configure の遅さが問題となるケースはあるかと思う.そういうケースではコンパイル自体も遅いだろうからそっちも含めてどうするか考えないといけなくなりそうだけど.