Perl Package Manager / Programmer's Package Manager.
ActivePerl に含まれているパッケージ管理ツール。 ActivePerl 5.8.8.817 には version 3.4 が同梱されている。
PPM のコマンドラインインタフェースである ppm コマンドを使用すると、PPM パッケージ形式の Perl モジュールをネットワークインストールすることができる。 PPM ではインストールしたパッケージのファイルを管理しているため、アンインストールをすることも可能である。
ActivePerl 5.8.8.819 に含まれている PPM version 4.00 では GUI インタフェースが追加された。
ppm query
ppm install packagename
ppm remove packagename
ppm rep add リポジトリ名 \\ホスト名\PPM\8xx
または
ppm ppm> rep add リポジトリ名 \\ホスト名\PPM\8xx
perl Makefile.PL nmake tar zcvf packagename.tar.gz blib nmake ppd
を実行する。できた PPDファイルの CODEBASE 部分にパッケージアーカイブの位置を追加する。
まず最初に PPM::Make パッケージをインストールする。
ppm install PPM-Make
CPAN モジュールの初期化をしていないとエラーになるので設定を行う。
perl -MCPAN -e shell
次にパッケージ化したいモジュールのソースアーカイブを展開し、make_ppm を実行する。
make_ppm
を実行する。自動的に perl Makefile.PL; make; make test が実行された後、.ppd ファイルと、.tar.gz ファイルが作成される。
PPDファイルの CODEBASE も適切に設定される。 最近のバージョンではCPANモジュールを使って AUTHOR 情報なども補完してくれる。
PPDの各設定は make_ppm のオプションで指定可能。
http://hoge/PPMPackages/6xx-builds-only/ 以下に packagename.tar.gz と packagename.ppd を置く
ppm install --location http://hoge/PPMPackages/6xx-builds-only packagename
でインストールできる。
(ppm3 については未確認)
PDLを使ったPerl数値処理プログラムによりインタラクティブ性が求められるようになってきたので、一部をCで書いて高速化する事を検討。 問題は Linux でも Windows + ActivePerl でもすんなり動くかどうか。
とりあず PDL::PP のサンプルから sumit 関数あたりを MathEx.pd に書いておく。
Foo::Bar パッケージの中の Foo::Bar::Math の一部を Foo::Bar::MathEx に移して、C extension 化したい。 ということで lib/Foo/Bar/MathEx.pd として、Makefile.PL の各種設定をしてみる。
がどうもうまくいかない。 PDL::PP の Makefile.PLサポートは、Makefile.PL と同じ位置に .pd がある事を想定しているようなので、いろいろと小細工をしなければならない。 一方 Perl の XS は Foo::Bar のベース名から Bar.so を作る前提になっているようで、これまたパッケージの中の一部のモジュールをどうもXS化しにくい。
Perl の ext/SDBM_File を真似て、子 Makefile.PL を使ってみることにした。
Foo-Bar-x.xx | +- Makefile.PL | +- lib | | | +- Foo | | | +- Bar.pm | | | +- Bar | | | +- Math.pm | | | +- MathNoEx.pm | | | ... | | +- blib/... | +- MathEx | | | +- Makefile.PL | | | +- MathEx.pd ...
パッケージディレクトリの下に MathEx ディレクトリを作り、そこに Makefile.PL と MathEx.pd を置く。 Makefile.PL は MathEx.pd 専用になるので、PDL::PP の標準的なものでOKになる。
全体のパッケージング・PPM化・インストール等が面倒にならないかと心配したが、Foo-Bar パッケージ化で perl Makefile.PL、make xxx を実行すれば子Makefile.PLまできちんと面倒をみてくれる。 MathEx 以下でビルドしたものもパッケージの blib に一緒に入れてくれるし(=一緒にインストールできる・PPM化できる)。 逆に make dist の際には子Makefileの方は余計なとりまとめはしないで、親Makefileが一括して tar.gz に入れてくれる。 これはよい。 MathEx.pd もきちんと Foo/Bar/MathEx.so になった。
XSが使えない環境のために、PerlとPPの両方で関数を書いておく。 XSが使えれば MathEx を、使えなければ MathNoEx.pm を使うように。 表向きのAPIは Foo::Bar::Math とし、ここで AUTOLOAD を使ってどちらか一方を呼び出すようにする。 間接呼び出しにして遅くなるのはいやなので、シンボルテーブルを直接設定する。
use vars qw($IMPLEMENT_CLASS $AUTOLOAD); BEGIN { $IMPLEMENT_CLASS = 'Foo::Bar::MathEx'; eval "use $IMPLEMENT_CLASS"; if ($@) { warn "Can't load $IMPLEMENT_CLASS: $@"; $IMPLEMENT_CLASS = 'Foo::Bar::MathNoEx'; eval "use $IMPLEMENT_CLASS"; die $@ if $@; } } sub AUTOLOAD { my $name = $AUTOLOAD; $name =~ s/.*://; my $implement = $IMPLEMENT_CLASS . '::' .$name; no strict "refs"; *{$name} = \&{$implement}; # ここでシンボルテーブル設定 return &{$implement}(@_); }
最初は、AUTOLOAD の最後の行で die したら、trap してエラーメッセージ中のパッケージ名(Foo::Bar::MathEx や Foo::Bar::MathNoEx)を呼び出された Foo::Bar::Math に置換して die し直すようにしようかと思ったが面倒なのでやめ。
使っているWindows BOX には Visual C++ 6 が入っているので、XSも問題なくビルドでき PDL extension もうまく動いた。
PPM化までここで済ませば、他のPCにも持っていけるはず。
これでバシバシPPで書けるわけだが、PPがこれまた難解で最初は苦労しそう。
[ Java ]
ここ最近めっきり仕事でコーディングしていないところに社内向けのとあるミニツールが欲しいという要望がでたため、喜んで引き受けることに(別の仕事もたまってはいるのだが)。
Perl でちゃちゃっと作れる内容なのだが、Windows で利用してもらうには ActivePerl のインストールの他に、必要なライブラリとミニツールのパッケージ(PPM)を入れてもらわなければならなくなるので、ちょっと面倒。 プログラムの更新も手間だし。
ということで久しぶりに Java。 Eclipse も半年以上見ないうちに結構変わったな。 ノート PC を新しくしたから以前みたいにメモリ不足で苦しむことなく使用できるようになった(というか落とすのが面倒なので起動しっぱなし)。 しかし 1024x768 GTK2 だと狭いな。
ついでにSWTベースでコードを書こうかと思ったが、一晩で仕上げるには知識不足なので普通に Swing に。 Java Web Start用に jnlp を書いて、JAR ファイルに電子署名してミニツール完成。
ExtUtils::Installed でリストアップしてチェック。
a | ActivePerl::DocTools |
ActiveState::RelocateTree | |
a | ActiveState::Rx |
* | Archive::Tar |
o | Archive::Zip |
* | Compress::Zlib |
o | Data::Dump |
* | Digest |
* | Digest::HMAC |
* | Digest::MD2 |
* | Digest::MD4 |
* | Digest::MD5 |
* | Digest::SHA1 |
* | File::CounterFile |
* | Font::AFM |
* | HTML-Tree |
* | HTML::Parser |
* | HTML::Tagset |
o | IO::Zlib |
* | MD5 |
* | MIME::Base64 |
* | Net (libnet) |
* | PPM |
PPM-Agent-Perl | |
PPM::Shell | |
* | Perl |
* | SOAP::Lite |
* | Storable |
o | Test::Simple |
o | Text::Autoformat |
* | Tk |
* | URI |
o | Unicode::String |
* | Win32 (libwin32) |
a | Win32::AuthenticateUser |
* | XML::Parser |
* | XML::Simple |
* | libwww-perl |
'*' は Copyright.html で オリジナルがオープンソースのものとして列挙されているもの。 'o' は列挙されていないが、オリジナルが Perl と同じライセンスか The Artistic License のもの。 'a' は ActiveState の Copyright があるもの (ActiveState Community License)。 それ以外は明記がないもの。
PAR でパッケージ化するには、Perl と同じライセンスの(あるいは再配布の問題のないもの)もののみストールしてある状態にしておき、PAR 化した中身に
が含まれていないかをチェック。
プロジェクトのWebビューのコードがごちゃごちゃしてきているので導入しようかどうか。 daemon 形式のプログラムなのでモジュールのローディング時間も問題にならないし。
AppConfig に依存しているのでWindows の ActivePerl 用に 1.56 を入れようとしたら make test でこける。AppConfig::Sys の getpwuid あたり。$^O で win32 の時は場合分けしているようなのだが、うまくいっていない様子。
Template Toolkit には process の出力を逐次処理する方法はないのだろうか。 長いページの際にはできあがったところから順次クライアントに送りたいのだが。
Windows Perl アプリケーション用に PPM リポジトリを久しぶりに整理。
自分が使用する PPM パッケージは以下の理由から、以前より基本的に自前でビルド/保存し PPM リポジトリをローカルに作成するようにしている。
PPM |-- <category> | `-- 8xx | |-- <projects A> [ 公開 / export ] | | |-- module1.ppd -> (A) | | |-- module1.tar.gz -> (B) | | `-- ... | `-- ... `-- pool |-- module1-x.yy | |-- module1.x.yy.tar.gz | |-- some documents... | `-- build817 | |-- module1.ppd (A) | `-- module1.tar.gz (B) `-- ...
PAR といえば Perl スクリプトを実行可能ファイル(Windows なら EXE 形式ファイル)に変換するモジュールとして有名である。
ちなみに実行可能ファイルを作成する部分はは PAR 0.97 より PAR-Packer パッケージに分けられ、PAR 自体はインストールしやすい pure Perl なパッケージになっている。
PAR が提供するもう一つの(こちらが本来はメイン?)機能は、プログラムの実行時に必要な Perl モジュールを PAR ファイルと呼ばれる Perl モジュールアーカイブファイルからロードする機能である。 XS モジュールなどもコンパイルすることができるどこかの環境で1度ビルドして PAR ファイルにしておけば、同じアーキテクチャのホスト上でそのまま利用することができる。
ロードしたい PAR ファイルはファイルパスだけではなく URL でも指定することができ、必要な時にオンデマンドでフェッチさせることができる。 これを使えば Perl プログラムの集中管理可能だ。
PAR 0.951 からは PAR リポジトリというコンセプトが追加され、パッケージ毎に作った PAR ファイルをサーバ上(あるいはローカル)のリポジトリに蓄積してオンデマンドでロードできるようになった。
個別に PAR ファイルを指定する従来の方式に比べてかなり便利そうである。 ということで試用してみた。
まずは
あたりをインストールし準備 OK。
最初に PAR-Repository に含まれている parrepo で。
parrepo create -r /tmp/PAR
PAR リポジトリファイルの中にはデータベースファイルが作成されるが、これは DBM::Deep というアーキテクチャ非依存のものを使っているので、Linux でも Windows でもどちらからでもアクセス可能である (つまり Linux 上でリポジトリをメンテできるということだ)。
次に必要な PAR ファイルを作成する。 作成したいパッケージを展開してビルドし、blib ができている状態で PAR::Dist を使ってパッケージ化する。
perl Makefile.PL make make test perl -MPAR::Dist -e blib_to_par
例えば ActivePerl*1 上で WWW-Mechanize-1.20 を PAR ファイル化すると
WWW-Mechanize-1.20-MSWin32-x86-multi-thread-5.8.8.par
というファイルが作成される。
普段から ActivePerl で必要なライブラリは基本的に自前で PPM パッケージ化して、動作確認した上で PPM リポジトリに蓄積するようにしているので、合わせて次の手順でパッケージを作ることになる。
perl Makefile.PL nmake nmake test perl -MPAR::Dist -e blib_to_par make_ppm
PAR ファイルができたら parrepo でリポジトリに登録する。
parrepo inject -r /tmp/PAR -f xxx.par
例えば先ほどの WWW::Mechanize がリポジトリに登録されている状態で
#!/usr/bin/perl use PAR { repository => 'file:///tmp/PAR/' }; use WWW::Mechanize; my $mech = WWW::Mechanize->new; $mech->get('http://www.example.com'); print $mech->content;
というスクリプトを書いて実行すると、PAR リポジトリから WWW::Mechanize がロードされて正しく実行される。
ここでリポジトリを Web サーバへアップロードして、repository のところに URL を指定するようにすることもできる。 例えばリポジトリを http://www.example.com/PAR/ に配置したとすると
#!/usr/bin/perl use PAR { repository => 'http://www.example.com/PAR/' }; use WWW::Mechanize; my $mech = WWW::Mechanize->new; $mech->get('http://www.example.com'); print $mech->content;
と書き換えることで、インストールしていない WWW::Mechanize を使用できるようになる。
先ほどの Perl スクリプトを get_top_page.pl という名前で保存して pp で実行可能ファイル化する。
pp -o get_top_page.exe -M PAR::Repository::Client get_top_page.pl
とすれば get_top_page.exe という実行可能ファイルが作成される。 WWW::Mechanize はオンデマンドで http://www.example.com/PAR/ からフェッチされるので、アップデートが必要な場合は新しい PAR ファイルを作成してリポジトリを更新するだけでよい。 EXE ファイルを作成しなおして利用者に配付しなすといった作業も不要だ。
さらには実行するスクリプトをも PAR リポジトリに置いておくことが可能だ。
例えば WWW-Mechanize に含まれている mech-dump をオンデマンドにフェッチして実行する実行形式ファイルは以下のコマンドで作成できる。
pp -o mech-dump.exe -M PAR::Repository::Client \ -e "use PAR { repository => 'http://www.example.com/PAR/', \ run => 'mech-dump' }"
ActivePerl では PPM があるとはいえ、普通のユーザにちょっとしたプログラムを使ってもらうのに「ActivePerl をインストールして、PPM パッケージをインストールして、……」というのは手間すぎる。
pp で プログラムに必要なものを全てバンドルした実行形式化ファイルにするという方法ももちろんあるのだが、頻繁にアップデートするようなスクリプトの場合には、起動のための部分だけ pp で作成しておいてあとは PAR リポジトリで集中管理するというのもちょっと魅力的である。
ActivePerl 5.8.8.819 までは .ppd と .tar.gz ファイルを置いたディレクトリを Web サーバで公開しておけば、そのディレクトリの URL を PPM リポジトリとして指定して使うことができた。
これが build 820 付属の PPM だとスキャンしてくれなくなった。 リポジトリの URL を指定する際、package.xml を指定しないと駄目らしい。
PPM リポジトリとして必要なファイル群は PPM-Make に含まれている rep_summary コマンドで生成することができる。
rep_summary --rep /path/to/ppm/repository
今後はこれで package.xml その他のファイルを生成しておくことにする。
一方複数の PPM リポジトリの扱いは良くなった。build 819 付属の PPM では、複数のリポジトリにまたがってパッケージの依存解決ができなくなっていて不便だったのだが、build 820 のものでは、以前のバージョンのもののようにまたがれるようになった。
基本的な PPM パッケージ群用と、プロジェクト毎の PPM パッケージ群用の PPM リポジトリを組み合わせて使うときに、依存解決できないと厄介だったのでこれは○。
build 819 のインストーラでは site\bin に PATH を通してくれないので、site にインストールしたパッケージ付属のコマンドが呼び出せず不便であった(もちろん自分で PATH を通せばよいのだが)。
build 820 のインストーラでは site\bin も PATH にいれてくれるようになった。○。
[ ActivePerl ]
Perl で書いた Web アプリケーションのポータブルな Win32 デモ環境として XAMPP を使ってみるとどんな感じになるか試してみた。
使ったバージョンは以下。
(http://www.apachefriends.org/jp/xampp-windows.html)
それぞれ 自己解凍型 7-ZIP アーカイブをとってくる。 最初に XAMPP を展開し、次にその xampp ディレクトリの中で Perl アドオンを展開。 xampp ディレクトリを c: の直下に移動する。
次にコマンドプロンプトを開き c:\xampp\perl\bin へ移動後 ppm コマンドを起動して作成済みの PPM パッケージをインストールする。 インストール先は \xampp\perl 以下とドライブ無しのパスで指定されているようで、問題なく必要な Perl ライブラリをインストールできた。
次に \xampp\xampp-control.exe を実行して GUI 管理ツールを立ち上げ、その画面から Apache を起動。 普通の Win32 版 Apache もインストールしてある PC だったため、xampp-control から Apache を起動したらそちらが立ち上がってしまったが、これは Svc にチェックが入っていたからだった。Svc を外せば \xampp 以下の Apache がきちんと起動する。
あとは \xampp\htdocs 以下で WiKicker CGI プログラムの配置や設定ファイルを作成すれば OK。 もともと WiKicker は相対パスだけで動くようになっている*1ので、問題なく実行することができた。
*1多分
一度セットアップできた \xampp ディレクトリを TrueCrypt 仮想ドライブにコピーして起動してみた。
こちらも問題なく OK。
ということで XAMPP でお手軽に Perl CGI プログラムの動く Web サーバ環境を作れることを確認できた。
問題があるとすれば XAMPP + Perl アドオンが馬鹿でかいところか。400MB オーバー。 今回何が一番時間がかかったかって、XAMPP + Perl アドオンを展開した直後の xampp ディレクトリを、後でまた使えるように 7-ZIP の最高圧縮する処理に時間がかかった。 使っている PC では 50分以上かかったよ。
Naney (なにい) です。株式会社MIXIで SNS 事業の部長をしています。
※本サイトの内容は個人的見解であり所属組織とは関係ありません。