« DBIx::Schema::DSLってのを書いている話 | メイン | 今週のおーぷんそーす活動と、Dist::MakerのModule::Build対応とか »

2013年2月13日

CPANモジュールのパッケージングの歴史

最近同僚が次々とCPAN Authorになってて良い流れだなーとか思っています。

ただ、CPANへのモジュールの上げ方がわからないとか、M::Iを使えばいいのか M::Bを使えばいいのか、それらがそもそも何やってるのか分からないという話も 聞くので、僕自身もその辺の知識を整理してアップデートしました。

とりあえず、今はModule::Buildを使っておけば良いんじゃないかと 思っていますが、そこに至る歴史的経緯をまとめてみます。

大体、以下に書いてあることに加えて、最近の動きを書いています。

Module::Build:MakeMakerの後継者を目指して

PerlでCPAN形式のモジュールを配布する場合は、Makefile.PLなりBuild.PLなりを モジュール作者が用意して、それがインストールに必要なファイル類を自動生成 するという流れになっています。

既存の雛形を使うと色々ファイルができてぎょっとしますが、最低限必要なのは lib/以下のモジュール本体と、(Makefile|Build).PLだけです。

ExtUtils::MakeMaker(EUMM)

Unix系OSではビルドツールに昔からmakeが多く使われているのは御存知の通り。 Perlモジュールもmakeでビルドしてインストールするのが楽だろうってことで、 make用のMakefileをPerlで書き出す仕組みが作られた。

それが ExtUtils::MakeMaker 。20世紀末くらいの話。

Makefile.PLの中でuse ExtUtils::MakeMaker;WriteMakefile(…);とかやって使う。

Perl5当初からコアモジュールなので、Makefile.PLの中でuseしてもCan’t locateとか 怒られない。

これで、以下の様な今のPerlモジュールインストールの形の基礎が作られました。

% perl Makefile.PL
% make && make test && make install

実際のところcpanm?コマンドもtarball落としてきて、こういうインストールコマンド を自動的に実行してくれています。

makeフェイズで実際に何をやっているかとかは以下が参考になります。

Perlのmakeフェーズの挙動

Module::Build(M::B)

make installでやってることってそんな大したことなくて、特にPurePerlの場合は ファイルの配置くらいだし、それってPerlの方が得意じゃね? ってことで、makeに頼らないPerlモジュールビルドツールってことで作られたのが、 Module::Build 。初リリースは2001年。

Build.PLというファイルを作ると、perl製のビルドスクリプトをBuildという名前で作 成する。

モジュールインストール手順は以下の通り。外部ツールに頼らずにPerlだけで完結して いる。

% perl Build.PL # Build ファイル作成
% ./Build test
% ./Build install

単にビルドスクリプトを作るだけではなく、モジュールのメタデータの自動生成と その仕様を定義し始めたのが功績で、 META.yml なんかはExtUtils::MakMaker 側にも入ることになります。これ後々の重要ポイントです。テストに出ますよ。

ただ、

  • 当然ながらModule::Buildがインストールされていない環境だと動かない*
  • CPAN Shellが上記のインストール方法に対応してくれるのが遅かった
  • XSモジュール作成用には弱かった

等の問題があり、また次に述べるModule::Installに多くの人が移行してしまったため 一旦あまり使われなくなります。

* 一応、Perl5.10からはコアモジュール入りしています。
また、ExtUtils::MakeMaker形式のMakefile.PLを自動生成する機能も 後から追加されたので、それを使って、モジュール作者側でパッケージに Makefile.PLも同梱するという回避策もあったりはします。

Module::Install(M::I)

そこに現れたのがM::I。正しくパッケージングすればサラの環境でも モジュールインストールが可能で、他にも良いことづくめなので、一世を風靡します。 今でもかなり使われていますね。

多くの人が使っているので、見よう見まねで他の人が書いているM::I形式の Makefile.PLを作ったことがある人も多いんじゃないでしょうか。僕がそうでした。

最初に作られたのは2003年くらい。特徴としては以下。

  • Makefile.PLをDSLでかっこ良く記述できる
  • インストール方法は従来のmake
  • プラグインで拡張可能 
  • inc/ の活用

前項でも述べましたが、EUMMにはコアモジュールならではの強みがあり、 サラの環境でいきなりperl Makefile.PLしてもちゃんと動きます。

ところがコアモジュールじゃないモジュールだと、エンドユーザーが事前にその モジュールをインストールしないといけないという問題が発生します。

じゃあどうするか。そこで、考えられたのが、

インストールモジュールをパッケージに同梱してしまう

というエポックメイキングな力技です。perl Makefile.PLすると、Makefileや メタファイルが作られるとともに、inc/が作られてそこにM::I自身や付随する プラグインが格納されます。

configure_requires登場によるinc/のオワコン化とM::B再び

inc/ は確かに現実的な解決策ですが、さすがにやりすぎ感があります。

インストール時にいきなり(Makefile|Build).PLを走らすから事前にインストールモジュールが 必要になるからこうなったわけですが、それを動かす前に必要なモジュールをインストールする 仕組みがあればよさそうです。

そこで利用されたのがMETA.ymlです。META.ymlはもともとCPANサイト掲載に必要なメタ情報 なんかをまとめてあるファイルですが、そこに事前にインストールされている必要があ るモジュールの情報を含めてしまえばよさそうです。

それがconfigure_requiresセクションです。

今はEUMMもM::IもM::Bも適切にPLファイルを書けば、META.ymlにconfigure_requiresを出力 してくれるので、それをパッケージに同梱します。

また主だったモジュールインストーラー(cpan(m|p)?)も現在はconfigurerequiresに対応 していて、Makefile.PLを走らせる間に、META.ymlのconfigurerequiresセクションを見て、 そのモジュールをインストールしてくれます。

このようにconfigure_requiresを使えば、inc/に色々同梱する必要はなくなりました。

configure_requiresに関しては以下にまとまっていました。

https://www.socialtext.net/perl5/configure_requires

また、M::Iの利点であるプラグイン機構も、昨年tokuhiromによって開発された Module::Build::Pluggableを使えばM::Bで実現出来ますし、M::B自体も継承すれば なにげに簡単に拡張できるようになっています。

そうなるとM::Iの利点はDSLと既存のプラグイン資産くらいです。それにDSLにも良し 悪しがあるし、M::I自体のが動作が不安定だった時期もありました。

だったら、M::BはPerl5.10からコアモジュールだしそれ使えばよくね?となってきてるのが 最近の流れ。

githubの存在も無縁じゃなくて、Module::Build使ったほうが色々楽だったりします。 具体的には以下の様な感じです。

  • Travis連携が超絶楽
  • cpanmでgithubからモジュールを簡単に直接インストールしてもらえる

まとまらないまとめ

とりあえず、今日はここまで。次はファイル構成の話なんかを気が向いたら書きます。

なんかざっくり書く予定が、途中から丁寧になって長文化してしまうのが悪い癖。

投稿者 Songmu : 2013年2月13日 12:50