rpmでソースパッケージを利用する際のTips

#概要
CentOSやFedoraでソースパッケージを改変/リビルドして使いたい事は良く有ります。
ただsrc.rpmをインストールして作業すると色々面倒な事が多いのでもっと手軽にやるTipsをまとめてみました。

#必要な物
開発環境フルセット+ターゲットのソース+依存パッケージ+作業領域が展開できるくらいの空きディスク領域

必須では有りませんがビルド用にfedoraのVMとターゲットOSのリポジトリのローカルミラーを作るのをお勧めします。CentOS用パッケージもfedora上でビルドできます。

#利用するパッケージ
fedora上でビルドする場合
```bash:
yum -y mock rpmdevtools rpmbuild
```

CentOS上でビルドする場合 
mockの為にepelが必要なのでリポジトリを追加します。
実際のファイル名は\${ }を適宜置き換えて下さい。
```bash:
yum -y localinstall \
http://dl.fedoraproject.org/pub/epel/${os-rel}/x86_64/epel-release-${release}-${version}.noarch.rpm
yum -y mock rpmdevtools rpm-build
```

必須では無いが有った方が良いもの
```bash:
yum -y diff patch
```
他に好みのツールとエディタ

__【重要】__ __gcc等の開発用パッケージとdevel等の依存パッケージはここではインストールしません。__

#mockとrpmdevtools
__mock__はchrootした環境内でyumを使用して依存パッケージをダウンロード/インストールしソースパッケージをリビルドします。ビルドごとに設定された構成から依存パッケージをインストールする為、ネットワークやディスクの負荷が多くなりビルドの時間もその分遅くなりますが、余計なパッケージが無いのでこの状態できちんとビルドできるspecなら大抵の場合問題無く動きます。
リポジトリのローカルミラーはこの負荷を軽減できますし、将来的に自前のパッケージが増えて固有の依存関係が出てきても独自リポジトリを構築してmockのターゲットOS設定ファイルに指定しておけば自動で取り込んでくれるので、セットで準備しておく事をお勧めします。

__rpmdevtools__はrpmパッケージをインストールせずに色々弄れるツール群です。
今回は初期設定で使うrpmdev-setuptreeとsrpmを展開するrpmdev-extractの為にインストールします。

#準備
rpmbuildで使うディレクトリとマクロファイルを作ります。
```bash:
cd ${HOME}
rpmdev-setuptree
```
rpmdev-extractはrpmの内容をインストールせずに展開してくれますが、そのままではrpmbuild時にソースを見つけられないのでマクロを修正します。
```bash:
echo "%_sourcedir %{_topdir}/SOURCES/%{name}-%{version}-%{release}.src" >> ${HOME}/.rpmmacros
```

以下の作業はroot権限が必要です。
ビルド時のユーザーをmockグループに追加します。
ターゲットOSの環境を構築します。
 /etc/mock以下にターゲットOSの設定ファイルがあるので目的の設定を指定します。
${ }は適宜置き換えて下さい
```bash:
sudo mock --init  -r ${OS}-${release}-${arch}
```
ターゲットは複数構築できるので使用するレポジトリごとにターゲットOS設定ファイルを作成する事も可能です。詳細は[fedoraのwiki](http://fedoraproject.org/wiki/Projects/Mock "Mock - Fedora Project")を参照して下さい。
出来上がったパッケージを回収したり、失敗した場合にchrootせずに作業できるように以下のディレクトリをmockグループで読み書きできるようにしておきます。
```bash:
cd /var/lib/mock/
sudo chown -R :mock ./${OS}-${release}-${arch}
sudo chmod -R 774 ./${OS}-${release}-${arch}
```
デフォルトで使用したいターゲットを指定しておきます。
```bash:
cd /etc/mock
sudo ln -s ${OS}-${release}-${arch}.cfg default.cfg
```
-rオプションでターゲットOSをビルドごとに指定する事もできます。
但し事前に構築は必要です。

#作業手順
hoge-ver-rel.src.rpmを例に取ると以下のようになります。

__単純にリビルドする場合__
```bash:
mock (-r ${OS}-${release}-${arch} ) --rebuild hoge-ver-rel.src.rpm
```

__specファイルを編集する場合__
1.1 srpmを作り直すのでオリジナルのsrpmは~/rpmbuild/SRPMSではない所に置き、srpmを展開します。
```bash:
cd ~/rpmbbuild/SOURCES
rpmdev-extract {~/rpmbuild/SRPMSではない何処か}/hoge-ver-rel.src.rpm
cp ./hoge-ver-rel.src/hoge.spec ~/rpmbuild/SPEC
cd ~/rpmbuild/SPEC
```
1.2 hoge.specを編集します。
1.2.1パッチや追加のソースは~/rpmbbuild/SOURCES/hoge-ver-rel.src/以下に配置します。
1.3 ソースパッケージを作成し出来上がった新しいhoge-ver-rel.src.rpmをビルドします。
```bash:
rpmbuild -bs hoge.spec
cd ~/rpmbuild/SRPMS
mock (-r ${OS}-${release}-${arch} ) --rebuild hoge-ver-rel.src.rpm
```
/var/lib/mock/\${OS}-\${release}-\${arch}/result/以下にパッケージが作成されます。
```bash:
ls /var/lib/mock/${OS}-${release}-${arch}/result
```

#ビルドに失敗した場合
下記ディレクトリに各種log及び作業ディレクトリが作成されるので確認できます。
/var/lib/mock/\${OS}-\${release}-\${arch}/result/
/var/lib/mock/\${OS}-\${release}-\${arch}/root/builddir/build/

修正は~/rpmbuild/SOURCES/hoge-ver-rel.src/以下に対して行い、手順の1.2からやり直しになります。

また--shellオプションでchrootした環境にrootでログインできます。
```bash:
sudo mock (-r ${OS}-${release}-${arch} ) --shell --no-clean
```
ログインしたら普通にyumでパッケージ追加なりrpmbuildなりで試行錯誤できます。

__【重要】__
__mockコマンドを起動すると/var/lib/mock/\${OS}-\${release}-\${arch}/root/builddir/build/は消えてしまう__
--no-cleanを適宜使用しないとmock --rebuildからやり直すはめになります。
__修正はchrootの外で~/rpmbuild/SOURCES/hoge.ver-rel.src/以下に対して行いsrpmを作り直してからrebuildする事__
通常mockはsrpmを展開してインストール/ビルドするのでsrpmを修正しないと変更が適応されません。特に依存関係が絡んだ修正は--no-cleanでは無い方が安全です。

mock --cleanで/var/lib/mock/\${OS}-\${release}-\${arch}/root/builddir/build/
以下を初期化できます。

mockはsandbox的な使い方も可能なのでdockerやkvmと組み合わせると試行錯誤が大分楽になります。