久々に環境を作り直したら、PARの導入が恐ろしく簡単になってた。
まずは、PAR::Packer
のインストールの前に、必要モジュールをPPMでインストールしておく1。必要なのは以下の6つだ。
Module::ScanDeps
Win32::Exe
Parse::Binary
Getopt::Argvfile
PAR
PAR::Dist
cpan
コマンドでPAR::Packer
をインストール
以前はここからが厄介だった。別のリポジトリからインストールしようとしてバージョン違いに泣いたり、以下のリンクなどを参考にしてMinGWやnmake
と格闘したりした。
BdP – PPM Repository
http://www.bribes.org/perl/ppmdir.htmlVista/XPのActivePerl 5.10.0でPAR::Packerをビルド ハードなソフトの話/ウェブリブログ
http://hardsoft.at.webry.info/200801/article_4.html
ところが今や、やることはこれだけである2。
C:\>cpan -fi PAR::Packer
これだけでcpan
コマンドが勝手にMinGWをダウンロードしてきてPAR::Packer
のコンパイル&インストールをやってくれる。
実際にexe化してみる
試しにテストスクリプトをexe化してみよう。
#!/usr/bin/perl -l use utf8; use strict; use warnings; print "Hello, World!";
-o
オプションでexeファイル名を指定する
C:\>pp -o test.exe test.pl C:\>test Hello, World! C:\>
Moose
なパッケージをexe化
Moose
を使ってても大丈夫。
#!/usr/bin/perl { package MyApp; use Moose; use Perl6::Say; has param_a => ( is => "rw", isa => "Num", required => 1 ); sub add_to_a { my $self = shift; $self->param_a( $self->param_a + shift ); } sub say_a { my $self = shift; say $self->param_a; } } my $app = MyApp->new( param_a => 20 ); $app->say_a; $app->add_to_a( 500 ); $app->say_a;
C:\>pp -o test_moose.exe test_moose.pl C:\>test_moose 20 520 C:\>
複雑なスクリプトのexe化
しかし、ちょっと複雑なスクリプトだと依存関係が解決できず、うまくいかない。
#!/usr/bin/perl { package MyApp; use Moose; use MooseX::AttributeHelpers; use Perl6::Say; has param_a => ( metaclass => "Number", is => "ro", isa => "Num", required => 1, provides => { add => "add_to_a", } ); sub say_a { my $self = shift; say $self->param_a; } } my $app = MyApp->new( param_a => 20 ); $app->say_a; $app->add_to_a( 500 ); $app->say_a;
ハイライトした部分でMooseX::AttributeHelpers
を使っている。このスクリプトをexe化して実行しようとすると……
C:\>pp -o test_moose2.exe test_moose2.pl C:\>test_moose2 Can't locate MooseX/AttributeHelpers/Trait/Base.pm in @INC (@INC contains: CODE(0x13f44b4) C:\DOCUME~1\delphinus\LOCALS~1\Temp\par-delphinus\cache-b1b75156f11447ac0b31ee7c267d96d75110c96d\inc\lib C:\DOCUME~1\delphinus\LOCALS~1\Temp\par-delphinus\cache-b1b75156f11447ac0b31ee7c267d96d75110c96d\inc CODE(0x126de64) CODE(0x126e164)). at Class/MOP.pm line 116 Class::MOP::load_first_existing_class('MooseX::AttributeHelpers::Trait::Base') called at Class/MOP.pm line 121 Class::MOP::load_class('MooseX::AttributeHelpers::Trait::Base') called at Moose/Util.pm line 108 Moose::Util::_apply_all_roles('Moose::Meta::Role=HASH(0x1ad1e54)', undef, 'MooseX::AttributeHelpers::Trait::Base ~以下略~
ものすごい量のエラーが出る。こういう時は-M
オプションを使って、足りないモジュールを追加してあげないといけない。
C:\>pp -M MooseX::AttributeHelpers::Trait::Base -M MooseX::AttributeHelpers::Trait::Collection -o test_moose2.exe test_moose2.pl C:\>test_moose2 20 520 C:\>
この“足りないモジュール”はTry&Errorで一つずつ見付けていくしかないのが辛いところ。まあ、exe化するつもりなら、元から妙なモジュールを使わないように気をつければいいだけなのかもしれない。
Pingback: 【Perl】Win32::GUI::LoftでGUIプログラミング | blog.delphinus.dev