Catalyst 5.7x on Snow Leopard

| | コメント() | トラックバック(0)
MacBookでCatalystの開発をしていて、Snow Leopardにアップグレードしたら、案の定手間取った。

本番環境は下記の通り。

OS: i386 GNU/Linux
Perl: v5.8.x built for i686-linux
Aplication Server : Apache/2.2.x (Unix) with mod_perl 2.x
DB: PostgreSQL 8.x

なるべくこの環境に近い開発環境をSnow Leopardで作ろうと思ったが、なかなかうまくいかない・・・。

問題点を整理してみるとうまくいかない原因は、

・デフォルトで64bitでコンパイルされている、またはコンパイルしてしまうので、アーキテクチャがそろわないため、不具合が起きる
・CPANのモジュールが意図せずバージョンがあがってしまう
・Universal仕様でコンパイルされていると、Dinamicにlinkする場合にどのアーキテクチャ用にすべきかわからずに停止してしまう

などなど。64bitへの布石がウリであるSnow Leopardならではの不具合。

解決の方向性としては、
1. 関連するものをすべてi386, 32bitに統一する
2. CPANのモジュールを本番環境と同じバージョンに保持する

っと決めるのは簡単なのだが、これがまたなかなか大変・・・。
まずは、Perl。

デフォルトのPerlは5.10.0で、しかも64bitでモジュールをコンパイルしてしまう。
$ file `which perl`
/usr/bin/perl.org: Mach-O universal binary with 3 architectures
/usr/bin/perl.org (for architecture x86_64):    Mach-O 64-bit executable x86_64
/usr/bin/perl.org (for architecture i386):      Mach-O executable i386
/usr/bin/perl.org (for architecture ppc7400):   Mach-O executable ppc
今回はバージョンを本番環境とあわせるため、5.8.xを使用したい。/usr/binには、perl5.10.0とperl5.8.9も用意されているのだが、
$ file /usr/bin/perl5.8.9
/usr/bin/perl5.8.9.org: Mach-O universal binary with 2 architectures
/usr/bin/perl5.8.9.org (for architecture i386): Mach-O executable i386
/usr/bin/perl5.8.9.org (for architecture ppc7400):      Mach-O executable ppc
となっているため、CPANのモジュールをコンパイルする際に、
Can't load 'lib/auto/File/Glob/Glob.bundle' for module File::Glob: dlopen(lib/auto/File/Glob/Glob.bundle, 1): no suitable image found.  Did find:
        lib/auto/File/Glob/Glob.bundle: mach-o, but wrong architecture at lib/XSLoader.pm line 73.
 at lib/File/Glob.pm line 96
Compilation failed in require at installperl line 133.
BEGIN failed--compilation aborted at installperl line 133.
make[1]: *** [install.perl] Error 255
make: *** [install] Error 2
というようになってしまう。もしSnow Leopard付属のPerlを利用する場合は、
	$ cd /usr/bin
	$ sudo lipo ./perl5.8.9 -thin i386 -output ./perl.5.8.9.i386
	$ sudo mv perl{,.org}
	$ sudo ln -s ./perl.5.8.9.i386 ./perl
もしくは
$ sudo cat > /usr/bin/perl5.8.9.i386
#!/bin/sh
/usr/bin/arch -i386 /usr/bin/perl5.8.9
^D
$ sudo chmod 755 /usr/bin/perl5.8.9.i386
$ sudo ln -s /usr/bin/perl5.8.9.i386 /usr/bin/perl
というように、i386のみのバイナリにしておく。

自前でPerlを入れる場合は、/usr/bin/perl5.8.9 -Vの出力を参考に、
$ sh ./Configure ¥
    -ds -e ¥
    -Accflags="-arch i386 -g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing -I/usr/local/include" ¥
    -Aldflags="-arch i386 -L/usr/local/lib" ¥
    -Alddlflags="-arch i386 -bundle -undefined dynamic_lookup -L/usr/local/lib"
$ make; make test
$ sudo make install
i386 32bitバージョンのみのバイナリを作成しておく。
$ file /usr/local/bin/perl
/usr/local/bin/perl: Mach-O executable i386


