VC++ とかでコンパイルに失敗する CPAN モジュールも、MinGW でコンパイルすれば使える、という話。たぶんありがちな話だしそのまんまの解説ページもあるんだけど、今回はじめてやったのでネタにしてみる。
■動機
きっかけはこれ。
404 Blog Not Found:perl - Encode-2.23 Released!
XSでPerl APIを直接呼び出している場合、一部APIににまだ文字列化されていない
Scalar(正確にはSV)を渡すとperlがほげるというのが原因でした。
もしかして最近 ActivePerl が不安定な気がしてたのはこれが原因?だったらいいなぁ。
試しに入れてみよう。
ということで、perl Makefile.PL && nmake install とかやってたら・・・
NMAKE : fatal error U1077: '"D:\Microsoft Visual Studio 8\VC\bin\cl.EXE"' : リターン コード '0x80'
Stop.
NMAKE : fatal error U1077: '"D:\Microsoft Visual Studio 8\VC\bin\nmake.exe"' : リターン コード '0x2'
みたいなエラーが。上記は VC++2005 でのエラーメッセージでよくわからなかったんだけど、会社(VC++6.0?)でやったら「sys/types.h がないですよ」的なメッセージが。
*nix 系じゃないとコンパイルできないのかなー?ってことで一旦放置
■MinGW を使ってみる
で、ひょんなことから MinGW を使えばコンパイルできそうなことがわかって。
MinGW で CPAN のモジュールをコンパイルする方法
これを試してみることに。ちなみに MinGW の入手は昨日 URL を貼った
Win32 + MSYS + MinGW 5.1.3 で SDL の開発環境を構築
の
MSYS + MinGW 環境用ファイル から落とすのが楽。公式サイトからは探しづらいので・・・。
で、この通りにやったんだけど、やっぱりエラーが。
NMAKE : fatal error U1073: 'C:\Perl\lib\CORE\libperl58.a' のビルド方法が指定されていません。
Stop.
NMAKE : fatal error U1077: '"d:\Microsoft Visual Studio\VC98\Bin\nmake.exe"' : リターン コード '0x2'
Stop.
■libperl58.a のエラー対策
libperl58.a って何?ということでググってみると。
Perl5 モジュールが使える Pugs をビルドするには
ExtUtils::FakeConfig をダウンロードして展開し(中略)インストールします。
これにより C:\Perl\lib\CORE に libperl58.a が作成されます。
んー・・・?できないよ?
ExtUtils::FakeConfig のバージョンによるとか?
それとも ExtUtils::FakeConfig 自体を MinGW つかってインストールしないとダメとか?
さらにググると。
nDiki: ActivePerl で Ming (2005-02-23)
ここで生成される Makefile の中で libperl58.a を指定している部分があるが、
ActivePerl では perl58.lib になるので、エディタで書き換え。
あー、そういう話か。MinGW 入れてると libXXX.a が作られる〜、とかそういう話かと思ってた。
perl Makefile.PL した後で Encode-2.23 配下の全ファイルに対して上記の置換。
ようやくコンパイル通った。
■CPAN shell では?
-MConfig_m をつけて perl Makefile.PL するために .tar.gz をいちいち落とすのは面倒なわけですが。
CPAN shell を使いたい場合は、
マニュアル にあるように、
set PERL5OPT=-MConfig_m
perl -MCPAN -eshell
みたいにやるといいみたい。
■libperl58.a の全置換が面倒な場合は?
上記の方法でいけることはわかったんだけど、事あるごとに libperl58.a の全置換とか面倒。
ということで、家の PC にインストールするときは別の方法を試してみた。
copy C:\Perl\lib\CORE\perl58.lib C:\Perl\lib\CORE\libperl58.a
とか。これでも問題ないみたい。
■nmake のパスによる問題
で、うまくいったんだけど nmake test とやると、妙なエラーが。
Can't find string terminator "'" anywhere before EOF at -e line 1.
NMAKE : fatal error U1077: 'C:\Perl\bin\perl.exe' : リターン コード '0xff'
Stop.
どうも perl -e "system('"D:\Microsoft Visual Studio 8\VC\bin\nmake.exe"')" みたいなコマンドが発行されている箇所があるみたい。仕方ないので、Makefile の頭のほうに
MAKE = D:\MICROS~1\VC\bin\nmake.exe
みたいなショートネームを指定しておいた。ショートネームを調べるには dir /x とか。
■墓穴
さらに make install すると、こんなエラーが。
Cannot forceunlink C:\Perl\lib\auto\Encode\Encode.dll: Permission denied at C:/P
erl/lib/File/Find.pm line 918
NMAKE : fatal error U1077: 'C:\Perl\bin\perl.exe' : リターン コード '0xd'
元々の Encode モジュールを消すためのスクリプト自信で Encode モジュールを使っているから、ファイルの削除の失敗してるっぽい。会社ではちゃんと動いたんだけどなぁ・・・?
一時間くらい悩んだところで気付いたけど、以前 File::Copy を
マルチバイト対応のために書き換えてたんだった。
これを元に戻したらすんなりインストールできました。
■で、perl が落ちる件は解決できたの?
ドキドキしながら実行してみる。
perl.exe - アプリケーション エラー
例外 unknown software exception (0xc0000005) がアプリケーションの 0x7d6010c8 で発生しました。
プログラムを終了するには [OK] をクリックしてください
プログラムをデバッグするには [キャンセル] をクリックしてください
結局 perl が落ちる件は未解決・・・と。
Encode と DBI の相性が悪いとか最近どこかで見かけた気がするし、今度はそっちから探るかな・・・。