独自のRPMパッケージやyumリポジトリを作ってみよう 2ページ

specファイルの作成/編集

 続いて、RPMパッケージ作成のキモとなるspecファイルについて説明していこう。具体的にspecファイルへ記述する内容は以下のようなものだ。

  • パッケージの説明やバージョンなどの情報
  • RPMパッケージのビルドに必要なソースファイル
  • パッケージが依存するパッケージ
  • ビルド手順
  • パッケージに含めるファイル一覧
  • パッケージのチェンジログ

 rpmbuildコマンドはこのspecファイルに記述された情報を元に、ソースコードのコンパイルや、コンパイル時の設定、パッケージに含めるファイルの決定といった処理を実行する。specファイルではさまざまなマクロやコマンドを利用して、これらの情報を記述していくことになる。

 なお、specファイルに記述できるマクロやコマンドは非常に多く、今回そのすべてを解説することはできないので、以下ではその一部を述べるだけにとどめておく。より詳しい詳細についてはFedoraプロジェクト内にあるドキュメント(Packagers Guide)を参照すると良いだろう。

パッケージ情報の記述

 パッケージの説明やバージョンといった情報は、ファイル先頭に記述する。たとえばUNIX系OSではおなじみtarコマンドのspecファイル(tar.spec)の場合、以下のようにパッケージの要約(サマリ)や名称、バージョンといった情報が定義されている。

Summary: A GNU file archiving program
Name: tar
Epoch: 2
Version: 1.23
Release: 11%{?dist}
License: GPLv3+
Group: Applications/Archiving
URL: http://www.gnu.org/software/tar/

バージョン番号とリリース番号、エポック番号

 specファイル内では、パッケージのバージョンを示すものとして「Version」と「Release」、「Epoch」がある。「Version」はパッケージの元となるソースファイルに付けられたバージョン番号(アップストリームのバージョン番号)を示すものだ。また、「Release」はパッケージのバージョンを示すものとなる。元にしたソースファイルのバージョンはそのままで、パッケージのみを更新した場合はReleaseの番号を更新する形になる。

 「Epoch」はパッケージの新旧を比較するために使われる数値で、指定されていない場合は「0」と見なされる。rpmコマンドやyumコマンドでパッケージをアップデートする場合、通常はVersionやReleaseの値の大小を比較してバージョンの新旧をチェックするのだが、Epochの値が指定されていた場合は、この値の大小でバージョンの新旧がチェックされる。つまり、VersionやReleaseの値が古い(数値が小さい)場合でも、Epochの値が大きければそちらのパッケージがより新しいものと認識される。

 Epochは通常パッケージ名には表示されないため、利用するとバージョンの新旧が判別しにくくなる。そのため、明示的に古いバージョンのものをインストールさせたい場合などを除き、利用は基本的には推奨されていない。

必要なソースファイルや依存パッケージの記述

 RPMパッケージのビルドに必要なソースファイルは次のように「Source」や「Patch」といった行で指定する。

Source0: ftp://ftp.gnu.org/pub/gnu/tar/tar-%{version}.tar.bz2
Source1: ftp://ftp.gnu.org/pub/gnu/tar/tar-%{version}.tar.bz2.sig
#Manpage for tar and gtar, a bit modified help2man generated manpage
Source2: tar.1
#Stop issuing lone zero block warnings
Patch1: tar-1.14-loneZeroWarning.patch
#Fix extracting sparse files to a filesystem like vfat,
#when ftruncate may fail to grow the size of a file.(#179507)
Patch2: tar-1.15.1-vfatTruncate.patch
  :
  :

 依存パッケージは「Requires:」や「BuildRequires:」といった行で指定する。「Require:」にはパッケージのインストール時に必要となるパッケージを、「BuildRequires」にはパッケージのビルド時に必要となるパッケージを列挙する。

Requires: info
BuildRequires: autoconf automake gzip texinfo gettext libacl-devel gawk rsh

ビルド手順の記述

 RPMパッケージの作成は、「prep」および「build」、「install」、「check」、「clean」という段階を踏んで行われる(表2)。

表2 RPMパッケージの作成における段階
段階名説明
prepソースアーカイブの展開やパッチの適用を行う
buildconfigureやmakeを実行してソースコードをコンパイルする
installmake installコマンドなどを実行してビルドしたバイナリを作業用ディレクトリにインストールする
check必要なファイルが用意されているかどうかをチェックする
cleanビルド時に生成された中間ファイルなどを削除する

 これらの段階で実行する処理は、それぞれ「%prep」や「%build」、「%install」、「%check」、「%clean」といったセクションで定義する。たとえば先のtarパッケージの場合、「%prep」セクションは以下のようになっている。ここでは、「%setup」マクロを使用してSource:行で指定したソースコードを展開し、「%patch」コマンドでPatch:行で指定したパッチをソースコードに展開後、autoreconfコマンドを実行している。

%prep
%setup -q
%patch1 -p1 -b .loneZeroWarning%
%patch2 -p1 -b .vfatTruncate
 :
 :
%patch23 -p1 -b .coredump-hash
autoreconf

 また、「%build」セクションは次のようになっている。ここでは「%configure」マクロでconfigureを実行し、続けてmakeコマンドを実行している。

%build
%configure --bindir=/bin --libexecdir=/sbin \
%if %{WITH_SELINUX}
  --enable-selinux
%endif
make

 これ以外のセクションも%prepや%buildセクションと同様、マクロやコマンドを記述して実際に行う処理を記述していくことになる。

それ以外のセクション

 specファイル中では先に示した%prepや%buildといったセクションに加えて、「%pre」や「%post」、「%preun」、「%postun」などのセクションを定義できる。これらにはパッケージのインストール前やインストール後、アンインストール前およびアンインストール後に実行する処理を記述する。詳しくはドキュメントなどを参照してほしい。

パッケージに含めるファイルの指定

 「%files」セクションでは、パッケージに含めるファイルのリストをそのフルパスで記述する。ここでは%{_bindir}や%{_mandir}といったマクロ変数やワイルドカードも利用可能だ。たとえばtarパッケージの場合、以下のようになっている。

%files -f %{name}.lang
%defattr(-,root,root)
%doc AUTHORS ChangeLog ChangeLog.1 NEWS README THANKS TODO
%ifos linux
/bin/tar
/bin/gtar
%{_mandir}/man1/tar.1*
%{_mandir}/man1/gtar.1*
%else
%{_bindir}/*
%{_libexecdir}/*
%{_mandir}/man*/*
%endif

%{_infodir}/tar.info*

チェンジログの記述

 specファイルの最後には、パッケージのチェンジログを記載する「%changelog」セクションを記述する。ここでは以下のように、一般的なchangelog形式で日時や著者名、変更点などを記載していく。

%changelog
* Mon Nov 19 2012 Pavel Raiskup <praiskup@redhat.com> - 2:1.23-11
- avoid crash by backporting upstream patch for internal construction of
  file-name hash table (#877769).