self-build パッケージについて
仕組みの概要
- 事前にターゲットの rpm パッケージを作成するのに必要な、spec と patch やその他のファイルを用意しておきます。
- 上記のファイル類を self-build-%{target} な rpm パッケージに含めておきます。
- %post で以下の処理を一括して行います。
- まず rpm ビルド用のテンポラリディレクトリと作成
- 次に patch やその他のファイルを /テンポラリ/rpm/SOURCES にコピー
- 続いて wget を使ってソースをダウンロード
- 後は、rpmbuild -bb でターゲットのパッケージを所定のディレクトリにビルド
- rpm2cpio | cpio を使ってビルドしたパッケージからファイルを事前に展開 (オプショナル)
- また apt/synaptic を使って self-build-%{target} をインストールした場合には、
所定のディレクトリ(/var/chache/self-build)に置かれたターゲットの rpm ファイル
のインストールまでを自動で実行します。
これは apt の Scripts::PM::Post:: というスロットを使うことで、rpm の DB に
変更がコミットされた(= self-build-%{target} 自体のインストールが完了した)直後
にヘルパースクリプトを呼び出すことで実現されています。
作り方
- ターゲット rpm 用のファイル一式の準備
最初にターゲットのプログラム(以下 lame を例に説明) の rpm パッケージが作成できる spec ファイルを用意します。
もし patch やその他のファイルが必要な場合は、これも一緒に準備しておきます。
- self-build 用の spec ファイルの作成
上記の spec ファイルを使って rpm のバイナリパッケージが作成できることを確認したら、次に self-buiild-lame 用の spec を作成します。
- ターゲットのプログラム用の spec や patch、その他のファイルを Source? で定義しておきます。
- PreReq: にターゲットのプログラムの BuildRequires: と同じものを書いておきます。
こうすることで、%post でコンパイルする時に必要となるパッケージが一緒にインストールされます。
- self-buiild 用の spec とターゲットのプログラム用の spec で、%{version}-%{release} が異なると事前のパッケージ配置に失敗するので、%prep でチェックしておきます。
%prep
[ "%{version}-%{release}" != $(rpm -q --queryformat "%%{version}-%%{release}\n" --specfile %{SOURCE0} | tail -1) ] && exit 1
- %install で Source? で定義した各種ファイルを全て ${RPM_BUILD_ROOT}/%{_datadir}/self-build-lame にインストールします。
またこれらのファイルを %files でも指定しておきます。
- %post で rpm パッケージをビルドするヘルパースクリプトを、以下のように実行します。
%post
/usr/lib/rpm/self-build-rpm.sh self-build-lame lame.spec http://...(ソースダウンロード URL) 12345(ログサイズ)
- 1つ目の引数は、self-build パッケージの名前を指定します。
この名前を使って spec や patch 類が置いてあるディレクトリ
(ここでは /usr/share/self-build-lame)を特定します。
- 2つ目の引数は、rpm のビルドに使用する spec ファイル名を指定します。
- 3つ目の引数は、ソースファイルをダウンロードするための URL を指定します。
ヘルパースクリプトはこの URL から wget を使ってソースをダウンロード
しようとします。
3つめ以降~n-1の引数は全てソースの URL と解釈するので、複数のファイルを
ダウンロードする必要がある場合は、続けて指定できます。
また同一の
ファイルを複数のミラーサイトからダウロードできる場合は、それらの URL も
複数指定できます。
この場合、いずれかの URL からファイルがダウンロードできたら2つ目以降の URL から
のダウンロードはスキップします。
- 最後(n番目)の引数は、ターゲット の rpm パッケージをビルドした際に出力される
ログファイル(通常であれば /var/tmp/self-build-lame.xxxxx/self-build-lame.log)
のサイズを指定します。
この値が指定されていると、ビルド中に実際に出力されるログファイルのサイズとの
比率でプログレスバーが表示されるようになります。
(* self-build-setup >= 0.9.5 が必要です)
- 他の self-build パッケージから依存される場合は、%post で更に以下のようヘルパースクリプトを実行して、作成した rpm パッケージが実際にインストールされるより前に、必要なファイルをファイルシステム上に展開します。(オプショナル)
%post
/usr/lib/rpm/pre-allocate-rpm.sh %{pkgname}-%{version}-%{release} \
%{pkgname}-devel-%{version}-%{release}
- 引数には、ターゲットの rpm パッケージ名を指定します。
対象のファイルが特定できるように Version と Release まで指定する必要があります。
- ヘルパースクリプトは指定された rpm から 設定ファイル(rpm -qc で表示されるもの)とドキュメント(rpm -qd で表示されるもの)を除いたファイルを rpm2cpio | cpio コマンドで抽出し、ファイルシステム上に展開します。
尚、この展開したファイルは後の rpm パッケージのインストールにより上書きされます。
- これにより依存関係をもつ複数の self-build パッケージが同一トランザクションでインストールできるようになります。
- 作成した self-build パッケージの作成とテスト
spec ができたら、$ rpm -ba self-build-lame.spec で rpm パッケージを作成し、
その後 root になって # rpm -Uvh self-build-lame-3.97-0vl3.i386.rpm のようにして
インストールし、ターゲットの rpm ファイルが /var/cache/self-build 以下にできあがる
ことを確認します。
実際にはパッケージ名やターゲットのプログラムの名前、ソースのダウンロード URL
等は %define でマクロとして最初に宣言しておいた方が管理しやすくなります。
self-build-lame.spec がサンプルとして使えると思いますので、初めて作成する方は
apt-get source self-build-lame を実行して ~/rpm/SPECS に展開された spec
ファイルを参考してみてください。
self-build 同士が依存する場合の注意点
ある self-build なパッケージが、他の self-build なパッケージが提供する rpm
に依存する場合、以下の点に注意する必要があります。
- 他の self-build パッケージから依存されそうな場合は、pre-allocate-rpm.sh を %post で実行
たとえば self-build-lame からは lame, lame-mp3x, lame-devel の3つの rpm が出来上がります。これらは(たとえば) mplayer を mp3 対応でビルドする為には、予めインストールされている必要があります。
このような場合、self-build-lame.spec の %post で pre-allocate-rpm.sh を実行しておくと、事前に必要なバイナリやヘッダファイル等がファイルシステム上に展開されるので、apt-get install self-build-mplayer を実行した結果、依存により self-build-mplayer と self-build-lame が一緒に一回でインストールされても、mplayer を mp3 対応でビルドできるようになります。
- self-build 同士の依存情報は、self-build-*.spec 内の PreReq にのみ記述
上記のケースで、mplayer のビルドに lame, lame-devel が必要となる場合、各 spec には以下のように記述します。
これは self-build の仕組み上、先にすべての rpm パッケージを作成して、その後にできた rpm パッケージをまとめてインストールするので、後からインストールされる rpm パッケージをその前の段階で要求すると、依存が満たせずにエラーとなるのを防ぐためです。
- self-build-mplayer.spec
PreReq: self-build-lame, *-devel
- mplayer.spec
BuildRequires: *-devel 等 (※ self-build-lame、lame-devel は書かない)
self-build パッケージに依存するパッケージのカテゴリ
self-build パッケージは、non-free カテゴリに属しております。
そのため、self-build パッケージに依存するパッケージのカテゴリは、
non-free カテゴリになります。
現時点で、例外のあるパッケージは以下の通りです。
self-build パッケージの %{arch}
self-build パッケージは、基本的には noarch で作成します。
ただし、BuildArch?: noarch を使うと、%ifarch が使えないので、
arch に依存するパッケージでは BuildArch? タグを使えません。
現時点で、arch に依存するのは、以下のパッケージです。
self-build 系パッケージ | arch に依存する理由
|
self-build-ffmpeg | %{ix86} x86_64: Requires(post): yasm
|
self-build-x264 | %{ix86} x86_64: Requires(post): yasm
|
self-build-vlc | %{ix86} x86_64: Requires(post): svgalib-devel libXvMC-devel
|
self-build-xvidcore | %{ix86}: Requires(post): nasm; x86_64: Requires(post): yasm
|
self-build-mplayer-codecs | %{ix86} ppc x86_64: arch により source0path が異なる
|
self-build-lame | %{ix86} x86_64: Requires(post): nasm
|
ファイルダウンロード時のプロトコル (http or ftp)
ソースアーカイブのダウンロード時に http と ftp が選べる場合は、
http を選ぶことを推奨します。
ftp は Active/Passive? いずれにおいても firewall や router の
設定によってはアクセスできない場合がある為、これを極力避ける
必要があります。
(<VineLinux:wishes:0191> と [VineSeed:18681] 以降のスレッド参照)
self-build パッケージ更新
リリースバージョンの場合、原則として、
so name の変更を伴う self-build パッケージの更新をしない下さい。
詳しくは、Package Maintenance Policy を参照。
例えば、faad2-2.6.1 を faad2-2.7 へ更新すると仮定します。
faad2-2.6.1 は libfaad.so.0.0.0 を提供しますが、
faad2-2.7 は libfaad.so-2.0.0 を提供しますので、
self-build-faad2-2.7 だけ put すると、
以下のように libfaad.so.0 の欠如により、
faad2-2.7 をインストールすることができません。
$ sudo apt-get install self-build-faad2-2.7-1vl6.noarch.rpm
パッケージリストを読みこんでいます... 完了
依存情報ツリーを作成しています... 完了
'self-build-faad2-2.7-1vl6.noarch.rpm' として self-build-faad2 を選択しました
アップグレード: 0 個, 新規インストール: 0 個, 再インストール: 1 個, 削除: 0 個, 保留: 0 個
0B/7698B のアーカイブを取得する必要があります。
展開後に 0B のディスク容量が追加消費されます。
続行しますか? [Y/n]Y
変更を適用しています...
準備中 ############################## [100%]
更新/インストール中
self-build-faad2-2.7-1vl6.noarch ############################## [100%]
rpm パッケージの作成を開始します。(self-build-faad2)
ソースファイルのダウンロード中...
(snip)
ソースファイルのダウンロードが完了しました。
rpm パッケージをビルド中...
(詳細は /var/tmp/self-build-faad2.log を参照してください。)
rpm パッケージのビルドが完了しました。
作成した rpm パッケージから必要なファイルを事前に配置しました。
完了
作成/ダウンロードした rpm パッケージをインストール中...
エラー: 依存性の欠如:
libfaad.so.0()(64bit) は (インストール済み)ffmpeg-libs-0.5-6vl5.x86_64 に必要とされています
libfaad.so.0()(64bit) は (インストール済み)gpac-libs-0.4.5-6vl5.x86_64 に必要とされています
libfaad.so.0()(64bit) は (インストール済み)libquicktime-1.1.2-1vl5.x86_64 に必要とされています
libfaad.so.0()(64bit) は (インストール済み)avidemux-cli-2.4.4-1vl5.x86_64 に必要とされています
libfaad.so.0()(64bit) は (インストール済み)avidemux-qt-2.4.4-1vl5.x86_64 に必要とされています
libfaad.so.0()(64bit) は (インストール済み)gstreamer-plugins-bad-0.10.12-1vl5.x86_64 に必要とされています
libfaad.so.0()(64bit) は (インストール済み)avidemux-gtk-2.4.4-1vl5.x86_64 に必要とされています
libfaad.so.0()(64bit) は (インストール済み)ffmpeg-mh-0.33-10vl5.x86_64 に必要とされています
libfaad.so.0()(64bit) は (インストール済み)xine-lib-faad-1.1.16.3-2vl5.x86_64 に必要とされています
libfaad.so.0()(64bit) は (インストール済み)vlc-1.0.1-1vl5.x86_64 に必要とされています
libfaad.so.0()(64bit) は (インストール済み)mplayer-1.0-23.20090821vl5.x86_64 に必要とされています
*エラー: rpm パッケージをインストールできません。
rpm ファイルは /var/cache/self-build に残っています。
この問題を解決する方法は、
- libfaad.0.0.0 を提供する compatibility パッケージを用意
- faad2 に依存するパッケージを rel + 1 する
で対処可能です。
しかしながら、非常にリポジトリの依存関係の壊れの元になりかねません。
原則として self-build 系のパッケージで lib 系のパッケージの更新においては、
so name の変更を伴う version up をしない方が懸命です。
TODO
- synaptic で self-build 系パッケージをインストールしたときに、
止まっているように感じるそうなので、ビルドログを表示する。
- 他の環境でビルドしたself-build 系パッケージの rpm を、
別の環境でインストールできる仕組みを作る。
- ビルドした self-build 系パッケージの src.rpm を保存する・しない、
ダウンロードした tarball などのソースを保持する・しないを設定できるようにする。