【perlメモ】ActivePerl 5.8.8 Build 824とPAR-Packer-1.008でperlのexe化環境の構築

perlのスクリプトをexe化する方法があるのですが、割とハードルが高いのであまり知られて無いように思います。私も随分前からやってみたいと思っていましたが面倒で今までやったこと無かったのですが初めてやってみました。どういう場合に便利なのかというと、通常のexeファイルのプログラムの様に実行ファイルを渡せばそれだけで使えるようになるのでperl自体をインストールしていない人でもすぐに使えるわけです。配布するときに便利です。しかし、結構面倒で現在の処は誰でも気軽にexe化できる状態とはいえない様です。

初めてだったので実際ハマリまくって、一晩掛かりました。

あまり理解せずに環境と作ろうとしたのではまったのですが、ある程度理化していると楽になる項目をまとめておくと。

  • perlのバージョンとビルドとPAR-Packer(以下PAR)のバージョンは合わせる必要がある。それ以外の場合は自分でコンパイルする必要がある。

基本はこちらのサイト「ぶたときどき真珠~深沢千尋のブログ~ ActivePerl 5.8.9でPARを使う」の記事を参考にして環境を構築した。ActivePerl5.8.8 Build 824を使ってexe化環境を作った人の記事が見つからなかったので成功するかわからなかったが色々手探りしながら環境を構築した。

色々モジュールを追加する必要があるが、基本的にはppmを使って行った。CPANモジュールなどをppmを使ってインストールする方法は以下の記事を参考にしてほしい。

