GNU 版 make ユーティリティ。
GNU Coding Standards 7.2.5 Standard Targets for Users より
Perl が使えることを前提とすれば ExtUtils::Command を使うことで、UNIX / Windows どちらでも動くコマンドを定義できる。
RM_RF = perl -MExtUtils::Command -e rm_rf CP = perl -MExtUtils::Command -e cp MKPATH = perl -MExtUtils::Command -e mkpath
現在進行中のプロジェクトの一つがそろそろ大詰め。 ドキュメント書きに突入。 前回までは過去の方法を踏襲して MS Word ベースだったのだが、自分がマネージャーになった今期からは全面的に TeX ベースへ移行させる。
を用意。 Makefile は時間がなかったので GNUmakefile と Makefile を作って Linux 用と Windows 用の両方作ったのだが、後々面倒なので一本化したい。
Windows だと nmake がやっぱり主流だろうか。 しかし GNU Make とは違う点が多く、使い分けるのも面倒。 かといって Ant というのも面倒。
ということで気軽に使える Windows 用の GNU Make を探す。 Cygwin 版は共同作業者に入れてもらうのが面倒なので却下(Makefile から呼ばれるコマンド群もLinuxと同様のものが入るのでこちらの方が便利といえば便利ではあるのだが)。
MinGW版が 3.80 をポーティングしているし単体でも動きそうなのでこれを試してみることにする。
mingw32-make-3.80.0-3.exe を取ってきて実行。make そのものだと思っていたがマニュアル等を含むインストーラだった。 一旦インストールして、mingw32-make.exe をコピーしてアンインストール。 mingw32-make.exe 単体で動作するので取り扱いが楽でよい(必要なら make.exe にでもリネーム)。
Windows 特有の問題があるかどうかは今後使ってみてチェックだな。
この間 Windows 用の GNU Make として MinGW版を選択して、プロジェクトのドキュメントのビルドの自動化をすすめている。
しかし(最初からわかっていたのだが)make だけでは駄目で各ユーティリティがなくて結構不便。 touch すら無いし。 幸い全員の環境に ActivePerl が入っていることが前提になっているので、必要ならスクリプトを書いていけばある程度はなんとかなる。
今日は、プロジェクトで開発したPerl モジュールのソースアーカイブを自動的に一時ディレクトリに展開して pod2latex をかけてごにょごにょという処理の Makefile を書く。 さすがに tar が無いと無理だ (Archive::Tar を使うという手もなくはないが結局標準ではないし)。
ということでGNU tarを探す。例によってインストール不要という条件で。
MinGW の中からは探せず。 GnuWin32 のものを使ってみる。 ついでに gzip も
fork できないとかで tar の -z オプションが使えない。かなりがっかり。
あれ、gzip が最初からPATH上にあるなと思ったら、texinst753 に含まれていた奴。 GNU tar も入っている。 ちょっとバージョンが古めだけど -z も効くし、これが扱いやすいかも。
なにより他のプロジェクトメンバの Windows BOX にもそれぞれ入っているはずだし。
ということで GNU tar 確保。
NSIS のサイトによるとビルドに「SCons」を使うようしたらしい。
と興味深いツールになっているようだ。
現在プロジェクトLaTeXベースのドキュメント生成には GNU Make を使っているのだが、UNIX、Windows の両方でビルドできるようにするには ComSpec 環境変数の有無で使用するコマンドを切り換えたり等いろいろ面倒なので、代替ツールとして使えないかなと。
基本的な機能は Make に対する改良がなされているようであるし、コピー等ファイル操作も SCons 自体がもっているのでクロスプラットフォームでビルドできるようにするのも楽そうだ。
一方 Autoconf 系の機能については、インストール済みのライブラリの検出や実装レベルのチェック等を実装しているようである。 make check や make dist、make install 等にあたるターゲットに関する機能(あるいは規約)のようなものは無い。これは非常に残念。 結局自分が Ant を使わなくなったのも GNU Autotools にあるこれらの機能に欠けているからであるし。
実は私がPerl が好きな理由の一つとして、これらサポートが充実しているという点がある。Perl では ExtUtils::MakeMaker (あるいは Module::Build)があり、ビルドからテスト、ソースパッケージのパッケージングまでフレームワークが整っている。
SCons は Python ベースで、Makefile にあたるファイルも Python スクリプトである。 SCons が影響を受けた Cons は Perl ベースであったのだが、既に2001年5月ごろから開発が止まってしまっている。残念。
ということで Make の代替には使えそうであるが、GNU Autotools と同じようなことをするにはいろいろ手をかけないといけないといった印象。
SCons で pLaTeX2e ソースファイルを PDF に変換する SConstruct ファイルを書いてみた。
bb_builder = Builder(action = 'ebb $SOURCE', suffix = '.bb', src_suffix = '.png') pdf_builder = Builder(action = 'dvipdfmx -V 4 $SOURCE', suffix = 'pdf', src_suffix = '.dvi') env = Environment(LATEX = 'platex') env.Append(BUILDERS = {'BBBuilder' : bb_builder}) env.Append(BUILDERS = {'PDFBuilder' : pdf_builder}) env.PDFBuilder(target = 'example-doc') env.DVI(target = 'example-doc', source = 'example-doc.tex') env.Clean('example-doc.dvi', ['example-doc.log', 'example-doc.out', 'example-doc.toc', 'example-doc.aux']) env.Depends('example-doc.dvi', 'image1.bb') env.Depends('example-doc.dvi', 'image2.bb') env.Depends('example-doc.dvi', 'image3.bb') env.BBBuilder('image1') env.BBBuilder('image2') env.BBBuilder('image3')
.tex から .dvi の生成ルールでは、補助ファイルを見て適宜数回 platex を実行してくれる。ここら辺はさすが。
GNU Make のような暗黙のルールの適用がない(わからない)ので、.bb ファイルを dvi の依存ファイルに指定するだけでは駄目で、ビルド指定をする必要があるのがちょっと面倒。
これだけだと GNU Make より便利とはいえないな。 プラットフォームによって異なるコマンド(cp / copy など)を使うような事や、もうちょっと複雑な事などをしないとそれほどメリットがでないか。
私が Perl が好きな理由の一つに、標準でExtUtils::MakeMakerという Makefile ジェネレータがついているところである。これを使って Makefile.PL を書くと
perl Makefile.PL make manifest make make test make dist
で <pacakge>-<versionno>.tar.gz というソースパッケージを作ることができ、
tar zxvf <pacakge>-<versionno>.tar.gz cd <pacakge>-<versionno> perl Makefile.PL make make test make install
という手順でインストールする事ができるようになる。 パッケージの作り方が確立されているので、容易に新しいパッケージを開発しはじめられる。
逆に Java でプログラムを書くのが億劫なのは、このあたりの準備が面倒だからである。 Ant を使っても結局ここら辺自分でやらなければならないし。
ちょっとしたパッケージを作りたいと思うことは良くある。 例えばいくつかのデータファイルと、READMEファイルなんかをひとまとめにしてアーカイブにするとか。
本当にちょっとしたであれば、手動でアーカイブすれば良いのだが、
あたりを考慮しなければならない時は面倒くさくなってくる。
自動化としては
あたりがぱっと思い浮かぶ。 しかし、最初の2つは毎回同じようなものを書くのが面倒だし保守もしにくい。 GNU Autotools はちょっとごっつすぎだし、Windows での環境構築も面倒。
ということで最初は ExtUtils::MakeMaker を使うという線で考えてみた。 もともと Perl モジュール用で汎用用途にはちょっと邪魔な振舞いもあるが、使えないことはないと思う。 しかし make (GNU Make あるいは nmake など) に依存しているという欠点がある。
ということで ExtUtils::MakeMaker の代替である Module::Build ベースで汎用用途に使えないか検討してみた。こちらは pure Perl で make を必要としない。
Module::Build も Perl モジュールビルドにあわせた振舞いがあるものの、ちょっとカスタマイズすれば使えそうだ。 で、いろいろいじった結果、次のような感じにすると使いやすそうだ。
use Module::Build; my $class = Module::Build ->subclass(class => 'NonmoduleBuilder', code => q{ # Don't make blib sub ACTION_code {}; # Don't make blib sub ACTION_docs {}; # Don't make META.yml sub ACTION_distmeta { # no warning on ACTION_distdir $_[0]->{metafile} = 'MANIFEST'; }; # Don't add MEATA.yml to MANIFEST sub ACTION_manifest { $_[0]->{metafile} = 'MANIFEST', $_[0]->SUPER::ACTION_manifest(@_); }; }); # Set your archive name and version. $class->new(dist_name => 'mypackage', dist_version => '1.0.2', )->create_build_script;
カスタマイズした部分は以下(Module::Build 0.26 で動作確認)。
上記のようなファイルを Build.PL という名前で作っておけば
perl Build.PL ./Build manifest ./Build ./Build test ./Build dist
等として、アーカイブ作成が容易にできるようになる。
しばらくこの方法でいろいろ試してみることにしてみよう。
Naney (なにい) です。株式会社MIXIで SNS 事業の部長をしています。
※本サイトの内容は個人的見解であり所属組織とは関係ありません。