データ定義部の次の部分は、以下のような%が頭に付くタグからはじまる、 一連のscriptで構成されます。重要なのは、各タグから始まる次のタグの前までの部分は、 独立したbashスクリプトとして実行されるということです。 (注:以下で、%setup, %patchはスクリプトのはじまりを表すタグではなく、 スクリプト中で記述を簡略するためのマクロです。)
より正確には、各タグが現れた時に #!/bin/sh -e が起動され(Vine Linuxでは/bin/shは/bin/bashにsym.linkされてる)、 各環境変数(RPM_SOURCE_DIRやRPM_PACKAGE_NAMEなど)が定義された後、 次のタグが出てくるまで、記述されているスクリプトが実行されます。
ソースのmakeやインストール作業前の準備の開始を示すタグです。 以下で説明する%setup,%patchなどのマクロを用いたり、 シェルスクリプトを記述して、ソースの展開などを行います。 ここで、
%prep
rm -rf ${RPM_BUILD_ROOT}
として、${RPM_BUILD_ROOT}(先のBuildrootで指定したディレクトリ) を掃除することが多いです。ただし、このときには、 Buildrootの設定には十分気をつけて下さい(何故かわかりますね?)
%prepからはじまるスクリプト中で、ソースを展開するためのマクロです。 %setupとオプションなしで書くと、以下が順に行われます。
Section 4.1, “環境設定”で指定したディレクトリBUILDにcdする。
指定ディレクトリ(-nで指定できる。デフォルトのディレクトリ名は、 ${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}、後述) がカレント・ディレクトリ(BUILD)に存在すれば消去する。
Sourceで指定したtar.gzのソースを展開する。
指定ディレクトリ(2の指定ディレクトリ名と同じ)にcdする。
以下を実行する。
chown -R root . chgrp -R root . chmod -R a+rX,g-w,o-w .
(注:一般userがrpmをbuildするときには、chown root, chgrp rootは実行権限がないので行われない。 一般userでbuildするときには、 %filesの%attrでファイルの属性設定を行う。後述)
hoge-1.1.tar.gzを展開したときに、hoge-1.1/というディレクトリができるなら、 オプションをつけなくても以上の作業が行われますが、例えば、 hoge/というディレクトリができるなら、このディレクトリの下にcdできるように、
%setup -n hoge
または、
%setup -n ${RPM_PACKAGE_NAME}
と指定します。
複数のソースがあるときには以下に述べるオプション-aや-bを使います。 例えばSource、Source1、Source2の3つがあるときには、
%setup -a 1 -a 2 -n hoge
などとします。(以下のオプションの指定参照。)
この%setupにはさまざまなオプションがありますが、 代表的なものを以下に示します。
%setupを実行した後(もしくは前)にcdするディレクトリ名(name)を指定する。 このオプションを省略したときの、デフォルトのディレクトリ名は、 ${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}。
指定ディレクトリ(上の-nオプションで指定したディレクトリ) を作成し(create)、そこにcdした後にソースの展開をします。
Source0を展開した後、 指定ディレクトリ(上と同じ)にcdした(after)、 #番目のソース(Source#)の展開をします。 %setup -a 2 -a 3 と複数-aオプションが指定された時には、 Source0 が展開された後、指定ディレクトリに cd し、 Source2、Source3を展開します。 (Source0の展開は最初の一回だけです。)
Source0を展開した後、 指定ディレクトリ(上と同じ)にcdする前に(before)、 #番目に指定されてるソース(Source#)の展開をします。
先に述べたように、%setupは、まず、指定ディレクトリ(上と同じ)が、 ディレクトリBUILDの下にあるかどうかをチェックして、もし存在していたら、 それを削除してから、ソースの展開などの作業を行います。 %setupを複数回呼びたい場合、 2回目に%setupを呼んだ時に最初の%setupで展開したディレクトリを削除されては困ります。 この-Dオプションは、このような削除を行わないようにします。(あまり使いません)
ソースの展開を行いません。先に述べたように、 オプション指定を -a 2 や -b 2 とすると、 Source0とSource2で指定したものが展開されます。 Source2だけを展開したいときには、このオプションを使って、
%setup -T -a 2
とします。また、
%setup -T -c hoge
とすると、パッケージの展開は行わず、ディレクトリhogeを作って、 そこにcdします。
ソースの展開のとき、展開中の情報を表示しません。 たとえば tar での展開の時に、-q 無しだと tar xvvf、-q 有りだと tar xf のように変わります。
次のように tar.gz ではないファイルが Source0 となる場合があります。
Source0: hoge-%{version}.lzh
tar.gz ではないので、%setup では展開できません。
このような場合には、まず %setup の -Tオプション を利用して作業ディレクトリに移動します。 %setup のあとには、bash script を書いて作業を行うことができるので、 通常のコマンドで Source0 のファイルを展開します。
%setup -T hoge-%{version}
lha x %{SOURCE0}
%{SOURCE0} のかわりに ${RPM_SOURCE_DIR}とファイル名を用いて
%setup -T hoge-%{version}
lha x ${RPM_SOURCE_DIR}/hoge.lzh
とすることもできます。
次のように tar.gz などでは無いファイルが Source2 としてあるということがあります。
Source0: hoge-%{version}.tar.gz
Source1: hoge-additional-%{version}.tar.gz
Source2: how-to-use-hoge.txt
こういった場合には、Source0 と Source1 を %setup で展開したあとで、installコマンドなどで、Source2 に対応するマクロ %{SOURCE2} を処理します。
%setup で展開するのと同じ処理をしたければ、
%setup -q -a 1
%{__install} -m 644 %{SOURCE2} .
のようにします。
%setup で Source0 を展開してできたディレクトリ BUILD/hoge-%version/ に移動しているので、installコマンド で . (カレントディレクトリ[1]) を指定すると . は BUILD/hoge-%version/ となっているので、BUILD/hoge-%version/に Source2 が install されます。
他のファイルと同じように BUILD/hoge-%version/ にあるので %doc として指定するのもそのままできます。
%files %doc how-to-use-hoge.txt
%{SOURCE2} といったマクロは %doc のところでは使えないので、%doc %{SOURCE2} とすることはできません。
lha や unzip など、特別なコマンドが必要になる場合は、 BuildRequires(prep): で指定します。
%prepからはじまるスクリプト中で、patchをあてるためのマクロとしてはたらきます。 例のように書くと、
patch -p1 -s < ${RPM_SOURCE_DIR}/<Patchで指定したファイル>
と同じことをするので、%patchを使うかわりに%setupのあとで上のように書いてもいいです。 オプションなしで%patchと書くと、
patch -p0 -s < ${RPM_SOURCE_DIR}/<Patchで指定したファイル>
が起動されます。%patchは%setupからはじまるスクリプトに含まれる、 単なるマクロとしてはたらきます。 Sourceと同様に、Patch0, Patch1,...と複数の設定に対して、
%patch0 -p1 %patch1 -p1
と実行することも出来ます。%patchには-b <name> (バックアップ・ファイルの拡張子指定、デフォルトは.orig)などのオプ ションがあります。
ソースをmakeするスクリプトの開始であることを示し、また、 %setupで指定したディレクトリにcdするマクロとしてはたらきます。 以下には、makeを行うときの手順をスクリプトとして書きます。
ここでの処理で必要となるパッケージ等は、 BuildRequires(build): で指定します。
ファイルをinstallするスクリプトの開始であることを示し、また、 %setupで指定したディレクトリにcdするマクロとしてはたらきます。 以下には、installを行うときの手順を示します。 ここで、Section 4.2, “makeの準備”で述べたように、 データ定義部のBuildrootで設定したディレクトリ(${RPM_BUILD_ROOT}) の下に全てのファイルがインストールされるように、工夫しましょう。 Makefileが短いときには、修正してpatchをつくるかわりに、ここに、 cp, installコマンド等を用いたinstallスクリプトを書くのも一手です。
%setup のところと同じように、マクロ %{SOURCE数字} を使って Source: で指定したファイルを直接インストールすることもできます。
%{__install} -m 644 %{SOURCE2} %{buildroot}/where/there/
なお、rpm-3.0.5以降では、インストールされたバイナリは rpmパッケージにする段階で自動的にstripされますので、 %installでbinaryのstripを行う必要はありません。
ここでの処理で必要となるパッケージ等は、 BuildRequires(install): で指定します。
install が正しく実行されたかをcheckするスクリプトの開始であることを示します。 %setupで指定したディレクトリにcdするマクロとしてはたらきます。 以下には、make test や make check などを実行するときの手順を示します。
GNOME などが利用する desktopファイルの書式チェックなどを行うこともできます。 Appendix B, パッケージ固有の作法等についてのGNOME,KDE,Xfce のメニューに追加するためにを参照してください。
rpm-4.2以降で実装された機能です。
ここでの処理で必要となるパッケージ等は、 BuildRequires(install): で指定します。
rpmを作ったあとの後始末をこのタグの下に記述します。
ここでの処理で必要となるパッケージ等は、 BuildRequires(clean): で指定します。
スクリプト部に入れることができるタグは、ほかにも、いろいろあります。たとえば、 以下のタグはそれぞれインストール時やアンインストール時に起動するシェルスクリプトを記述するためのものです。
rpmパッケージをinstallするとき、パッケージの展開前に行うことを書く。 -pオプションについては%postの場合(以下)参照。
ここでの処理で必要となるパッケージ等は、 Requires(pre): で指定します。
rpmパッケージをinstallするとき、パッケージの展開後に行うことを書く。
ここでの処理で必要となるパッケージ等は、 Requires(post): で指定します。
たとえば、infoファイルをインストールする時には、
%post
if [ "$1" = 0 ] ; then
%{_syssbindir}/install-info %{_infodir}/hoge.info.gz %{_infodir}/dir
fi
として、info のメニューエントリに infoファイルを追加します。 if [ $1 = 0 ]; then と fi の行は、 アップグレード時には実行せず、インストール時だけに実行させるための記述です。 Chapter 9, rpmパッケージをつくるときの注意を参照してください。
%{_syssbindir}/install-info というコマンドが必要になるので、 Requires(post): %{_syssbindir}/install-info とします。
info ファイルは、アンインストール時にも処理が必要になります。 %preun も参照してください。
たとえば、ライブラリをインストールする時には、
%post
%{_syssbindir}/ldconfig
とすると、ldconfigが実行される。また、代わりに
%post -p %{_syssbindir}/ldconfig
と、-pオプションを用いて書くと、 シェルを起動すること無く直接コマンドが実行される。 またこのコマンドはrpmパッケージのインストール時に必要なコマンドとして、 Requires(interp): %{_syssbindir}/install-info として登録される。
正確にいうと、タグに -pオプションをつけた場合は、
/bin/sh ではなく別のプログラムでスクリプト部分を解釈(interpret)させるということになります。
この場合には Requires(interp) として登録されます。(%postなので Requires(post) としても登録されます。)
以下は問題が起こる例です。
%post -p %{_syssbindir}/ldconfig
# update ld.so.cache
%files
この場合は %post と %files の間の2行が、スクリプト部分になります。 一行目に
# update ld.so.cache
と書いてあります。 bash であれば、# で始まる行は コメントと解釈され無視されますが、 このスクリプト部分を読み、実行するのは /bin/sh ではなく %{_syssbindir}/ldconfig です。 ldconfig には # 以降をコメントとして無視するというルールは無いので、 そのまま実行しようとしてエラーになります。
エラーを起こさないようにするには
%post -p %{_syssbindir}/ldconfig
%files
とするか、
%post
%{_syssbindir}/ldconfig
# update ld.so.cache
%files
とします。
一つ目の例では、%{_syssbindir}/ldconfig がスクリプト部分を実行するために起動し(、起動した時点で ld.so.cache が更新されますが)、スクリプト部分については何も書かれていないので何もせずに終了します。
二つ目の例では、/bin/sh が起動し、スクリプト部分を解釈し %{_syssbindir}/ldconfig を実行、# 以下はコメントなので無視します。
rpmパッケージをuninstallするとき、展開ファイルの削除前に行うことを書く。
ここでの処理で必要となるパッケージ等は、 Requires(preun): で指定します。
-pオプションについては%postの場合と同様です。Requires(interp): と Requires(preun): に登録されます。
たとえば info ファイルをアンインストールする時には、
%preun
if [ $1 = 0 ]; then
%{_syssbindir}/install-info --delete %{_infodir}/hoge.info.gz %{_infodir}/dir
fi
として、info のメニューエントリから削除します。 if [ $1 = 0 ]; then と fi の行は、 アップグレード時には実行せず、アンインストール時だけに実行させるための記述です。 Chapter 9, rpmパッケージをつくるときの注意を参照してください。
rpmパッケージをuninstallするとき、各ファイルを削除した後に行うことを書く。
ここでの処理で必要となるパッケージ等は、 Requires(postun): で指定します。
-pオプションについては%postの場合と同様です。Requires(interp): と Requires(postun): に登録されます。
以上のタグは、作成したrpmパッケージをinstallやuninstallするときの、 実行されるスクリプトの設定になるので、 specファイルからrpmパッケージを作るときには、実行されることはありません。
さらに、他のパッケージがインストールされた時に起動するスクリプトも記述できます。
%pre %post %preun %postun %triggerin %triggerun %triggerpostun といったタグを使うのは、ちょっと注意が必要です。 詳しくは、Chapter 9, rpmパッケージをつくるときの注意を参照してください。
パッケージが正しくインストールされているかを検証するには、rpm コマンドで -V オプションを用いますが、-V オプションでできることを増やすためのタグもあります。
あるパッケージがインストールされていた、 もしくは、された時に起動するスクリプトを書く。たとえば、
%triggerin -- hoge echo "hoge is installed"
と書いておくと、パッケージhogeをインストールしたときに、 上記メッセージが表示されます。以下のように、バージョン指定もできます。
%triggerin -- hoge > 3.0 echo "hoge is installed"
同様にして、あるパッケージの削除前に実行される%triggerun、
あるパッケージの削除後に実行される%triggerpostunがあります。このタグについては、
/usr/share/doc/rpm-<version>/triggers に詳しい説明があります。
rpmパッケージを検証するとき(rpm -Vを実行した時)に、追加して実行することを書く。
ここでの処理で必要となるパッケージ等は、 Requires(verify): で指定します。
-pオプションについては%postの場合と同様です。Requires(interp): と Requires(verify): に登録されます。
このスクリプトの実行結果は、成功した場合には何も表示されず、エラーが発生したときにエラーメッセージのみが標準出力に出力されます。rpm -Vvv などのようにした場合には、標準出力への出力も確認できます。
たとえば、%pre で %{_sbindir}/useradd hoge などとしてユーザーを登録した場合には、
%verifyscript
%{_bindir}/id hoge
としておくと、hoge というユーザーが存在しているかどうかを確認することができます。
この場合、/usr/bin/id というコマンドは coreutils というパッケージに含まれているので、 Requires(verify): %{_bindir}/id あるいは、Requires(verify): coreutils とします。