ActivePerlにGDをインストールする – KUMA TYPE

  1. PAR-Packerはppmからもインストールできるが ActivePerl5.8.8 Build824用は見当たらなかった。一通り入れてMみたが、ぜんぜん動かなかった。20100612
    適当にインストールしても下のようなエラーが出て使えない。
    「プロシージャエントリポイント Perl_sv_2iv_flagsがダイナミックリンクライブラリperl58.dllから見つかりませんでした。」
    20100604 
    「プロシージャエントリポイント Perl_hv_common_key_lenがダイナミックリンクライブラリperl58.dllから見つかりませんでした。」
    20100605
  2. ExtUtils-FakeConfigのインストール。ppmでVer.0.12をインストールした。
    20100614
  3. MinGWをインストール
    MinGW – Minimalist GNU for Windows – Browse Files at SourceForge.netからmingw-get-inst-20101030.exeをダウンロードしてインストール。[Next]>[Next]>[Next]>[I accept the agreement]>[Next]>[Next]>[Next]と進んで、[Select Components]の画面では下の二つにチェックを入れて[Next]>[Install]>[Finish]でインストール完了。
    20100615
  4. 環境変数の追加
    [スタート]>マイコンピュータを右クリック>[プロパティ]>[システムのプロパティ]の画面で[詳細設定]タブをクリック>[環境変数]をクリック>[環境変数]の画面で[システム環境変数]の変数[Path]を選択して[編集]をクリック>[変数値]の頭に「C:\MinGW\bin;C:\MinGW\msys\1.0\bin;」を追記>追記したら各画面の[OK]ボタンを押して閉じる。
    20100617
    20100618
  5. NMAKEがインストールされていなければインストール。
    http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/nmake15.exeからダウンロードできる。ダウンロードしたファイルを実行すると自己展開されるので出てきたファイルをどこかPathの通っているところにコピーする。(C:\Windowsなど)
    既にインストールしているかどうかはコマンドプロンプトでnmakeと打てばよい。下の画像の様にnmakeがパスが通ったところに存在すれば何らかの反応がある。
    20100619 
  6. PAR::Packerのダウンロード。
    Browse and search CPAN : PAR::Packer[http://cpan.uwinnipeg.ca/module/PAR::Packer]
    から、PAR-Packer-1.008.tar.gzをダウンロードする。適当な解凍ソフトで解凍(展開)する。解凍レンジで解凍できた。
  7. ファイルの修正。
    現在も必要なのか不明だが参考サイトの記述にしたがって、script\par.plの753行目(require_modulesというサブルーチンの中)に

    require Win32 if $^O eq ‘MSWin32’;
    という行を追加して下の様に変更した。

        require PAR::Filter::PodStrip;
        require Win32 if $^O eq ‘MSWin32’;
        require attributes;
        eval { require Cwd };

  8. PAR::Packerのコンパイル。
    以下の順序でコマンドを実行してコンパイルを行う。

    >perl Makefile.PL
    >nmake
    >nmake test
    >nmake install
    >perl -MConfig_m Makefile.PL
    >nmake
    >nmake test
    >nmake install

  9. perl Makefile.PLしたところ

    C:\PAR-Packer-1.008>perl Makefile.PL
    Set up gcc environment – 4.5.0
    Checking if your kit is complete…
    Looks good
    Writing Makefile for the par.exe program
    Writing Makefile for PAR::Packer

    C:\PAR-Packer-1.008>

  10. nmake したところ

    C:\PAR-Packer-1.008>nmake

    Microsoft (R) Program Maintenance Utility   Version 1.50
    Copyright (c) Microsoft Corp 1988-94. All rights reserved.

             C:\Perl\bin\perl.exe "-Minc::Module::Install" -e "extract_par(q(PAR-Packer-1.008-MSWin32-x86-multi-thread-5.8.8.par))"
    Set up gcc environment – 4.5.0
    cp lib/App/Packer/PAR.pm blib\lib\App\Packer\PAR.pm
    cp lib/PAR/Packer.pm blib\lib\PAR\Packer.pm
    cp lib/PAR/Filter/Obfuscate.pm blib\lib\PAR\Filter\Obfuscate.pm
    cp lib/PAR/Filter/PodStrip.pm blib\lib\PAR\Filter\PodStrip.pm
    cp lib/PAR/StrippedPARL/Base.pm blib\lib\PAR\StrippedPARL\Base.pm
    cp lib/PAR/Filter.pm blib\lib\PAR\Filter.pm
    cp lib/PAR/Filter/PatchContent.pm blib\lib\PAR\Filter\PatchContent.pm
    cp lib/PAR/StrippedPARL/Dynamic.pm blib\lib\PAR\StrippedPARL\Dynamic.pm
    cp lib/PAR/Filter/Bytecode.pm blib\lib\PAR\Filter\Bytecode.pm
    cp lib/pp.pm blib\lib\pp.pm
    cp lib/PAR/Filter/Bleach.pm blib\lib\PAR\Filter\Bleach.pm
    cp lib/PAR/StrippedPARL/Static.pm blib\lib\PAR\StrippedPARL\Static.pm
            nmake -f Makefile all -nologo
            C:\Perl\bin\perl.exe sha1.c.PL sha1.c
            gcc -c -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DNO_HA
    SH_SEED -DUSE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMPLICIT_CONTEXT -DPERL
    _IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX -DHASATTRIBUTE -fno-strict-alia
    sing -mms-bitfields  -I"C:\Perl\lib\CORE"  -DPARL_EXE=\"parl.exe\" -O2 main.c
            C:\Perl\bin\perl.exe file2c.pl -s ..\script\par.pl -l my_par_pl.c load_m
    y_par_pl
            gcc -c -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DNO_HA
    SH_SEED -DUSE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMPLICIT_CONTEXT -DPERL
    _IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX -DHASATTRIBUTE -fno-strict-alia
    sing -mms-bitfields  -I"C:\Perl\lib\CORE"  -DPARL_EXE=\"parl.exe\" -O2 my_par_pl
    .c
            g++ main.o my_par_pl.o win32.coff -s   -L"C:\Perl\lib\CORE"  C:\Perl\lib
    \CORE\perl58.lib C:\MinGW\lib\libkernel32.a C:\MinGW\lib\libuser32.a C:\MinGW\li
    b\libgdi32.a C:\MinGW\lib\libwinspool.a C:\MinGW\lib\libcomdlg32.a C:\MinGW\lib\
    libadvapi32.a C:\MinGW\lib\libshell32.a C:\MinGW\lib\libole32.a C:\MinGW\lib\lib
    oleaut32.a C:\MinGW\lib\libnetapi32.a C:\MinGW\lib\libuuid.a C:\MinGW\lib\libws2
    _32.a C:\MinGW\lib\libmpr.a C:\MinGW\lib\libwinmm.a C:\MinGW\lib\libversion.a C:
    \MinGW\lib\libodbc32.a C:\MinGW\lib\libodbccp32.a C:\MinGW\lib\libmsvcrt.a -lper
    l58 -o par.exe
            C:\Perl\bin\perl.exe -e1
            C:\Perl\bin\perl.exe file2c.pl -l -c 30000 par.exe my_par.c load_my_par
            C:\Perl\bin\perl.exe file2c.pl -l -c 30000 -n perl58.dll C:\Perl\bin\perl58.dll my_libperl.c load_my_libperl
            gcc -c -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DNO_HA
    SH_SEED -DUSE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMPLICIT_CONTEXT -DPERL
    _IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX -DHASATTRIBUTE -fno-strict-alia
    sing -mms-bitfields  -I"C:\Perl\lib\CORE"  -DPARL_EXE=\"parl.exe\" -O2 static.c
            g++ static.o -s   -L"C:\Perl\lib\CORE"  C:\Perl\lib\CORE\perl58.lib C:\M
    inGW\lib\libkernel32.a C:\MinGW\lib\libuser32.a C:\MinGW\lib\libgdi32.a C:\MinGW
    \lib\libwinspool.a C:\MinGW\lib\libcomdlg32.a C:\MinGW\lib\libadvapi32.a C:\MinG
    W\lib\libshell32.a C:\MinGW\lib\libole32.a C:\MinGW\lib\liboleaut32.a C:\MinGW\l
    ib\libnetapi32.a C:\MinGW\lib\libuuid.a C:\MinGW\lib\libws2_32.a C:\MinGW\lib\li
    bmpr.a C:\MinGW\lib\libwinmm.a C:\MinGW\lib\libversion.a C:\MinGW\lib\libodbc32.
    a C:\MinGW\lib\libodbccp32.a C:\MinGW\lib\libmsvcrt.a -lperl58 win32.coff -o sta
    tic.exe
            C:\Perl\bin\perl.exe -e1
            C:\Perl\bin\perl.exe parlsig.pl static.exe par.exe 1 30000
            C:\Perl\bin\perl.exe run_with_inc.pl static.exe -I../blib/lib -q -B -O..\script\parl.exe
    Set up gcc environment – 4.5.0
    Copyright (C) 2010 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

            C:\Perl\bin\perl.exe -e "chmod(oct(‘0600’), ‘..\blib\lib\PAR\StrippedPARL\Static.pm’);"
            C:\Perl\bin\perl.exe encode_append.pl static.exe ..\blib\lib\PAR\StrippedPARL\Static.pm
            C:\Perl\bin\perl.exe -e "chmod(oct(‘0444’), ‘..\blib\lib\PAR\StrippedPARL\Static.pm’);"
            C:\Perl\bin\perl.exe run_with_inc.pl par.exe -I../blib/lib -q -B -O..\script\parldyn.exe
    Set up gcc environment – 4.5.0
    Copyright (C) 2010 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

            C:\Perl\bin\perl.exe -e "chmod(oct(‘0600’), ‘..\blib\lib\PAR\StrippedPARL\Dynamic.pm’);"
            C:\Perl\bin\perl.exe encode_append.pl par.exe ..\blib\lib\PAR\StrippedPARL\Dynamic.pm
            C:\Perl\bin\perl.exe -e "chmod(oct(‘0444’), ‘..\blib\lib\PAR\StrippedPARL\Dynamic.pm’);"
            cd ..
            C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/parldyn.exe blib\script\parldyn.exe
            C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/parl.exe blib\script\parl.exe
            C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/tkpp blib\script\tkpp
            pl2bat.bat blib\script\tkpp
            C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/pp blib\script\pp
            pl2bat.bat blib\script\pp
            C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/par.pl blib\script\par.pl
            pl2bat.bat blib\script\par.pl

    C:\PAR-Packer-1.008>

  11. nmake test
    長いので省略
  12. nmake installの結果

    C:\PAR-Packer-1.008>nmake install

    Microsoft (R) Program Maintenance Utility   Version 1.50
    Copyright (c) Microsoft Corp 1988-94. All rights reserved.

         C:\Perl\bin\perl.exe "-Minc::Module::Install" -e "extract_par(q(PAR-Packer-1.008-MSWin32-x86-multi-thread-5.8.8.par))"
    Set up gcc environment – 4.5.0
        nmake -f Makefile all -nologo
        C:\Perl\bin\perl.exe -e "chmod(oct(‘0600’), ‘..\blib\lib\PAR\StrippedPARL\Static.pm’);"
        C:\Perl\bin\perl.exe encode_append.pl static.exe ..\blib\lib\PAR\StrippedPARL\Static.pm
        C:\Perl\bin\perl.exe -e "chmod(oct(‘0444’), ‘..\blib\lib\PAR\StrippedPARL\Static.pm’);"
        C:\Perl\bin\perl.exe -e "chmod(oct(‘0600’), ‘..\blib\lib\PAR\StrippedPARL\Dynamic.pm’);"
        C:\Perl\bin\perl.exe encode_append.pl par.exe ..\blib\lib\PAR\StrippedPARL\Dynamic.pm
        C:\Perl\bin\perl.exe -e "chmod(oct(‘0444’), ‘..\blib\lib\PAR\StrippedPARL\Dynamic.pm’);"
        cd ..
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/tkpp blib\script\tkpp
        pl2bat.bat blib\script\tkpp
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/pp blib\script\pp
        pl2bat.bat blib\script\pp
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/par.pl blib\script\par.pl
        pl2bat.bat blib\script\par.pl
    Installing C:\Perl\html\bin\par.html
    Installing C:\Perl\html\bin\tkpp.html
    Installing C:\Perl\html\site\lib\pp.html
    Installing C:\Perl\html\site\lib\PAR\Filter.html
    Installing C:\Perl\html\site\lib\PAR\Packer.html
    Installing C:\Perl\html\site\lib\PAR\Filter\Bleach.html
    Installing C:\Perl\html\site\lib\PAR\Filter\Bytecode.html
    Installing C:\Perl\html\site\lib\PAR\Filter\Obfuscate.html
    Installing C:\Perl\html\site\lib\PAR\Filter\PatchContent.html
    Installing C:\Perl\html\site\lib\PAR\Filter\PodStrip.html
    Installing C:\Perl\html\site\lib\PAR\StrippedPARL\Dynamic.html
    Installing C:\Perl\html\site\lib\PAR\StrippedPARL\Static.html
    Installing C:\Perl\site\lib\PAR\StrippedPARL\Dynamic.pm
    Installing C:\Perl\site\lib\PAR\StrippedPARL\Static.pm
    Installing C:\Perl\site\bin\parl.exe
    Installing C:\Perl\site\bin\parldyn.exe
    Appending installation info to C:\Perl\lib/perllocal.pod

    C:\PAR-Packer-1.008>

  13. perl -MConfig_m Makefile.PLの結果

    C:\PAR-Packer-1.008>perl -MConfig_m Makefile.PL
    Set up gcc environment – 4.5.0
    Writing Makefile for the par.exe program
    Writing Makefile for PAR::Packer

    C:\PAR-Packer-1.008>

  14. nmakeの結果その2(失敗)

    C:\PAR-Packer-1.008>nmake

    Microsoft (R) Program Maintenance Utility   Version 1.50
    Copyright (c) Microsoft Corp 1988-94. All rights reserved.

         C:\Perl\bin\perl.exe "-Minc::Module::Install" -e "extract_par(q(PAR-Packer-1.008-MSWin32-x86-multi-thread-5.8.8.par))"
    Set up gcc environment – 4.5.0
        nmake -f Makefile all -nologo
        gcc -c -O2 -DWIN32 -DPERL_IMPLICIT_CONTEXT -DPERL_MSVCRT_READFIX  -I"C:\Perl\lib\CORE"  -DPARL_EXE=\"parl.exe\" -O2 main.c
    In file included from utils.c:25:0,
                     from mktmpdir.h:84,
                     from mktmpdir.c:1,
                     from main.c:53:
    env.c: In function ‘__findenv’:
    env.c:56:16: warning: ‘win32_environ’ redeclared without dllimport attribute: previous dllimport ignored
        g++ main.o my_par_pl.o win32.coff -s   -s -L"C:\Perl\lib\CORE"  C:\Perl\lib\CORE\libperl58.a C:\MinGW\lib\libmsvcrt.a C:\MinGW\lib\libmoldname.a C:\MinGW\lib\libkernel32.a C:\MinGW\lib\libuser32.a C:\MinGW\lib\libgdi32.a C:\MinGW\lib\libwinspool.a C:\MinGW\lib\libcomdlg32.a C:\MinGW\lib\libadvapi32.a C:\MinGW\lib\libshell32.a C:\MinGW\lib\libole32.a C:\MinGW\lib\liboleaut32.a C:\MinGW\lib\libnetapi32.a C:\MinGW\lib\libuuid.a C:\MinGW\lib\libwsock32.a C:\MinGW\lib\libmpr.a C:\MinGW\lib\libwinmm.a C:\MinGW\lib\libversion.a C:\MinGW\lib\libodbc32.a -llibperl58.a -o par.exe
    c:/mingw/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/bin/ld.exe: cannot find -llibperl58.a
    collect2: ld returned 1 exit status
    NMAKE : fatal error U1077: ‘C:\WINDOWS\system32\cmd.exe’ : return code ‘0x1’
    Stop.
    NMAKE : fatal error U1077: ‘C:\WINDOWS\system32\cmd.exe’ : return code ‘0x2’
    Stop.

    C:\PAR-Packer-1.008>

    上記の様にエラーになってしまった。「cannot find -llibperl58.a」の部分がエラーメッセージの肝。色々調べたところこちらのサイト(MinGW で CPAN モジュールをコンパイル – miau's blog?)の記事が参考になった。上の方で「ExtUtils-FakeConfig」モジュールをppmでインストールしたがこれでlibperl58.aが作成されるはずだが、実際にはperl58.libという名前で作成されているらしいのでファイルが見つからないという事らしい。そういうわけで簡単にperl58.libをlibperl58.aという名前でコピーした。perl58.lib通常下のフォルダにあるはず。

    C:\Perl\lib\CORE

    単純にファイル名の違う内容の同じファイルが同じフォルダに二つあることになる。
    しかし結果は同じエラーになった。

  15. nmake結果その3(成功)
    14.の結果も結局同じエラーになったので結局Makefileを書き換えた。
    PAR-Packer-1.008\myldr\Makefile
    の11行目と12行目は以下の様になっている。

    PERL_LDFLAGS=-s   -s -L"C:\Perl\lib\CORE"  C:\MinGW\lib\libmsvcrt.a C:\MinGW\lib\libmoldname.a C:\MinGW\lib\libkernel32.a C:\MinGW\lib\libuser32.a C:\MinGW\lib\libgdi32.a C:\MinGW\lib\libwinspool.a C:\MinGW\lib\libcomdlg32.a C:\MinGW\lib\libadvapi32.a C:\MinGW\lib\libshell32.a C:\MinGW\lib\libole32.a C:\MinGW\lib\liboleaut32.a C:\MinGW\lib\libnetapi32.a C:\MinGW\lib\libuuid.a C:\MinGW\lib\libwsock32.a C:\MinGW\lib\libmpr.a C:\MinGW\lib\libwinmm.a C:\MinGW\lib\libversion.a C:\MinGW\lib\libodbc32.a -llibperl58.a
    STATIC_LDFLAGS=-s   -s -L"C:\Perl\lib\CORE"  C:\MinGW\lib\libmsvcrt.a C:\MinGW\lib\libmoldname.a C:\MinGW\lib\libkernel32.a C:\MinGW\lib\libuser32.a C:\MinGW\lib\libgdi32.a C:\MinGW\lib\libwinspool.a C:\MinGW\lib\libcomdlg32.a C:\MinGW\lib\libadvapi32.a C:\MinGW\lib\libshell32.a C:\MinGW\lib\libole32.a C:\MinGW\lib\liboleaut32.a C:\MinGW\lib\libnetapi32.a C:\MinGW\lib\libuuid.a C:\MinGW\lib\libwsock32.a C:\MinGW\lib\libmpr.a C:\MinGW\lib\libwinmm.a C:\MinGW\lib\libversion.a C:\MinGW\lib\libodbc32.a -llibperl58.a

    これを下の様に書き換えた。

    PERL_LDFLAGS=-s   -s -L"C:\Perl\lib\CORE"  C:\MinGW\lib\libmsvcrt.a C:\MinGW\lib\libmoldname.a C:\MinGW\lib\libkernel32.a C:\MinGW\lib\libuser32.a C:\MinGW\lib\libgdi32.a C:\MinGW\lib\libwinspool.a C:\MinGW\lib\libcomdlg32.a C:\MinGW\lib\libadvapi32.a C:\MinGW\lib\libshell32.a C:\MinGW\lib\libole32.a C:\MinGW\lib\liboleaut32.a C:\MinGW\lib\libnetapi32.a C:\MinGW\lib\libuuid.a C:\MinGW\lib\libwsock32.a C:\MinGW\lib\libmpr.a C:\MinGW\lib\libwinmm.a C:\MinGW\lib\libversion.a C:\MinGW\lib\libodbc32.a -lperl58
    STATIC_LDFLAGS=-s   -s -L"C:\Perl\lib\CORE"  C:\MinGW\lib\libmsvcrt.a C:\MinGW\lib\libmoldname.a C:\MinGW\lib\libkernel32.a C:\MinGW\lib\libuser32.a C:\MinGW\lib\libgdi32.a C:\MinGW\lib\libwinspool.a C:\MinGW\lib\libcomdlg32.a C:\MinGW\lib\libadvapi32.a C:\MinGW\lib\libshell32.a C:\MinGW\lib\libole32.a C:\MinGW\lib\liboleaut32.a C:\MinGW\lib\libnetapi32.a C:\MinGW\lib\libuuid.a C:\MinGW\lib\libwsock32.a C:\MinGW\lib\libmpr.a C:\MinGW\lib\libwinmm.a C:\MinGW\lib\libversion.a C:\MinGW\lib\libodbc32.a -lperl58

    結果、下の様にコンパイルに成功。

    C:\PAR-Packer-1.008>nmake

    Microsoft (R) Program Maintenance Utility   Version 1.50
    Copyright (c) Microsoft Corp 1988-94. All rights reserved.

         C:\Perl\bin\perl.exe "-Minc::Module::Install" -e "extract_par(q(PAR-Packer-1.008-MSWin32-x86-multi-thread-5.8.8.par))"
    Set up gcc environment – 4.5.0
        nmake -f Makefile all -nologo
        g++ main.o my_par_pl.o win32.coff -s   -s -L"C:\Perl\lib\CORE"  C:\MinGW\lib\libmsvcrt.a C:\MinGW\lib\libmoldname.a C:\MinGW\lib\libkernel32.a C:\MinGW\lib\libuser32.a C:\MinGW\lib\libgdi32.a C:\MinGW\lib\libwinspool.a C:\MinGW\lib\libcomdlg32.a C:\MinGW\lib\libadvapi32.a C:\MinGW\lib\libshell32.a C:\MinGW\lib\libole32.a C:\MinGW\lib\liboleaut32.a C:\MinGW\lib\libnetapi32.a C:\MinGW\lib\libuuid.a C:\MinGW\lib\libwsock32.a C:\MinGW\lib\libmpr.a C:\MinGW\lib\libwinmm.a C:\MinGW\lib\libversion.a C:\MinGW\lib\libodbc32.a -lperl58 -o par.exe
        C:\Perl\bin\perl.exe -e1
        C:\Perl\bin\perl.exe file2c.pl -l -c 30000 par.exe my_par.c load_my_par
        C:\Perl\bin\perl.exe file2c.pl -l -c 30000 -n perl58.dll C:\Perl\bin\perl58.dll my_libperl.c load_my_libperl
        gcc -c -O2 -DWIN32 -DPERL_IMPLICIT_CONTEXT -DPERL_MSVCRT_READFIX  -I"C:\Perl\lib\CORE"  -DPARL_EXE=\"parl.exe\" -O2 static.c
        g++ static.o -s   -s -L"C:\Perl\lib\CORE"  C:\MinGW\lib\libmsvcrt.a C:\MinGW\lib\libmoldname.a C:\MinGW\lib\libkernel32.a C:\MinGW\lib\libuser32.a C:\MinGW\lib\libgdi32.a C:\MinGW\lib\libwinspool.a C:\MinGW\lib\libcomdlg32.a C:\MinGW\lib\libadvapi32.a C:\MinGW\lib\libshell32.a C:\MinGW\lib\libole32.a C:\MinGW\lib\liboleaut32.a C:\MinGW\lib\libnetapi32.a C:\MinGW\lib\libuuid.a C:\MinGW\lib\libwsock32.a C:\MinGW\lib\libmpr.a C:\MinGW\lib\libwinmm.a C:\MinGW\lib\libversion.a C:\MinGW\lib\libodbc32.a -lperl58 win32.coff -o static.exe
        C:\Perl\bin\perl.exe -e1
        C:\Perl\bin\perl.exe parlsig.pl static.exe par.exe 1 30000
        C:\Perl\bin\perl.exe run_with_inc.pl static.exe -I../blib/lib -q -B -O..\script\parl.exe
    Set up gcc environment – 4.5.0
    Copyright (C) 2010 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

        C:\Perl\bin\perl.exe -e "chmod(oct(‘0600’), ‘..\blib\lib\PAR\StrippedPARL\Static.pm’);"
        C:\Perl\bin\perl.exe encode_append.pl static.exe ..\blib\lib\PAR\StrippedPARL\Static.pm
        C:\Perl\bin\perl.exe -e "chmod(oct(‘0444’), ‘..\blib\lib\PAR\StrippedPARL\Static.pm’);"
        C:\Perl\bin\perl.exe run_with_inc.pl par.exe -I../blib/lib -q -B -O..\script\parldyn.exe
    Set up gcc environment – 4.5.0
    Copyright (C) 2010 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

        C:\Perl\bin\perl.exe -e "chmod(oct(‘0600’), ‘..\blib\lib\PAR\StrippedPARL\Dynamic.pm’);"
        C:\Perl\bin\perl.exe encode_append.pl par.exe ..\blib\lib\PAR\StrippedPARL\Dynamic.pm
        C:\Perl\bin\perl.exe -e "chmod(oct(‘0444’), ‘..\blib\lib\PAR\StrippedPARL\Dynamic.pm’);"
        cd ..
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/parldyn.exe blib\script\parldyn.exe
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/parl.exe blib\script\parl.exe
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/tkpp blib\script\tkpp
        pl2bat.bat blib\script\tkpp
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/pp blib\script\pp
        pl2bat.bat blib\script\pp
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/par.pl blib\script\par.pl
        pl2bat.bat blib\script\par.pl

    C:\PAR-Packer-1.008>

  16. nmake testの結果。
    長いので省略。結果は正常終了。
  17. nmke installの結果

    C:\PAR-Packer-1.008>

    Microsoft (R) Program Maintenance Utility   Version 1.50
    Copyright (c) Microsoft Corp 1988-94. All rights reserved.

         C:\Perl\bin\perl.exe "-Minc::Module::Install" -e "extract_par(q(PAR-Packer-1.008-MSWin32-x86-multi-thread-5.8.8.par))"
    Set up gcc environment – 4.5.0
        nmake -f Makefile all -nologo
        C:\Perl\bin\perl.exe -e "chmod(oct(‘0600’), ‘..\blib\lib\PAR\StrippedPARL\Static.pm’);"
        C:\Perl\bin\perl.exe encode_append.pl static.exe ..\blib\lib\PAR\StrippedPARL\Static.pm
        C:\Perl\bin\perl.exe -e "chmod(oct(‘0444’), ‘..\blib\lib\PAR\StrippedPARL\Static.pm’);"
        C:\Perl\bin\perl.exe -e "chmod(oct(‘0600’), ‘..\blib\lib\PAR\StrippedPARL\Dynamic.pm’);"
        C:\Perl\bin\perl.exe encode_append.pl par.exe ..\blib\lib\PAR\StrippedPARL\Dynamic.pm
        C:\Perl\bin\perl.exe -e "chmod(oct(‘0444’), ‘..\blib\lib\PAR\StrippedPARL\Dynamic.pm’);"
        cd ..
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/tkpp blib\script\tkpp
        pl2bat.bat blib\script\tkpp
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/pp blib\script\pp
        pl2bat.bat blib\script\pp
        C:\Perl\bin\perl.exe "-Iinc" -MExtUtils::Command -e cp script/par.pl blib\script\par.pl
        pl2bat.bat blib\script\par.pl
    Installing C:\Perl\site\lib\PAR\StrippedPARL\Dynamic.pm
    Installing C:\Perl\site\lib\PAR\StrippedPARL\Static.pm
    Installing C:\Perl\site\bin\parl.exe
    Installing C:\Perl\site\bin\parldyn.exe
    Appending installation info to C:\Perl\lib/perllocal.pod

    C:\PAR-Packer-1.008>

  18. ppを使ってみるテスト。
    本当に簡単に1行のサンプルプログラムを書いた。
    test.pl
    print "PAR Test\n";

    これをppコマンドを使って下の様にexe化する。
    pp [-o 出力ファイル] <ソースファイル>

    > pp -o test.exe test.pl

    ppの使い方は下記のサイトを見ると良い。
    [PAR] perlをexe化 :: ぼくはまちちゃん!
    pp – search.cpan.org
    実行結果

    C:\PAR-Packer-1.008>pp -o test.exe test.pl
    Set up gcc environment – 4.5.0
    Set up gcc environment – 4.5.0
    Copyright (C) 2010 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    Set up gcc environment – 4.5.0
    Copyright (C) 2010 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    C:\PAR-Packer-1.008>test
    PAR Test

    C:\PAR-Packer-1.008>

  19. 少し複雑なプログラムを組むとエラーになる。
    パッケージをうまくパックできないとエラーになるらしい。
    下の様にかなり最初は手間取った。exe化は出来たがいざ実行しようとすると下の様にエラーが発生する。
    20100606

    上のエラーでは「Cant’t call method "desiredCompressionMethod" on an undefined」というエラーが発生しているが、エラーメッセージに表示されている「C:\Perl\site\lib\PAR\Packer.pm」の1128行目付近を見てみると[Archive::Zip]モジュールが必要そうなことがわかるのでppmからインストールする事で解決した。  20100607
    上のエラーは「Can’t locate Image/ExifTool/Writer.pl」と出ているので、「Image::ExifTool」パッケージがパックできなかったのだろうと参考にしたサイトの記事などを見て

    > pp -M Image::ExifTool -o mbc.exe mbc.pl

    などとしてみたがダメだった。

    >pp -M"C:\Perl\site\lib\Image\ExifTool\Writer.pl" -o mbc.exe mbc.pl

    上の様にしてみた場合も、出来たexeファイルを実行するとエラーになる。どうやらフルパスで書くとその書いたフルパスでテンポラリディレクトリが作られるためにフォルダを作成できずにエラーになるようだ。(C:\とかはフォルダ名に出来ないので)、結局色々試した結果。モジュールが.plファイルの場合。以下の様にする事で正常に実行できるようにモジュールを取り込めるようになった。フルパスで指定しないのがミソ。

    >pp -M "Image/ExifTool/Writer.pl" -o mbc.exe mbc.pl

     

PARの環境構築で参考にさせていただいたサイト

pp使い方で参考にさせていただいたサイト

問題解決時に参考にさせていただいたサイト

必要なソフト類の入手先

nmakeリファレンス

g++オプション

追記:2010/12/07

書き忘れてた事があったので追記。

実際に作成したexeファイルを他のパソコンに持っていって実行したところ「libgcc_s_dw2-1.dll」が無いといって怒られた。

「libgcc_s_dw2-1.dll」は通常「C:\MinGW\bin」に格納されているexeファイルと一緒に渡して同じフォルダにおいて実行すれば怒られる事は無い。

「libgcc_s_dw2-1.dll」自体はネットで検索すればSourceForge.JPなどでいくらでもダウンロードできるので配布時にはダウンロード先のページを明記するか検索して入手するように書いておけばいいだろう。

未確認だがexeファイルと一緒にDLLを添付する場合GNUライセンスになると思われる。この場合ソースを公開することになるのではないかと思うがPARの場合perlのソースとモジュール関係をパックしただけなのでソースコードを公開してるのと同じなので問題ないと考えていいのかな?

タグ : , ,