carton bundle
を実行すると、App::FatPackerを用いて、cartonを1ファイルのスクリプトにまとめてくれます。
このfatpacked cartonをCentOS5のsystem perl(5.8.8)で使用したかったのですが、carton bundle
で生成されたfatpacked cartonを実行すると、エラーが発生して動きませんでした。
何とか動作させる方法を調べたので、エラーの原因と解消方法をまとめておこうと思います。
なお、carton bundle
でのfatpacked carton生成は、"experimental feature"のようです。
https://github.com/miyagawa/carton/issues/141
また、fatpacked cartonが原因の課題が多いため、carton bundle
ではデフォルトで作成させず、別コマンドに切り離すIssueが作成されてます。
https://github.com/miyagawa/carton/issues/156
Cartonのバージョン
v1.0.12
App::FatPackerがfatpackする条件
CHECKブロックで%INCからfatpackするモジュール一覧を取り出すので、それまでにrequireされたモジュール(のはず)
エラー内容と解決方法
1. Can't locate Algorithm/C3.pm in @INC
Algorithm::C3がfatpackされていないという理由で怒られます。
この問題の原因はClass::C3です。
CartonとAlgrorithm::C3の関係は以下の通り。
Carton \- Moo \- MRO::Compat \- Class::C3 \- Algorithm::C3
Class::C3はClass::C3::XSが存在する場合は、Algorithm::C3がrequireされません。
Class::C3::XSはPerlのバージョンが5.9.5より下であれば自動でインストールされるので、fatpackする時にXSが対象となり、Algorithm::C3はfatpackされません。
しかし、fatpacked cartonではXSモジュールのロードに失敗するので、Algrorithm::C3をrequireしようとしてエラーとなります。
(詳細はClass::C3のBEGINブロック参照)
対処法は、Class::C3::XSをuninstallすることです。
cpanm -U Class::C3::XS carton bunlde
因みに、Perl 5.10.0以上だとMRO::Compatのかわりにmroが使用されるので、この問題は発生しません。
(詳細はMoo/_mro.pmを参照)
2. List::Util version 1.33 required--this is only version 1.18
List::Utilのバージョンが古いという理由で怒られます。
これは、CPAN::Metaの2.133380以降がList::Utilの1.33以上に依存していることが原因です。
CartonはCPAN::Metaの2.120921に依存していますが、Perl 5.8.8のコアモジュールにCPAN::Metaが入っていないため、CPANからインストールされます。
この時インストールされるバージョンは2.140640(2014/03/11時点)です。
このバージョンではList::Util 1.33以上に依存しているので、併せてList::Util 1.38(2014/03/11時点)がインストールされ、carton bundle
時にfatpackされます。
しかし、List::UtilはXSモジュールなので、fatpacked cartonではロードに失敗します。
なので、コアのList::Utilが使われるのですが、バージョンが1.18と古いため、エラーが発生します。
対処法は、CPAN::MetaをuninstallしてCPAN::Metaの2.120921を入れ直せば良いです。
cpanm -U CPAN::Meta cpanm CPAN:Meta@2.120921 carton bundle
因みに、Perl 5.17.1以上だとコアモジュールにCPAN::Metaの2.120921が入っているので、この問題は発生しません。
まとめ
以下のどれかを採用しましょう。
- End of lifeとなったPerl 5.8.8とか使ってないで、Perl 5.18.2(or later)を使おう
- サーバセットアップ時にPerlと一緒にCartonをインストールしよう
- cpan-module-bootstrapを使おう
どうしてもPerl 5.8.8でfatpacked cartonを作りたければ、上記の方法で頑張ってつくろう。