いまさら聞けないrpmbuildことはじめ

CentOSなどrpmを使っているシステムで、欲しいツールのrpmが見つからない、使いたいツールのバージョンが古いときに、rpmbuildを使って望みのrpmを作成することが出来ます。
ウェブを探せば色々と情報はあるんですが、ざっとスタートするときに必要な流れをまとめて書いてみることにしました。

専用のビルド環境

専用の環境を準備た方が吉です。centXbuildXXみたいな名前でVMを作ってます。

  • cent4build32.tnmt.local
  • cent5build64.tnmt.local

とか。
パッケージの依存性もあるので、あまりサードパーティのyumリポジトリなどを追加しないか、実環境と同じリポジトリのみ有効にするとよいです。複数サービスがあったらそれごとにVMを作るのもありかと思います。

必要なパッケージ類のインストール

rpmbulidに必要なパッケージ類をインストールします。パッケージ名はハイフンつきに注意。

sudo yum install rpm-build

あとビルド専用の環境なんで、その他もろもろのライブラリやツールも一緒に入れておくと、ビルド時に足りないというシーンも少なくなるのでgroup installしておくと吉です。

sudo yum groupinstall "Development Tools"

専用のビルドユーザ

OfficialのHOW TOにもこう載ってます。

Building RPMs should NEVER be done with the root user. It should ALWAYS be done with an unprivileged user. Building RPMs as root might damage your system. You have been warned.

「rpmビルドはrootでやっちゃだめだぞ、システムにダメージ与える可能性あるからやるなよ、絶対やるなよ!」と書いてありますので、フリじゃなくてきちんとそれにしたがいましょう。

ユーザ作成

自分のアカウントでもいいですが、俺はrpmbuilderなユーザを作ってます。

sudo useradd rpmbuilder

ユーザの環境設定

作成したrpmbuilderにsu -して環境を設定します。必要なのはビルドに使用するディレクトリと、rpmbuildをコントロールする.rpmmacrosです。

ディレクトリ

mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}

内訳は

  • BUILD: ビルド時に使われる一時ディレクトリ
  • RPMS: ビルドされたrpmが格納されるディレクトリ、各アーキテクチャごとのサブフォルダに分かれる
  • SOURCES: ビルドのもとになるソースやパッチを配置するディレクトリ
  • SPECS: specファイルを配置するディレクトリ
  • SRPMS: ビルドした際にsrc.rpmが出来るようにしていればそれが格納されるディレクトリ

.rpmmacros

rpmbuild時に参照される設定一覧です。さきほど作成したrpmbuild以下を使用するために、以下で新規作成を行います。

echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros

俺はあとdebugパッケージを作らないような設定とsmpの設定を入れてます。smpのj3はmakeの引数になる感じなので適宜自分の環境に合わせてですね。

%_topdir      %(echo $HOME)/rpmbuild
%debug_package %{nil}
%_smp_mflags  -j3

以上2つの作業はepelリポジトリにあるrpmdevtoolsの中のrpmdev-setuptreeで簡単に設定可能です。
参考: rpmdevtools | Carpe Diem

あとはビルド

よくやる2通りを書いておきます。

src.rpmをそのままビルド

バイナリが提供されていないパッケージが欲しかったり、少しバージョンが古かったりな時に使えます。
お目当てのsrc.rpmをダウンロードします。

cd ~/rpmbuild/SRPMS/
wget http://foo.var.com/foovar-1.0.src.rpm

rpmbuildします。src.rpm直接指定の時は --build オプションです。

rpmbuild --rebulid foovar-1.0.src.rpm

ひと手間加えてビルド

既存のパッケージにパッチをあてたり、configureオプションをいじったりするときに使う方法。yum-utilsパッケージ内のyumdownloaderが便利なので合わせて紹介します。入ってない場合は

sudo yum install yum-utils

ソースパッケージ取得

cd ~/rpmbuild/SRPMS/
yumdownloader --source foovar

src.rpmインストール

rpm -ivh foovar-1.0.src.rpm

これで ~/rpmbuild/SOURCES/ 以下にソース、パッチ類と、 ~/rpmbuild/SPECS/ 以下にrpm作成のもととなる パッケージ名.spec (今回はfoovar.spec) が配置されます。
このfoovar.specに色々と変更を加えます。

