Module::Install::XSUtilでXSモジュール用のMakefile.PLを書く
前置き
こんにちは,gfxです。好きなソースはタルタルソースとsv.cです。JPerl Advent Calendar 2009 Hacker Trackも8日目ですね。そろそろTipsを読むだけでは飽き足らず,モジュールを書きたくなってきたんじゃないでしょうか。そんなわけで,今日はModule::Install::XSUtilを紹介します。
本題
皆さんの中にはよくXSを書く方もいらっしゃると思いますが,XSモジュールを含むディストリビューションはビルド環境の設定が結構大変ですよね。build_requiresにExtUtils::ParseXSやXSLoaderを指定したり,make_maker_argsにOBJECT => '$(O_FILES)'を指定したりする必要がありますし,Cコンパイラは使えるか,Cコンパイラの警告を有効にしたい,ppport.hは十分に新しいか,などなど考えなければいけないことが多々あります。ディストリビューションの中にXSモジュールが複数あると,また一層大変です。
これらの面倒なことはプログラムにやらせましょう!
まず基本コマンドです。Makefile.PLの冒頭は以下のようになります。
use strict; use warnings; use inc::Module::Install; use Module::Install::XSUtil; # for co-developpers all_from 'lib/Foo/XS.pm'; cc_warnings; use_ppport 3.19;
cc_warningsはコンパイラの警告を有効にするコマンドですが,モジュールでXSを使うことを宣言する意味もあります。設定される警告はコンパイラによって異なりますが,たとえばgcc4だと -Wall -Wextra -Wdeclaration-after-statement となります。
use_ppportはppport.hを生成します。従来の慣習では,ppport.hをディストリビューションに同梱していました。しかし,そのやり方では,ppport.hが提供するルーチンにバグがあった際の対処が面倒です。ユーザーがディストリビューションをビルドする前に,ユーザー自身が同梱されているppport.hを破棄し,新しいppport.hを生成しなければならないからです。use_pportはまさにこの作業を自動化するものです。
XSUtilの基本コマンドはこれだけですが,他にもいくつか便利なコマンドがあります。
cc_src_paths @xs_src_dirs;
XSモジュールが複数のソースからなるケースでは,Makefile.PLの設定は煩雑になりがちです。しかし,cc_src_pathsでディレクトリを指定するのなら一行で済みます。
ところで,これはXSUtilとは直接関係はないのですが,XSファイルが複数あるときには,メインのXSファイルから他のXSファイルのbootルーチンを呼ぶ必要があります。以下はMouseのソースからの抜粋ですが,このような方法で処理するといいでしょう。
/* mouse.h */ #define MOUSE_CALL_BOOT(name) STMT_START { \ EXTERN_C XS(CAT2(boot_, name)); \ PUSHMARK(SP); \ CALL_FPTR(CAT2(boot_, name))(aTHX_ cv); \ } STMT_END /* Mouse.xs */ MODULE = Mouse PACKAGE = Mouse BOOT: /* ... */ MOUSE_CALL_BOOT(Mouse__Util); MOUSE_CALL_BOOT(Mouse__Util__TypeConstraints); MOUSE_CALL_BOOT(Mouse__Meta__Method__Accessor__XS); MOUSE_CALL_BOOT(Mouse__Meta__Attribute);
また,インクルードパスを指定したいときは,cc_include_pathsを使います。
cc_include_paths @inc_dirs;
Cプリプロセッサマクロを指定することもできます。
cc_define qw(-DFEATURE_FOO); cc_define qw(-UFEATURE_BAR);
なお,cc_src_pathsやcc_defineなどは既存のオプションに追加してゆくため,一つのMakefile.PLの中で複数回使用することができます。
また,XSとPure Perl二つの実装を持つモジュールの場合は,cc_availableを使用して以下のように設定します。
if(cc_available){ cc_warnings; ...; }
cc_availableはコンパイラが使用可能かどうかをチェックするコマンドですが,XSUtil バージョン0.19からはMakefile.PLへの引数を調べて,--ppが指定されていると強制的に偽を,--xsが指定されていると強制的に真を返すようになりました。
Perlのバージョンが特定以上の場合のみXSを使用したいというケースでは,以下のようになるでしょう。
if($] >= 5.010 && cc_available){ cc_warnings; ...; }
通常のXSモジュールで使用する機能はこのくらいでしょう。XSUtilによって煩雑なMakefile.PLの設定が少しでも楽になれば幸いです。Enjoy XS!
まとめ
今回は Module::Install::XSUtil について解説しました。
このモジュールは,同様の処理を何度も書いたり見かけたりしているうちに,「もうめんどくさいからモジュールにしちゃおう」とおもって作りました。普段から「定型的なコードがないだろうか」と気をつけていることが重要ですね。
というわけで今回はここまで。明日は id:TAKESAKO さんです。