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のモジュールを本番環境と同じバージョンに保持する
っと決めるのは簡単なのだが、これがまたなかなか大変・・・。
本番環境は下記の通り。
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でモジュールをコンパイルしてしまう。
自前でPerlを入れる場合は、/usr/bin/perl5.8.9 -Vの出力を参考に、
Snow Leopard付属のApacheは例のごとくUnivarsalで、デフォルトが64bitで起動する・・・。
自前でコンパイルする場合は、CFLAGSとARCHFLAGSを指定するとよい。
mod_perlも32bit版のApacheで。
DBもCFLAGSとARCHFLAGSを同様に指定してコンパイルするか、バイナリ版を利用する場合は、fileコマンドで32bitバージョンかどうか確認すること。
ちなみに、PostgreSQLは下記のようにした。
CPANモジュール。これが一筋縄ではいかない。まずバーションをあわせるため、本番環境の.cpanディレクトリをローカルにコピーし、ミラーを作成しておく。モジュールのダウンロード先をローカルのミラー二向ければ、理論上は同じバージョンでそろうはず。
そのため、ネットに接続しない環境にしておき、モジュールをインストールするほうがよい。たとえばHoge::Fugaというモジュールをインストールする場合、下記のような優先順位でインストールするとよい。
Snow Leopardならではのトラブル。あとから思いかえすと簡単なことなんだけどねぇ・・・。
デフォルトの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 ppcApacheも同様に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 commito 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ならではのトラブル。あとから思いかえすと簡単なことなんだけどねぇ・・・。