パッチあてる場合

  • ~/rpmbuild/SOURCES/ 以下にあてたいパッチを作成する。例: buzz.patch
  • ~/rpmbuild/SPECS/foovar.specのpatchセクションに buzz.patch を当てる設定を書く
    1. PatchXXでかぶらないナンバリングで PatchXX: buzz.patch 追記
    2. 同じナンバリングで%patchXX -p1 -b .foovar (foovarはバックアップ識別名で任意)

configureオプション変える場合

  • ~/rpmbuild/SOURCES/foovar.spec のconfigureオプションを変更

こんな風にして修正したspecファイルをビルドします。修正を加えたspecファイルを含むsrc.rpmも同時に作成する -ba オプションで指定します。

rpmbuild -ba ~/rpmbuild/SPECS/foovar.spec

この後は

ビルドしたファイルは ~/rpmbuild/RPMS/i386/ や ~/rpmbuild/RPMS/x86_64/ などビルドしたマシンのアーキテクチャごとに配置されます。これらを独自yumリポジトリを作成して登録しておくと、各サーバーへのインストールも楽ちんです。

独自yumリポジトリ作成については、以下のエントリが参考になります。
RE: 独自/ミラー yum リポジトリを作ろう | Carpe Diem
Cobbler便利です。

まとめ

rpmbuildの始め方についてのざっとの流れでした。オレオレパッケージはあまり作らないに越したことはないですが、ソースインストールよりも管理のミスも減りますし、バージョン管理や展開が早く行えるメリットもあるので、今後も色々とやり方の効率化は探っていきたいと思います。

rpm, yumコマンドでパッケージの更新履歴を見る

rpmパッケージに更新がかかったときに、何の変更があったか知りたいときがあります。

ちょっと調べたら出てきたのでメモ。

rpmの場合は下記のコマンドでChangelogを見ることが出来ます。

rpm -q --changelog パッケージ名
rpm -qp --changelog パッケージファイル名

yumだと、yum-changelogというプラグインがあって、それをインストールすると下記で見れるようになります。ただしCentOSだと5以降、Fedoraも5以降。Fedora 11, 12はyum-plugin-changelogになります。

sudo  yum --changelog update パッケージ名

yumの場合は、現在インストールされているバージョンから、アップデート対象のバージョンの差だけ見れるので、確認してからアップデートということが出来るようになります。

rpm作成時の小ネタ (yum-builddep)

欲しいrpmが無かったりバージョンが古かったりするときにrpmを自前で作成する場合、こういうことがあるかと思います。

rpmbuild --rebuild foovar-0.0.1.src.rpm
error: Failed build dependencies:
        bzip2-devel is needed by foovar-0.0.1.i386
        sqlite2-devel >= 2.8.0 is needed by foovar-0.0.1.i386
        libedit-devel is needed by foovar-0.0.1.i386
        libtool-ltdl-devel is needed by foovar-0.0.1.i386
        libc-client-devel is needed by foovar-0.0.1.i386
        mysql-devel >= 4.1.0 is needed by foovar-0.0.1.i386
        unixODBC-devel is needed by foovar-0.0.1.i386
        net-snmp-devel is needed by foovar-0.0.1.i386
        libxslt-devel >= 1.0.18-1 is needed by foovar-0.0.1.i386
        libjpeg-devel is needed by foovar-0.0.1.i386
        xorg-x11-devel is needed by foovar-0.0.1.i386
        libmcrypt-devel is needed by foovar-0.0.1.i386
        libtidy-devel is needed by foovar-0.0.1.i386
        freetds-devel is needed by foovar-0.0.1.i386
        aspell-devel >= 0.50.0 is needed by foovar-0.0.1.i386
        recode-devel is needed by foovar-0.0.1.i386
        libicu-devel >= 3.6 is needed by foovar-0.0.1.i386</code></pre>

specファイルに記述された BuildRequires 依存パッケージの嵐!こういう時素直に

sudo yum install bzip2-devel sqlite2-devel libedit-devel libtool-ltdl-devel

でもいいんだけど、すごくめんどくさい。

そんなときに便利な yum-builddep 。 yum-utils というツール郡の中の一つです。

入っていなければインストール。

sudo yum install yum-utils

たとえば foovar-0.0.1.src.rpm というSRPMがあって、それが BuildRequires している依存パッケージをインストールするのが、下の1コマンドで完了します。

sudo yum-builddep foovar-0.0.1.src.rpm

他にも yum-utils はその名のごとく色々な便利ツールを含んでいるのですが、それはまた別で調べようかと思います。