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フェイズで実際に何をやっているかとかは以下が参考になります。
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からモジュールを簡単に直接インストールしてもらえる
まとまらないまとめ
とりあえず、今日はここまで。次はファイル構成の話なんかを気が向いたら書きます。
なんかざっくり書く予定が、途中から丁寧になって長文化してしまうのが悪い癖。