Snow Leopard付属のApacheは例のごとくUnivarsalで、デフォルトが64bitで起動する・・・。
$ file /usr/sbin/httpd
/usr/sbin/httpd: Mach-O universal binary with 3 architectures
/usr/sbin/httpd (for architecture x86_64):  Mach-O 64-bit executable x86_64
/usr/sbin/httpd (for architecture i386):    Mach-O executable i386
/usr/sbin/httpd (for architecture ppc7400): Mach-O executable ppc
Apacheも同様にi386 32bitバージョンを作成するか、lipoコマンドで32bitバイナリを作成する。
自前でコンパイルする場合は、CFLAGSとARCHFLAGSを指定するとよい。
$ CFLAGS="-arch i386" ARCHFLAGS="-arch i386" ¥
./configure ¥
     --prefix=/usr/local/apache2 ¥
     --enable-module=so ¥
     --enable-proxy ¥
     --enable-dav ¥
     --enable-dav-fs ¥
     --enable-dav-lock ¥
     --enable-rewrite ¥
     --with-included-apr ¥
     --enable-ssl ¥
     --with-ssl=../openssl-$(OPENSSL_VERSION) ¥
     --enable-suexec ¥
     --with-suexec-caller=$(APACHE_USER) ¥
     --with-mpm=prefork ¥;
     make;
$ sudo make install
fileコマンドで確認。
$ file /usr/local/apache2/bin/httpd
/usr/local/apache2/bin/httpd: Mach-O executable i386


mod_perlも32bit版のApacheで。
$ perl Makefile.PL ¥
MP_APXS=/usr/local/apache2/bin/apxs; ¥
make; sudo make install

$ file /usr/local/apache2/modules/mod_perl.so
/usr/local/apache2/modules/mod_perl.so: Mach-O bundle i386


DBもCFLAGSとARCHFLAGSを同様に指定してコンパイルするか、バイナリ版を利用する場合は、fileコマンドで32bitバージョンかどうか確認すること。
ちなみに、PostgreSQLは下記のようにした。
$ ARCHFLAGS='-arch i386' ¥
CFLAGS='-arch i386' ¥
PERL=/usr/bin/perl ¥
./configure ¥
--prefix=/usr/local/pgsql ¥
--with-perl ¥
--with-pam ¥
--with-bonjour ¥
--with-libxml ¥
--enable-debug ¥
ここまでで、必要なすべての物がi386、32bitバージョンでそろうはず。


CPANモジュール。これが一筋縄ではいかない。まずバーションをあわせるため、本番環境の.cpanディレクトリをローカルにコピーし、ミラーを作成しておく。モジュールのダウンロード先をローカルのミラー二向ければ、理論上は同じバージョンでそろうはず。
$ mv .cpan ~/cpan
$ sudo cpan
> o conf urllist unshift file:///path/to/cpan/sources/
> o conf commit
o confコマンドで、urllistがローカルに置いたミラー先に向いていることを確認し、install Task::Catalystすればよいのだが、上記の設定で指定しても、あくまでも一次参照先でしかないので、ちょっと気を許すとftp.cpan.orgに取りにいってしまう。

そのため、ネットに接続しない環境にしておき、モジュールをインストールするほうがよい。たとえばHoge::Fugaというモジュールをインストールする場合、下記のような優先順位でインストールするとよい。
> install Hoge::Fuga
> install H/HF/HOGEFUGA/Hoge-Fuga.tar.gz
これでもできない場合は、しょうがなくcpan.orgからダウンロードする。tar玉の指定が大変なので、下記のようにリストを作っておいて、grepすると楽。
$ find /path/to/cpan -name '*.tar.gz' | sed -e 's!/path/to/cpan/sources/authors/id/!!' > cpan.txt
$ grep Hoge cpan.txt
理論上バージョンがそろうはずなのだが、実際にやってみるといつのまにかCatalyst::Runtimeが5.8にあがっていたりする・・・。そういう場合は、
> install M/MR/MRAMBERG/Catalyst-Runtime-5.7014.tar.gz
というように、強引に上書きするしかない。


Snow Leopardならではのトラブル。あとから思いかえすと簡単なことなんだけどねぇ・・・。

トラックバック(0)

このブログ記事を参照しているブログ一覧: Catalyst 5.7x on Snow Leopard

このブログ記事に対するトラックバックURL: http://blog.on-net.jp/tf/cgi-bin/mt-tb.cgi/22

コメント