空の RPM パッケージで依存関係の問題を解決する (2)
昨日は「新設された -devel
パッケージへの依存に困ったときは -devel
を捏造すればいい」と力説したわけで、今日は、このために必要な空の RPM パッケージの作り方をメモしておこう。
作り方といっても大したことではなく、こんな感じの SPEC ファイルを書けばいい:
Name: perl-devel Summary: This is a dummy package just for resolving dependency problems. Version: 5.8.8 Release: dummy.0 Group: Development/Languages License: public domain Packager: masugata_k <masugata_k@example.com> Source0: %{name}-%{version}.tar.gz Source1: README BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %description No files but README are installed by this package because all necessary files are installed by "perl" package. %prep %setup %build %install %clean [ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT} %files %defattr(-,root,root) %doc $RPM_SOURCE_DIR/README
昨日は「popt-devel
がなくて困るんだよ」的な話をしたが、今日は偶々 perl-devel
がなくて困った((subversion
を rpmbuild --rebuild
していた。))ので perl-devel
を題材に取ることにした。
続いて、SPEC ファイル中で Source0
, Source1
としている perl-devel-5.8.8.tar.gz*1 と README を用意する。perl-devel-5.8.8.tar.gz は、perl-devel-5.8.8 という空のディレクトリが入っているだけの TAR ボールだ。README の方には何でも好きなことを書けばよい。インストールされた暁には /usr/share/doc/perl-devel-5.8.8/README になるので、このニセモノパッケージを作るに至った経緯などを書いておくといいと思う。ちなみに、TAR ボールと README を分けたのは、README を簡単に編集できるようにするためだ。
たったこれだけ。あとは、rpmbuild -ba --clean SPEC/perl-devel.spec
するだけで、perl-devel-5.8.8-dummy.0.i386.rpm がめでたく出来上がる。
CentOS 本来のパッケージに Provides
を追加するのとどちらが簡単か?
昨日は Provides
を書いて再ビルドする方がいい気がしていたが、やはり、空の -devel
の方がいいと思う。perl
の再ビルドなんてやりたくない。BuildRequires
なのを入れまくるのも避けたいところだ。
空の RPM パッケージで依存関係の問題を解決する (1)
CentOS を使っていてちょっと困るのは、パッケージの少なさと古さだ。安定性が売りなのだから仕方がないが、欲しいパッケージやバージョンが Fedora にあると、「安定性」とやらを多少犠牲にしても手を出さずにはいられない*1。
もちろん、取ってくるのは SRPM で、rpmbuild --rebuild
してインストールする。別のディストロのバイナリ RPM をブチ込むなんていう恐ろしいことはゴメンだ*2。大概、rpmbuild --rebuild
は問題なく完了する。別に何をしたわけでもないのにターミナルに流れる大量のメッセージが“ビルドしたぜ!!”という意味不明な満足感と達成感を与えてくれる一種の魔境で、疲れたときの気分転換などによい。
だがしかし、ここに1つの罠がある。BuildRequires
されているパッケージが CentOS には存在しないことがあるのだ。
パッケージがない、というのにも2つのパターンがある。1つは、当該のパッケージが“本当に”ない場合だ。これは大した問題ではない。そのパッケージの SRPM を Fedora から取ってきて rpmbuild --rebuild
すればいいだけの話だ。そこでもまた BuildRequires
が見つからないかもしれないが、再帰すればいい。
困るのは、「ちょっとパッケージ構成見直しちゃったよ」系の“見つからない”だ。ありがちなのは、ライブラリの -devel
を別パッケージに分けたよ、というやつ。たとえば、CentOS 5 では popt
という1つのパッケージなのが Fedora 9 では popt
と popt-devel
に分けられている。この場合、「Fedora 9 の SRPM は popt-devel
を BuildRequires
するが、そんなパッケージは CentOS 5 には存在しない」という事態に陥る。
このパターンだと、Fedora 9 から popt-devel
を持ってくるわけにはいかない。この popt-devel
は、CentOS 5 の popt
とは競合する。popt
の方も Fedora 9 のものに置き換えるという手もあるが、別に popt
の最新版が使いたいわけではないのだから、“安定性”が期待できる CentOS のパッケージを使い続けたい。
「ビルドしようとしている SRPM の SPEC ファイルを書き直す」というのは、正攻法ではあるが面倒くさい。特に、popt-devel
のように多くのパッケージから BuildRequires
されているパッケージの場合、大量の依存元に個別対処していくのは精神衛生上よろしくない。
では、どうすればいいのか。答えは簡単で、popt-devel
という名前の空の RPM を作ってインストールすればいい。必要なファイルは全部インストール済みで、足りないのは popt-devel
という名前だけなのだから。「うちの popt
は popt-devel
を Provides
してるんですよ、実は。」という表明だと捉えることもできる((「じゃあ、CentOS 5 の popt
の SRPM を取ってきて、SPEC に Provides popt-devel
って書いて rpmbuild -bb
すればいいじゃん」と思われるかもしれない。確かにそうですね。今これを書いていて気付きました……。))。
というわけで、漸く本題で「空の RPM パッケージの作り方」なわけですが、今日はもう疲れたので明日にします。ごめんなさい。
『Google C++ Style Guide』だってさ
はてなブックマークの「最近の人気エントリー」に『Google C++スタイルガイド日本語訳』というのがあったので、『Google C++ Style Guide』の存在を知ることができた。
日頃は「Google の開発者っていいよなー」と羨ましがることしきりだが、今日は初めて「Google 勤めじゃなくて本当によかったよ」と思えました。
grep をカラーで
文章の良さには様々な尺度があると思うが、とりあえず、短いのはいいことだ。
~/.bash_profile にこう書いておくと結構いいですよ:
export GREP_OPTIONS=--color=auto
冠詞は形容詞みたいなもの
『【コラム】エンジニアのための英語術 (53) 重要なのは受け手を混乱させないこと - 定冠詞"the"再考 | エンタープライズ | マイコミジャーナル』より:
すごく納得した。文法的にどうのこうのっていうのもあるんだけど、意味としてどうなのかが大事なんだろう。日頃、「こういうときは付けるのか?」じゃなくて「付けるとどういう感じになるんだ?」という感覚で考えるようにしている。
ネイティブスピーカ向けの文法の解説書には「articlesはnouns(名詞)を形容するadjective(形容詞)のうちのひとつ」という位置付けになっているものもあります。私が日本で勉強してきた英語は、冠詞は冠詞であって形容詞ではなかったので、当初、この分類には違和感を持ちましたが、たしかにarticlesの用法を考慮すると、形容詞のひとつ、というのはうなずけます。
冠詞の有無は、シンタックスじゃなくてセマンティクスの領域なんだろう。“正しくない使い方”は、「そこに付けるとこういう意味にあるけど、そんな状況ってあんまりないよね。」という意味で正しくなくわけだ。
で、これを「コンパイル時エラーじゃなくて実行時エラー*1なのか」と捉えるのは職業病か?
*1:“エラー”というほどじゃなくて“奇妙な振る舞い”ぐらいだけど、まあいい。
MacPorts と Universal Binary
Universal Binary をビルドしたい場合、ライブラリも Universal Binary でないといけない、……らしい*1。なので、MacPorts でインストールするライブラリも Universal Binary のやつにしたい。
まず分かったのは、「univeral
」バリアントを入れればいいということ。で、sudo port install
のたびに +universal
を付けるのは面倒なので /opt/local/etc/macports/variants.conf にこう書いておく、というのも分かった:
+universal
ところが、これだけだと、"-arch ppc -arch i386
" な*2 Universal Binary になってしまう。どうせなら*3、"-arch ppc -arch i386 -arch ppc64 -arch x86_64
" な Universal Binary にしたい。
『MacPorts Guide』には、macports.conf の「universal_archs
」で「ppc i386 ppc64 x86_64
」を指定しなさい、みたく書いてあるが、やってみたところ効果なし。どうやら割と最近入った機能らしく、1.6.0 にはまだ入っていないっぽい。
途方に暮れて*4「grep -FR -- '-arch' /opt/local
」としたところ、/opt/local/share/macports/Tcl/port1.0/portconfigure.tcl なるものを発見。で、恐る恐る修正:
--- portconfigure.tcl.bak +++ portconfigure.tcl @@ -87,10 +87,10 @@ } options configure.universal_args configure.universal_cflags configure.universal_cppflags configure.universal_cxxflags configure.universal_ldflags configure.universal_env default configure.universal_args --disable-dependency-tracking -default configure.universal_cflags {"-isysroot $sysroot -arch i386 -arch ppc"} +default configure.universal_cflags {"-isysroot $sysroot -arch i386 -arch ppc -arch x86_64 -arch ppc64"} default configure.universal_cppflags {} -default configure.universal_cxxflags {"-isysroot $sysroot -arch i386 -arch ppc"} -default configure.universal_ldflags {"-arch i386 -arch ppc"} +default configure.universal_cxxflags {"-isysroot $sysroot -arch i386 -arch ppc -arch x86_64 -arch ppc64"} +default configure.universal_ldflags {"-arch i386 -arch ppc -arch x86_64 -arch ppc64"} # Select a distinct compiler (C, C preprocessor, C++) options configure.ccache configure.distcc configure.cc configure.cxx configure.cpp configure.objc configure.f77 configure.f90 configure.fc configure.javac configure.compiler
こんなんでいいのかなぁ、と自分でも疑問に思いつつ、どうやら問題ない様子。
ファイアウォール内で MacPorts を使う
MacPorts は非常に便利で嬉しい存在なんだが、ポーツをリポジトリに同期させるのに rsync を使うため、ファイアウォールに閉じこめられている……、いやいや匿って頂いている身としてはちょっと使いづらい。いろいろと工夫したら何とか使えるようになったので、備忘のためにメモしておく。
インストール
インストールは、.dmg で .pkg な普通のインストールで大丈夫だ。インストーラが port selfupdate
しようとしてくれてエラーになって終わるが、環境変数の設定を自分でやらないといけないこと以外には、別に問題はないようだ。
ポーツリポジトリは Subversion で持ってくる
rsync が使えないので、port selfupdate
や port sync
ができない。そこで、/opt/local/etc/macports/sources.conf をこんな風に設定する:
#rsync://rsync.macports.org/release/ports/ file:///opt/dports/
これで、rsync など止めて /opt/dports を見に行くようになる。
問題は /opt/dports をどうやって取ってくるかだが、これは http://svn.macosforge.org/repository/macports/trunk/dports/ から Subversion でチェックアウトできる。
trunk なんかから持って来ちゃって大丈夫かよ、とも思ったが、こんなことが書いてあるので別によさそう:
Though a distinction is made between pre-release and release versions of MacPorts base, the ports collection supports no such distinction or versioning. The selfupdate command installs the latest port revisions from subversion (at a slight delay), and updates MacPorts base to the latest released version.