perl-5.8.8 on Fedora リビルド顛末記

2007/10/11 追記

そういえば言及し忘れてましたが(FC 7 だと rel 19)

* Sat Jun 23 07:00:00 2007 Robin Norwood - 4:5.8.8-19

  • Resolves: rhbz#196836
  • Apply upstream patch #28775, which fixes an issue where reblessing overloaded objects incurs significant performance penalty

という changelog があがってたんで,たぶんもう大丈夫なんじゃないかな。未検証ですが。

本題

このへんを読んで,perlRPM を再生成(on FC5)してみました。昔どこかで読んだときは x86_64 向けの話だった気もするんですが,念のために i386 で。

すでに標準モジュールを沢山アップデートしてる環境やモジュールなにそれ?な人にはムツカシイと思いました。Capi なんとかとか使ってれば別かもしれませんが。

RPM のビルド

先人の記録

を利用して書いていきます。

あれこれ検索した挙げ句、specファイルってのはどんなrpmパッケージを作るかを記述するファイルっぽい。でもって肝心のモノはsrc.rpmに対してrpm2cpioとか使うと抽出できることがわかったのでそうする。

http://d.hatena.ne.jp/tomisima/20070102/1169366278

src.rpm が存在すれば,それを rpm -i でインストールすると,必要なソースが SOURCES フォルダに,spec ファイルが SPECS フォルダにインストールされます。だから rpm2cpio とか使わなくて大丈夫。

また,参照元では「/usr/src/redhat/」フォルダで作業をなさってますが,パッケージを作成するだけなら一般ユーザで行うのがベストでしょう。RPM 生成環境の設定については,【一般ユーザーでRPMパッケージをビルドするには − @IT】の後半に書いてあります。

% sudo yum -y install rpmdevtools
% fedora-buildrpmtree

このコマンドによってホームディレクトリに ~/rpmbuild というディレクトリが生成され,RPMS, SOURCES, SPECS ナドの必要なサブディレクトリが作成されます。また適宜 ~/.rpmmacros という設定ファイルも作ってくれるので,あとは普通に rpmbuild コマンドを利用すると自分のホームディレクトリで作業が行えます。

早速specファイルをいじろうと思ったのだけど、作業サーバのOSはfedora5で、そこに入ってるperl-5.8.8-5に対応するsrc.rpmが見当たらなかった。

http://d.hatena.ne.jp/tomisima/20070102/1169366278

perl-5.8.8-5 は FC5 だと updates レポジトリのほうにあるので,たとえば理研のミラーであれば次のようにして取得&展開できます。

% rpm -ivh http://ftp.riken.go.jp/Linux/fedora/core/updates/5/SRPMS/perl-5.8.8-5.src.rpm
   1:perl #####
warning: user brewbuilder does not exist - using root
warning: group brewbuilder does not exist - using root
... (など怒られるけど気にしない)

rpm コマンドには上記のようにリモートの URI を指定できます。これで,~/rpmbuild/SOURCES/ 以下に perl-5.8.8 のソースとパッチ,~/rpmbuild/SPECS/ に perl.spec という spec ファイルが生成されました。

% cd ~/rpmbuild
% vi SPECS/perl.spec
(27509, 27512 のパッチに該当する部分をコメントアウト)

あとは,rpmbuild コマンドでパッケージを作成します。

% rpmbuild -ba SPECS/perl.spec
...(すんごい時間がかかる)

% ls RPMS/i386/
perl-5.8.8-5.i386.rpm
perl-debuginfo-5.8.8-5.i386.rpm
perl-suidperl-5.8.8-5.i386.rpm

と,無事生成できました。

RPM のインストール

既に perl-5.8.8-5 というパッケージはインストールされているので,--force フラグをつけてアップグレードしてもいいんですが,個人的に色々困ったことが起きたりしたんで,ちょっと潔癖ぎみに下記のようにしました。

# rpm -e --nodeps perl
# rm -r /usr/lib/perl5/5.8.8
# rm -r /usr/lib/perl5/site-perl/5.8.8(お好みで)
# rpm -ivh RPMS/i386/perl-5.8.8-5.i386.rpm

はじめに依存パッケージを無視して perl 単体のパッケージを削除します。これまでに標準モジュールをアップデートしているとライブラリフォルダに更新したファイルが残るので,2行目でそれらを念のために削除します。

標準モジュールが perl-5.8.8 に付属のバージョンに戻ってしまいます。なのでインストール祭の開催決定なのですが,この後 CPANPLUS 等でインストールしようとすると,

CPAN Terminal> i threads

Installing threads
[MSG] Trying to get 'ftp://ftp.dti.ad.jp/pub/lang/CPAN/authors/id/J/JD/JDHEDDEN/CHECKSUMS'
Fetch failed! HTTP response: 500 Internal Server Error
 [500 Errno architecture (i386-linux-thread-multi-2.6.9-34.elsmp)
  does not match executable architecture
  (i386-linux-thread-multi-2.6.20-1.2300.fc5smp)
  at /usr/lib/perl5/site_perl/5.8.8/Errno.pm line 11.
Compilation failed in require
  at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/IO/Socket.pm line 17.

のように怒られてしまいます。これは旧 perl パッケージ時代に,Errno モジュールをアップデートしていた場合に発生します。

% perldoc -l Errno
/usr/lib/perl5/site_perl/5.8.8/Errno.pm
% sudo rm `perldoc -l Errno`

の2行目のように,Errno.pm が site_perl のほうにインストールされている場合はそちらは削除してください(/usr/lib/perl5/5.8.8/Errno.pm に存在した場合は削除してはいけません)。

さらに。もし CPANPLUS を使っている場合は,モジュールビルド時のソースツリーを再利用しようとするので,

CPAN Terminal> i CGI
...

[ERROR] MAKE TEST failed: Illegal seek Makefile out-of-date with respect to
  /usr/lib/perl5/5.8.8/i386-linux-thread-multi/Config.pm
  /usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/config.h
Cleaning current config before rebuilding Makefile...
make -f Makefile.old clean > /dev/null 2>&1
/usr/bin/perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for CGI
==> Your Makefile has been rebuilt. <==
==> Please rerun the make command.  <==
false

のように,一度ではうまくいかないことがあります(既存の perl パッケージの CORE/config.h と,作り直したパッケージの設定が変わってしまったためです)。

モジュールインストール祭を始める前に,ビルドツリーは削除しておきましょう。

% rm -r ~/.cpanplus/5.8.8/build