モダンPerlの世界へようこそ
第23回 Module::Build:MakeMakerの後継者を目指して
今年もよしなにお願いいたします
連載第18回ではlocal::libの話題を取り上げましたが,今回はそのときにもちらと紹介した,モジュールをインストールするときに利用するいくつかのモジュールについて簡単にまとめてみます。
ExtUtils::MakeMakerが生まれるまで
Perlがバージョン3でコンパイル時にユーザ独自のライブラリを組み込んで本体機能を拡張できるようになったとき(1990年),おそらくもっとも喜んだのがデータベースを使っていたユーザでした。彼らはいそいそと自分の使っていたデータベースのライブラリをPerlに組み込み,それとわかる名前をつけて公開しました。当時の記録によれば,Oracleに対応したOraperlやPostgreSQLに対応したPgperlなど,データベース関連だけで8つないし9つの専用Perlがあったようです(※1)。
でも,このアプローチには問題もありました。さまざまなライブラリを組み込んだバリエーションが生まれたことでメンテナンスコストは高くなりましたし,データベースライブラリのAPIには互換性がなかったため,特定のデータベースライブラリを組み込んだPerl用に書かれたアプリケーションを別のデータベースライブラリを組み込んだPerl用に移植するのは一苦労でした。
そのため1992年には早くもバズ・モシェッティ(Buzz Moschetti)氏らを中心にデータベースまわりの問題を議論するユーザグループが生まれ,それがやがていまのDBIへと発展していくのですが(DBIはPerl 5のベータ時代から存在していた最古のモジュール群のひとつです),このDBI構想を実現させるためには,Perl本体の外にPerlとCの世界をつなぐインタフェースを用意してデータベースライブラリとリンクさせる必要がありました。そのため,Perl 5ではPerl本体だけでなく外部のライブラリやモジュールも(当時のPerlユーザにとっては)おなじみのmakeを使って別途,再帰的にコンパイルできるようになります。その前処理を行うためにつくられたのがExtUtils::MakeMaker (EUMM)でした。
ExtUtils::MakeMakerの使い方
ExtUtils::MakeMakerを使うと典型的なモジュールのMakefile.PLはたとえばこのように書けます。
use strict;
use warnings;
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'MyModule::Name',
AUTHOR => 'Some Person <person@example.com>',
VERSION_FROM => 'lib/MyModule/Name.pm',
ABSTRACT_FROM => 'lib/MyModule/Name.pm',
PREREQ_PM => {
'Some::Module' => 0,
'Other::Module' => 0,
'Test::Module' => 0.88,
},
($ExtUtils::MakeMaker::VERSION > 6.30
? ( LICENSE => 'perl' )
: ()
),
);
ExtUtils::MakeMakerの問題点
Perl 5のWikiによると,このExtUtilsという名前空間は「外部ユーティリティ」を意味する「Ext(ernal) Util(itie)s」ではなく,Perlソースのext/ディレクトリ以下に配置されている「Ext(ension)用のUtil(itie)s」という意味だそうですが,ExtUtils::MakeMakerは,そのext/ディレクトリに格納されている(Perl 4の時代から利用されてきた)各種DBMやPOSIX層とのつなぎをしただけでなく,いまも例としてあげたDBI/DBDや,日時計算を行うCライブラリ,Tkのような大きなGUIライブラリ群などのつなぎ役としても利用されるようになりました。また,その余録として,一般の,Cとは無関係のPerlモジュールをインストールするツールとしても活用されました(ディストリビューション内のファイルはいずれにしても適切な位置に配置しなければなりませんから,この転用はごく自然なことでした)。
ところが,時が過ぎて,Cとは無関係なモジュールが増えてくるにつれ,「自分たちはCを使うのがめんどうだからPerlを使っているのに,どうしてわざわざCのツールを使う必要があるのだろう」という問いかけが行われるようになってきました。移植性の低いMakefileや,入っているかどうかもわからないmakeを使わなくても,ファイルの再配置くらいPerlでできるし,Perlを使ったほうが移植性が高まるじゃないか,というわけです。
実際,Unix系のプラットフォームとは異なるシェルを採用しているWindows環境などでは,MakefileのなかにシェルのコマンドではなくExtUtils::Commandを利用したPerlのワンライナーが埋め込まれていました。Windowsというと「またか」という顔をする方もいるでしょうが,移植性の問題を抱えているのはWindows環境だけではありません。ExtUtils::MakeMakerにはほかにもAIX,BeOS,Cygwin,DOS,Darwin(Mac OS X),(メンテナンスが放棄された)Mac OS(Classic),NW5,OS2,QNX,U/WIN,VMS,VOSといったプラットフォームのためにMakefileを微調整する仕掛けが用意されています。
このようなバッドノウハウの塊こそがExtUtils::MakeMakerの肝なのですが,そのメンテナンスが大変なことは誰もが認めていました。そのため,21世紀に入るとExtUtils::MakeMakerにかわる新しい代替品を模索する動きが活発化します。その第一弾として登場したのがケン・ウイリアムズ(Ken Williams)氏が2001年にリリースしたModule::Buildでした。
Module::Buildの誕生
「makeいらず」を売りにしていたModule::Buildは,その前年に始まったPerl 6プロジェクトの影響もあってか,ExtUtils::MakeMakerとの互換性は考慮せず,自分が理想的と思う設定の書き方を追求していきました。先ほどの例をModule::Buildで書き直してみると,たとえばこのように書けます。
use strict;
use warnings;
use Module::Build;
my $builder = Module::Build->new(
module_name => 'MyModule::Name',
dist_author => 'Some Person <person@example.com>',
dist_version_from => 'lib/MyModule/Name.pm',
requires => {
'Some::Module' => 0,
'Other::Module' => 0,
},
build_requires => {
'Test::Module' => 0.88,
},
# license => 'perl',
);
$builder->license('perl') if $Module::Build::VERSION > 0.06;
$builder->create_build_script;
このようにオブジェクトを明示することでモジュールの継承などがしやすくなるほか,ExtUtils::MakeMakerを使ったMakefile.PLでよく見かける三項演算子のかわりに,条件によって値がかわる設定をあとからメソッド経由で変更したりオブジェクトの内部に保存されている値を取り出しやすくなったりする,というのがModule::Buildのひとつの売りでした。
モダンPerlの世界へようこそ
- 第27回 Test::Most:Test::Moreでは物足りなくなってきたら
- 第26回 ShipIt:モジュールのリリースをもっと手軽に
- 第25回 Module::Starter:モジュールを書くためのテンプレート
- 第24回 CPAN:Perl界の水先案内人
- 第23回 Module::Build:MakeMakerの後継者を目指して
- 第22回 Mojolicious::Lite:本当に簡単なウェブアプリがあればいいときは
- 第21回 KiokuDB:マッピングが複雑すぎると感じたら
- 第20回 Email::Sender:メールを送信する
- 第19回 Who's Who on IRC:Perl界の紳士録(IRC編)
- 第18回 local::lib:ふだんと違う環境でPerlを使う


