RPM を使ったパッケージの作成方法 (RPM-BUILD-HOWTO)

古高和禎(ふるたか@原研),furutaka@Flux.tokai.jaeri.go.jp
石岡 尚(ishi), ishioka@PPP01.infoPepper.or.jp

第 0.5 版 96/12/02
この文書では、RPM (Redhat Package Manager) を使ったバイナリパッケージ (*.rpm) 及びソースパッケージ (*.src.rpm) の作成方法を説明します。 なお、説明する RPM の機能は、執筆時の最新版である 2.2.9 のもの です。

注意: この文書はかなり以前に書かれたものなので、 いまどきの Linux 環境にはあてはまらない箇所があります。 (JF Project)

1. 概要

2. RHL 以外のディストリビューションへの RPM のインストール

3. 設定ファイルと作成ツリー

4. パッケージ作成の準備 I (パッチ等の作成)

5. パッケージ作成の準備 II (spec ファイルの記述法)

6. パッケージ作成

7. 作成したパッケージのテスト

8. 依存性(dependencies)について

9. アドバンスト・コース

10. よくあるトラブル

11. 謝辞


1. 概要

1.1 この文書に書かれている事

この文書では、Red Hat Software の開発したパッケージマネージメント ツール、Redhat Package Manager (RPM) を用いたバイナリ及びソース パッケージの作成方法を解説しています。

この文書では、RPM を用いた、バイナリパッケージのインストール 及び更新方法、情報の問い合わせ方法や検証方法は解説しておりません。 これらに関しては、 RPM-HOWTO, RPM-Tips 及び rpm(8) の man page (または それらの翻訳)を参照して下さい。
RPM-HOWTO は、山縣 敦 <ayamagat@phys.metro-u.ac.jp> さんが日本語に翻訳して下さいました。
rpm(8) の man page は、第一筆者が翻訳し、随時 Linux-ML 等に 流しております。

なお、この文書では、パッケージマネージャを``RPM'' と 大文字で表記し、それを用いて作られるバイナリパッケージ (*.rpm)及びソースパッケージ(*.src.rpm) と区別しています。

1.2 著作権及び配付条件

この文書の著作権は古高和禎及び石岡尚にあるものとします。

また、この文書は、GPL に従って自由に配付・利用できるもの とします。

1.3 フィードバック

この文書は、筆者達が package-ML における RPM を使用したパッケージングの実験を通して得た 少ない経験及び知識をまとめたものです。

従って、筆者の誤解による誤った記述や欠落してしまっている情報が 数多くあるものと思われます。

誤りや追加すべき情報を発見なさった方は、 第一筆者 にお知らせ頂ければ、文書の更新時に訂正/追加を行なって参ります。

2. RHL 以外のディストリビューションへの RPM のインストール

RPM とは、Redhat Package Manager の略で、その名の通り Red Hat Software (RHS) の Linux ディストリビューション Red Hat Linux (RHL)用に開発されたツールで、ソフトウェア のインストール、保守、パッケージングを行ないます。

しかし、RPM は RHL 以外では使えない訳ではありません。 むしろ、RHS の面々が様々な文書で言っているように、 「他のディストリビューションでも容易に使える」のです (実際、最近では、とある理由から Debian ディストリビューションで RPM のバイナリパッケージが流通されていた筈です)。 また、Red Hat 以外のディストリビューションを使用している方も RPM を容易に使用できる様に、RPM のバイナリを(RPM を用いずに) インストールする方法が(現在のところix86アーキテクチャのみ ですが)用意されています。

この節では RHL 以外の ix86 アーキテクチャ用ディストリビューション に RPM をインストールする方法を解説します。 RHL ディストリビューションを用いている方は、RPM が インストールされていますから、この節は飛ばして構いません。 (もし、使用している RPM が古いもので、この文書で説明している 機能が使いたいのに使えない、という場合は、Red Hat 自身による RPM のアップグレード法に従って下さい。)

2.1 必要なファイル

RPM を使用するためには、

が必要です。これらのファイルは
Red Hat の本家ミラーサイト
及び、そのミラーサイトの対応するディレクトリ (例えば、日本国内なら、
KDD のミラー
等)にあります。

お使いのシステムに既に cpio がインストール されていても、バージョンが古い場合には (例えば Slackware 3.0 に含まれている ``GNU cpio version 2.3'') RPM が用いる --quiet というオプションが 備わっていないので RPM 2.2.9 と組み合わせては使用できません。 この場合は、上記ミラーサイト等から cpioftp し、現在インストールされている cpio と 入れ換えておいて下さい。

2.2 インストール

必要なファイルが揃ったら、root になって、 ``/'' ディレクトリで

gunzip < rpm-2.2.9-1.i386.cpio.gz | cpio -ivumd
と入力して下さい。

次に RPM の使用するデータベースファイルの準備をしましょう。

まず、root のまま(CWD は何処でも構いません)、 RPM の使用するデータベースファイルを置くためのディレクトリを 作成しましょう。

mkdir /var/lib/rpm

そして、

rpm --initdb
とすれば、/var/lib/rpm にデータベースファイルが作成されます。

これで RPM のインストールは完了しました。 RPM を用いて、.rpm バイナリパッケージのインストール を行なう事が出来る筈です!

3. 設定ファイルと作成ツリー

3.1 設定ファイル

RPM に対する設定は、

という(設定レベルの異なる)三種類のファイルにより行なわれており、夫々
/usr/lib/rpmrc

RHS の勧める RPM の設定が記述されている

/etc/rpmrc

サイト毎の設定ファイル

$HOME/.rpmrc

各個人毎に設定を行なうためのファイル

という役割を担っています。 この中で、/usr/lib/rpmrcは RPM パッケージに含まれて いますが、/etc/rpmrc 及び $HOME/.rpmrc は各自が作成する必要があります。 (RPM バージョン 2.2.7 以前は /etc/rpmrc も配付パッケージに 含まれて いたのですが、バージョン 2.2.8 以降は望ましい設定値が全て /usr/lib/rpmrc に書かれるようになったため、 同梱されなくなりました。 /etc/rpmrc が無い! 節を参照して下さい。 また、バージョン 2.2.8 でのバグについては、 RPM をアップグレードした際にエラーが出る 節を参照して下さい。)

3.2 パッケージ作成ツリー

RPM は、ディフォルト(即ち、/usr/lib/rpmrcの設定)では、 パッケージ作成ツリーの最上位ディレクトリを

topdir: /usr/src/redhat
とし、その下にある というディレクトリを利用します。
RPM を用いたパッケージを root として作成するためには 不可欠ですので、対応するディレクトリツリーを作成しておいて 下さい。

夫々のディレクトリは

BUILD

ソースを展開し、パッチを当て、make を行なう

RPMS/{i386,axp,sparc}

完成したバイナリパッケージ(*.rpm)が置かれる
(使用しているシステムが ix86 アーキテクチャなら、RPMS/i386 に置かれます。)

SOURCES

ソースファイル、パッチを置く
(``glint'' の使用するアイコン用の gif ファイル等もここに置きます。)

SPECS

パッケージ作成用の仕様書(spec ファイル)を置く

SRPMS

完成したソースパッケージ(*.src.rpm)が置かれる

ために用いられます。

この他にも、make して出来たファイルをその下に 「仮想的にインストール」してバイナリパッケージを作成する ためのディレクトリ(``BuildRoot:'')も用いられます。 こちらは、作成する各パッケージ毎に設定できますので、 spec ファイルを書く際 に説明します。

3.3 個人用作成ツリー

以上のディレクトリツリーさえ有れば、root として パッケージを作成する事が出来ます。

しかし、/usr/src 以下には(恐らく)書き込み権の無い 一般ユーザ「も」自分のホームディレクトリ以下にパッケージ作成 用ディレクトリツリーを設定し、RPM を用いてパッケージを作成する 事が出来ます。

パッケージ作成用ディレクトリツリーを一般ユーザの ホームディレクトリ以下に設定するには、そのユーザの $HOME/.rpmrc ファイル中に

topdir: /home/hogehoge/<mybuilddir>
と書いておき、<mybuilddir>以下に BUILD, RPMS,... といったサブディレクトリを作成 しておけば良いのです。 ここでは、ユーザ hogehoge のパッケージ作成用 ディレクトリを、そのホームディレクトリの下の <mybuilddir> に設定しています (勿論、<mybuilddir> はあなたが使用する 実際の作成用ディレクトリに置き換えて下さい)。

以後、 /home/hogehoge/<mybuilddir> 等を <topdir> と記述します。

4. パッケージ作成の準備 I (パッチ等の作成)

4.1 まずは make 出来るように...

まずは、オリジナルのソースを展開し、make 出来る様に しましょう。

ここでは、ソースファイルが harehore-1.23.tar.gz というファイルに保存されているとします。

  1. <topdir>/SOURCESharehore-1.23.tar.gz を持って来ます。
  2. <topdir>/BUILD で、オリジナルソースを展開します。 必要な(ソフト自体に対する)パッチも当てましょう。
    (新たにディレクトリを作り、そこにファイルを展開する 「のでない」アーカイブの場合は、後々のために ``harehore-1.23'' という ディレクトリを作成し、そのディレクトリに移って展開して下さい。)
  3. ディレクトリ ``harehore-1.23'' の名前を ``harehore-1.23.orig'' 等 に変更します。
  4. 1. の操作を繰り返し、再び ``harehore-1.23'' 中にソースファイルを展開します。
  5. ``harehore-1.23'' に移り、うまくmake 出来る ようになるまで変更を加えます。
  6. うまく make 出来るようになったら、make clean 等の操作によりソース・ディレクトリ内の *.o 等を消去した後、 パッケージ作成の為のパッチを作成し、<topdir>/SOURCES に置きます。
    このために、<topdir>/BUILD
    diff -uNr harehore-1.23.orig harehore-1.23 > ../SOURCES/harehore-1.23.patch
    として下さい。

4.2 「仮想」インストール

RPM は、make して出来たバイナリその他を一度システム上に インストールし、それらを用いてバイナリパッケージを作ります。 しかし、これでは、システム上に既にインストールされているファイルを 上書きしてしまう可能性があります。 これを避ける為に、あるディレクトリを指定し、それをインストールする ディレクトリツリーの最上位ディレクトリに見立てて、そのディレクトリ 以下に「仮想的に」インストールし、バイナリパッケージを作成する 事ができます。

最上位ディレクトリの指定は、Imakefile 等を用いている プログラムの場合は変数 DESTDIR で、また GNU のソフトの場合は Makefile の中の PREFIX (prefix) 等で指定する事が出来ます。

しかし、その様な機構が用意されていない場合は、インストールする ディレクトリツリーの最上位ディレクトリを指定できるように、 Makefile 等を改造しておきましょう。

例えば、以下の様な仮想的な Makefile の一部

----------
BINDIR=/usr/local/bin
LIBDIR=/usr/local/lib/harehore
 .......
install :
        install -s harehore ${BINDIR}
 .......
----------
に対しては、
----------
installprefix=$(ROOT)
BINDIR=$(installprefix)/usr/local/bin
LIBDIR=$(installprefix)/usr/local/lib/harehore
 .......
install :
        install -s harehore ${BINDIR}
 .......
----------
という様に変更を行なって下さい。

この Makefile に施した変更も、patchにして <topdir>/SOURCES に置いておきましょう。 (これらの変更を施してから前節の最後で述べた diff の操作を行なって patch を作るのでも構いません。)

5. パッケージ作成の準備 II (spec ファイルの記述法)

次はいよいよ、.rpm 及び .src.rpm を作成する為の 「仕様書」である spec ファイルを作成します。

5.1 spec ファイルの例

ただズラズラと spec ファイル中に記述すべき項目の説明を羅列 しても分かりにくいだけですので、例をあげて説明しましょう。

ここでは、著者の一人が作成した plain2-2.54 用の spec ファイル、``plain2-2.54-3.spec'' を例に取って説明します。

注:通常、.rpm 等のファイル名は、
<パッケージ名>-<バージョン番号>-<リリース番号>.<アーキテクチャ>.rpm
とします。例えば、i386 向けに作成した plain2 のバージョン 2.543 番目の rpm リリースに対しては、

plain2-2.54-3.i386.rpm
となるようにします。

以下に上記のspecファイルを示します。 右端の数字は解説用のインデックスで、実際のspecファイル には書かれていません。

---------- plain2-2.54-3.spec ----------
Summary: Plain2 plain text -> LaTeX/troff converter              1.
Name: plain2                                                     2.
Version: 2.54                                                    3.
Release: 3                                                       4.
Group: Applications/Publishing/TeX                               5.
Source: Flux.tokai.jaeri.go.jp:/plain2-2.54.tar.gz               6.
Copyright:                                                       7.
Packager: Kazuyoshi Furutaka <furutaka@Flux.tokai.jaeri.go.jp>        8.
URL: http://Flux.tokai.jaeri.go.jp                               9.
BuildRoot: /home/furutaka/work/rpm/plain2                       10.
Patch: Flux.tokai.jaeri.go.jp:/plain2-2.54.patch                11.

%package docs                                                   12.
Summary: Documents package of plain2                            13.
Group: Applications/Publishing/TeX                              14.

%description                                                    15.
Plain2 plain text -> LaTeX/troff converter (desc.)              16.

%description docs                                               17.
This package contains lots of documentation and Makefile        18.
for plain2 plain text -> LaTeX/troff converter.

%prep                                                           19.
%setup                                                          20.
%patch -p1                                                      21.
#%patch -p1                                                     22.

rm -rf   $RPM_BUILD_ROOT                                        --
mkdir -p $RPM_BUILD_ROOT/usr/local/bin                          23.
mkdir -p $RPM_BUILD_ROOT/usr/local/lib/plain2                   --

%build                                                          --
cd src                                                          24.
make                                                            --

%install                                                        --
cd src                                                          25.
make installprefix="$RPM_BUILD_ROOT" install                    --

%clean                                                          --
rm -rf $RPM_BUILD_ROOT                                          26.
                                                                --

%post                                                           --
chown -R root.root /usr/local/lib/plain2                        27.
chown    root.root /usr/local/bin/plain2
chown -R root.root /usr/doc/plain2-2.54-2                       --

%files                                                          --
%dir /usr/local/lib/plain2                                      ↑
/usr/local/bin/plain2
/usr/local/lib/plain2/OHP.p2
/usr/local/lib/plain2/OHP_t.p2                                  28.
/usr/local/lib/plain2/header.p2
/usr/local/lib/plain2/header_t.p2
/usr/local/lib/plain2/jbook.p2                                  ↓
/usr/local/lib/plain2/supsnum.p2                                --

%files docs                                                     29.
%doc doc/*
---------- end of plain2-2.54-2.spec ----------

では、各エントリーについて、順番に説明して行きます。

1.--18. はヘッダで、RPM を用いてパッケージの問い合わせ等に対する 返答や、ソースアーカイブなどの名前を記述しておくのに用いられます。

  1. このパッケージ(spec ファイル)の簡単な説明です。
  2. パッケージの名前です。
  3. パッケージが元にしているソースファイルのバージョン番号です。
    (ただし、バージョン番号の中にはハイフン ``-'' を用いる事は出来ません。 しようがないので、代わりにアンダースコア ``_'' を使って下さい。)
  4. この (.rpm 及び .src.rpm)パッケージの リリース番号です。
    (ソースのバージョンとは関係ありません。)
  5. Red Hat LiNUX でのパッケージの分類です。
    (日本語環境用配付パッケージ集を作成する時は、 独自の分類を考えた方が良いでしょう。RHL では、 Extensions/Japanese という階層が有ります。 (しかし、そこには ktermしか有りませんが(^^;;)
  6. 本来は、オリジナルのソースファイルの一次配布 ftp サイトを記述します。
    しかし、このように記述し、かつ、 自分の topdir: の下の SOURCES ディレクトリにソースファイルが置いてあれば問題無い様です。)
  7. 著作権を記述しておきます。
  8. ここには「RPM パッケージの維持」を行なっている人の名前と 電子メールアドレスを書いておきます。
    (ただし、これを書いておいても rpm -qiしただけでは 情報が表示されません。)
  9. ここには、パッケージ中のソフトウェアについての情報又は文書 への URL を書いておきます。
    将来的に RPM がこのタグを使う可能性もあるそうです。
    (このタグも、8. と同様 rpm -qi では情報が表示 されません。)
  10. バイナリ・パッケージを作成する為に「仮想的に」インストール を行なう際の、最上位ディレクトリを指定します。
  11. パッチの置き場所を記述します。
    (``Source:''(ソースの置き場所)と同様に、 この様な書式で指定し、かつ <topdir>/SOURCES にパッチファイルが置かれていれば、問題無く動作するようです。) 12.--14. は、ソースに含まれるファイルの一部を別のパッケージとする 場合のエントリです。(すべてのファイルを単一パッケージとする 場合は必要ありません。)
    この様にした場合は、(この例の場合) 文書ファイルを含まない plain2-2.54-2.i386.rpm の他に plain2-docs-2.54-2.i386.rpm という文書ファイルのみを含んだパッケージが作成されます。
  12. docs という別パッケージを作成する事を宣言します。
  13. 別パッケージの内容の簡単な説明を記述します。
  14. 別パッケージに対する分類を記述します。(この例では同じ分類)
  15. メインのパッケージ(この例では plain2-2.54-2.i386.rpm)の説明文のタグです。
  16. メインのパッケージの機能等を(アルファベット 50 字程度で) 記述します。
  17. サブパッケージ(この例では plain2-docs-2.54-2.i386.rpm)の説明文のタグです。
  18. サブパッケージの機能などを記述します。
  19. ソースを BUILD ディレクトリに展開し、パッチを当てる、 等の作業内容を記述しておくためのタグです。
  20. 実際にソースを展開し、パッチを当てる為の「マクロ」です。 動作内容は、オプション無しでは「ソースを展開し、出来た ディレクトリに cd する」ことです。 オプションには -n <name>, -c, -b #, -a #, -T, -D 等があり、夫々、
    -n <name>

    ソースを展開した後に cd するディレクトリ名を <name> とします。 ディフォルトでは $NAME-$VERSION です。 他には、 例えば $NAME, ${NAME}${VERSION} 等と する事も出来ます。
    (RPM-HOWTO にはこう書いてありますが $NAME$RPM_PACKAGE_NAME と書かないとダメな様です。)

    -c

    ソースファイルを展開する「前に」、指定したディレクトリを作成し、 そこにcd します。 上の -n <name> オプションと組み合わせて

    %setup -n <name> -c
    とする事により、<name> というディレクトリを作成し、 そこに cd する様にします。

    -b #

    展開先ディレクトリにcdする「前に」 # 番目のソース(Source#:)を展開します。

    -a #

    展開先ディレクトリに cd した「後で」 # 番目のソース(Source#:) を展開します。

    -T

    ディフォルトでは、%setupが現れる「毎に」 ``Source:''に示されたソースが展開されてしまいます。 そこで、複数のファイルが有る時は、二番目以降の%setup ではこのオプションを指定して、再び``Source:''が 展開されない様にします。 これに先だつ%setup-b 0 又は -a 0 と指定して、メインのソース「のみ」を展開しておかなくてはなりません。

    -D

    ディフォルトでは、%setup「毎に」BUILD ディレクトリに展開したものを消去してしまいます。 そこで、このオプションを指定して、二番目以降のソースを展開する 際に(既にBUILD に作成されている)ソースディレクトリを消去 しない様にします。

    という機能を持っています。 以上のオプション使用法の具体例を %setup マクロのオプションの使用例 節にて解説していますので、そちらを参照して下さい。
  21. パッチを当てるための「マクロ」です。 いくつかのオプションを取る事が出来ます。
    #

    ヘッダ中に Patch#: で示されている # 番目の パッチを当てます。

    -p #

    patch(1) コマンドに渡すべき、飛び越し可能 ディレクトリの階層数を # で指定します。

    -P

    ディフォルトの動作 (Patch もしくは Patch0を当てる) を抑止し、メインのソースがエラー無く展開できた事(返り値 0)を 確かめます。
    %patch # -P とする代わりに %patch# と指定する事も出来ます。

    この他にも、文書に記述されてはいないが使う事の出来る 機能/オプションが幾つかあるようです。 Undocumented(?) %patch functions節 を参照して下さい。
  22. コメントです。 コメントアウトするには行の最初の文字を '#' にします。
  23. 「仮想的にインストールする」ディレクトリを消去し、 新たに作り直しておきます。 ここで、RPM_BUILD_ROOT は、ヘッダ中で ``BuildRoot:'' により 指定したディレクトリに展開されます。 このように、%prep%buildといった 各タグの中では shell コマンドを書いておいて 実行させる事が出来ます。
  24. %build は実際の make を行なう 過程を示すタグです。
  25. %install は、インストール過程で行なう 作業を記述するタグです。 即ち、「BuildRoot: で指定されたディレクトリ 以下に仮想的にインストール」を行なっています。
  26. パッケージ作成終了後に行なう動作を記述するタグです。 無くても構いません。 ここでは、仮想インストールディレクトリの消去を行なっています。
  27. バイナリ・パッケージのインストール終了後に設定スクリプト等を 走らせる過程のためのタグです。
    (ここでは、一般ユーザがパッケージを作成しているために、ファイル の所有者が作成者になってしまっているので、所有者を root に変更しています。)
  28. %files は、このパッケージが所有するファイルを リストしておくためのタグです。 あるファイルがどのパッケージの所有物であるか問い 合わせる際や、パッケージを削除する際などに用いられます。 この際、各ファイルに %dir, %doc %config 等の印をつけておく事も出来ます。
    %dir

    これを付けられたディレクトリ「のみ」がこのパッケージ所有の ものであることを示します。 これを付けずにディレクトリを指定すると、そのディレクトリ 「中のすべてのファイル」がそのパッケージに属すると見做され、 インストールされます。

    %doc

    文書ファイルである事を示します。 ディフォルトでは /usr/doc/$NAME-$VERSION-$RELEASE にインストールされます。

    %config

    設定ファイルである事を示します。 アップグレード時には、古いリリースパッケージ中でこの印を付けられた ファイルに変更が加えられていない場合はそのまま消去し、変更 されていた場合はファイル名に .rpmsave を付けて保存します。

  29. サブパッケージ(この場合は docs) の所有するファイル を示すための、別の %files タグです。 サブパッケージを作らない場合は %doc doc/* の行を 27. に含めておけば良いだけです。
どうですか?分かりましたか?

5.2 例に登場していないタグ

上で用いられている以外にも、以下のようなタグがあります。

%pre

インストール前に行なう動作を記述するタグ

%preun

アンインストール前に行なう動作を記述するタグ

%postun

アンインストール後に行なう動作を記述するタグ

例えば、%post には、 「一般ユーザとして作成したためファイルの所有者がそのユーザに なってしまっている」ので chown したい場合や、 chmod したい場合などに用いる事が出来ます。

5.3 %setup マクロのオプションの使用例

ソースのディレクトリ名を指定する (%setup -n <name>)

%setup セクションの -n オプションを使うと、ソースを展開した 後で cd し、また %build で作業をするディレクトリの名前を指定することができます。

kon のソース(kon-0.99.4g.tar.gz) を例に取りましょう。このソースファイルを展開すると、

drwx--x--x manabe/dsl        0 Apr 17 16:06 1996 kon/
drwx--x--x manabe/dsl        0 Apr 17 00:53 1996 kon/font/
-rw------- manabe/dsl     4552 May  8 12:39 1994 kon/font/minix.c
-rw------- manabe/dsl      491 Apr  6 12:57 1996 kon/font/Makefile
(以下略)
と、kon というディレクトリの下にソースファイルが 展開されます。

一方、RPM は ${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION} というディレクトリ以下にソースが展開されているものとして、 %setup マクロを実行した後はそのディレクトリに cd しようとします。

この場合は、単に %setup とやるのではなく、 %setup -n kon と指定すれば、上記ソースを展開した後 kon という ディレクトリに cd します。 また、%buildの際もこのディレクトリで作業を します。 特に、この場合は $RPM_PACKAGE_NAME = kon ですので、

%setup -n $RPM_PACKAGE_NAME
とする事も出来ます。

因みに、RPM の中で定義されていて、spec ファイルの中で 使う事が出来る変数としては以下の様なものがあるようです。 (中身は筆者の一人の環境での例です。)

RPM_ARCH=i386
RPM_BUILD_DIR=/home/ishioka/local/work/package/redhat/BUILD
RPM_BUILD_ROOT=/home/ishioka/local/work/package/rpm-tmp
RPM_DOC_DIR=/usr/doc
RPM_OPT_FLAGS=-O2 -m486 -fno-strength-reduce
RPM_OS=Linux
RPM_PACKAGE_NAME=kon
RPM_PACKAGE_RELEASE=0
RPM_PACKAGE_VERSION=0.99.4g
RPM_ROOT_DIR=/home/ishioka/local/work/package/rpm-tmp
RPM_SOURCE_DIR=/home/ishioka/local/work/package/redhat/SOURCES

ディレクトリを作成してからソースを展開する (%setup -c)

%setup -c を使うと、まずソースを 展開するディレクトリを作成し、そこに cd したあとで ソースを展開してくれます。 例えば、xc32.tar.gz の場合、 ソースを展開すると次のようにカレントディレクトリにファイルを作る ので...

tar tzvf ../SOURCES/xc32.tar.gz
-rw-rw-r-- 0/1            3343 Jun 14 07:53 1991 .autocis
-rw-rw-r-- 0/1            1152 Jun  6 10:56 1991 .uni
-rw-rw-r-- 0/1             824 Jun  6 10:56 1991 .callhq
-rw-rw-rw- 0/1            4127 Aug 25 10:17 1991 Makefile

この様な場合は、

%setup -c -n xc-3.2
と指定して、まず xc-3.2 というディレクトリを作って cdさせ、そこに展開させます。 あとは普通の場合とおなじです。

複数ソース、パッチを当てる

以下のように複数のソースを順に展開することができます.

Source:  xc32.tar.gz .......... メインのソース
Source1: xc32pat.tar.gz ....... サブソース1
Source2: xc32news.tar.gz ...... サブソース2

%prep
%setup -c ..................... (1)
%setup -D -a 1 -T ............. (2)
%setup -D -a 2 -T ............. (3)

(1) では メインのソース(Source: で指定したもの) を 展開しています。 xc の場合、カレントディレクトリにファイルを作るので、 -c オプションで先にディレクトリを作成し、 cd した後で展開させています。

(2), (3)ではサブソースを展開していますが、これも(1) と同様の 理由から -c を付加しています。 また, それぞれ Source[12]: を指定 するために -a # オプションも使っています。 ここでは、-D オプションを使って、 (1)で展開したディレクトリを消去してしまわない様にしています。 こうしておかないと、せっかく展開したメインのソースが消されて しまうのです! また、単に -a 2 とだけ指定すると、 Source2 「と Source」 が展開 されてしまうので、-T オプションも指定しています。

5.4 Undocumented (?) %patch functions

%path マクロは、パッチファイルが圧縮されていても 動作するようです。
(自動的に ``gzip -dc <PatchFile> | patch ...'' を行なってくれる。)

また、%patchマクロのオプションとしては、 undocumented ではありますが、下記の様な patch(1) オプションも指定する事が出来るようです。

-b xxx

バックアップとして保存するファイルの拡張子を .orig から .xxx に変更する。

-R

リバースパッチを施す。

-E

パッチを当てた結果空になったファイルを削除する。

6. パッケージ作成

specファイルを書いてしまえば、 あとは <topdir>/SPECS に移って RPM を使ってパッケージを作成するだけです。

RPM 構築コマンドの一般的な形は

& rpm -bO [作成オプション] <specファイル名>+
です。

[作成オプション]は man page の翻訳等を 参照して頂くことにして、ここでは -bO の部分だけを 説明します。

-bOspec ファイル中で記述したどの過程 (タグ)まで作業を行なうかを指定するものです。

-bp

%prep 過程まで、即ち、ソースを展開してパッチを 当てるところまで作業を行ないます。

-bl

%files で記述されたファイルのリストの検査を 行ないます。

-bc

%build 過程(通常は実行ファイルを make するところ)まで行ないます。

-bi

%install 過程(通常 make install を行なう) までを行ないます。

-bb

(%prep, %build, %install を行なって から)バイナリパッケージを作成します。

-ba

(%prep, %build, %install を行なって から)バイナリ及びソースパッケージを作成します。

一つだけ [作成オプション] について説明しておきます。 --short-circuit をつけると、(-bc 又は -bi とともに用いた場合は) その前の過程をやらずにいきなり目的とする過程を実行します。

さて、-bb または -ba を指定してパッケージを 作成してみましたか? うまく行けば、

出来ている筈です。

7. 作成したパッケージのテスト

「でも、お前の作ったのなんて、大丈夫なの?...」

テストに関しては、RPM-HOWTO と重複が多くなるので、改めて 多くを述べる事は致しませんが...

究極のテストは、やはり全く異なるマシンにインストールして 使用してみる事です。

いくら(パッケージを作成した)自分のマシンにインストールして テストしても、(例えrpm -eしたとしても、何度も 何度も make installしたマシンでは、設定ファイル 等が残っていたりして)完全にはテストすることが出来ません。

そ・こ・で...

親しい Linuxer に「こんなのを作ってみたんだけど、使ってみない?」 と(甘い言葉を囁いて)テストしてもらうのが良いのではないでしょうか? (当然の事ながら、複数の Linux box をお持ちの方は、 自分の別のマシンにインストールしてみれば良い訳ですが。)

しかし、まず友達に渡す前に、最低限

rpm -qp --scripts <PackageName>
とやって、%pre及び%postインストールスクリプト でとてつもなく変な/愚かな事をやっていないか?位は確認しておかないと、 友達をなくしますよ!!!

8. 依存性(dependencies)について

8.1 依存性(dependencies)

これは非常にばかげた例ですが、先程例に上げた plain2-2.54-3.spec で作られるサブパッケージ plain2-docs-2.54-3.i386.rpm に含まれる ファイルは plain2 で加工してはじめて TeX のファイルとなるため、 plain2-2.54-3.i386.rpm (plain2 本体)が インストールされていなければなりません。 このような場合には、spec ファイル中に

Requires:  plain2
と記しておけば、「plain2-docs-2.54-3.i386.rpm を インストールするためには plain2 というパッケージが インストールされていなくてはいけない」という依存性関係を明示 しておく事が出来ます。 もし plain2 がインストールされていないのに plain2-docs をインストールしようとすると、
[root@Flux i386]# rpm -ivh plain2-docs-2.54-3.i386.rpm
failed dependencies:
        plain2 is needed by plain2-docs-2.54-3
と表示され、インストールは行なわれません。(依存性関係を無視して 無理矢理インストールしてしまう事も出来る事は出来ます。) (注 : この様に、サブパッケージで Requires: にメイン パッケージを指定する事も出来ます。)

Requires: の指定にはバージョン番号を含める事も出来ます。 例えば:

Requires: perl >= 5.003

同時に複数のパッケージを Requires: に指定する事も出来ます:

Requires: perl >= 5.003, python
(注 : 複数パッケージの区切りは `,' でも ` ' (空白)でも良いそうです。)

ところで、RPM 中のバージョン番号の新旧判断アルゴリズムは大抵の 場合うまく働きますが、β版である事を示すために b が付けられている場合もあり、この時は例えば 5.003b5.003 よりも新しいと判断されてしまいます。 このような事態を回避するために、パッケージにシリアル番号を 付けておく事が出来ます。

Serial: 19
このシリアル番号を持つパッケージを Requires: で指定 するには
Requires: perl =S 19
とします。

8.2 仮想パッケージ

ここで、あるパッケージを使用するにはなんらかの fortran コンパイラが必要であるが、コンパイラ自体は fort77(をコンパイラと呼ぶなら) でも g77 でも良いという場合を想像してみましょう。 こういう場合には、個々のパッケージ (fort77 又は g77) を指定する代わりに 「なんらかの fortran コンパイラ」として仮想的な パッケージを Requires: に指定する事も出来ます:

Requires:  fortran
この時は、fort77 又は g77 パッケージに
Provides:  fortran
という指定がなされていて、且つそれらのいずれがインストール されていれば、依存性が満たされ、これに依存するパッケージを 正常にインストール(して使用)する事が出来ます。

8.3 依存性関係の自動的な追加

しかし、便利な依存性関係も、いちいち全て Requires: で指定しなくてはならないとしたら、たまったもんではありません。 また、そのパッケージが依存するパッケージをいちいち手で調べて追加 していくのも容易ではありません。

そこで、RPM は、パッケージのファイルリスト中に共有ライブラリ を必要とするものがあった場合は、(その so 名が) Requires: に指定されているものと見做してそのパッケージ の依存性リストに自動的に追加して行きます。 また、逆にそのパッケージが供給する共有ライブラリの so 名も自動的に追加されます。

9. アドバンスト・コース

9.1 パッケージへの電子的署名

RPM で作成したパッケージが本当に query により表示 される人が作ったものかどうか、またパッケージが ftp 等の際に損傷していないかを調べられるように、 各パッケージには電子署名を付けておく事が出来ます。

現在は (version 2.2.9) MD5, SIZE, PGP の署名を サポートしています。

MD5, SIZE の署名は常に行なわれます。

PGP 署名をする場合はオプション引数にて指定します。 (PGP の鍵束はディフォルトでは $HOME/.pgp に 置かれていると想定していますが、環境変数PGPPATH で、 もしくは $HOME/.rpmrc ファイル中に pgp_path: という行を書いておく事によって変更する事が出来ます。)

パッケージの作成と同時に PGP 署名をするには、オプション 引数に --sign を付け足すだけです。

既存のパッケージに PGP 署名をし直す場合は、

rpm --resign <package>
とします。

しかし、この場合は以前付けられていた署名は消去されてしまい ます。
新たに PGP 署名を追加したい場合は、

rpm --addsign <package>
とします。

(でも、あなたの公開鍵を公開しておかないと、 他の人は確かめようがありませんよ!!!)

10. よくあるトラブル

10.1 日本語環境で用いた場合に Seg.Fault する事への対策

Q :

JE 環境で rpm --help 等とすると Segmentation Fault を起こして、RPM が死んでしまう のですけれど...
rpm -ivh <package> 等は正常に働きます。

A :

RPM は、多国語対応化するために GNU gettext utility を使って います。そして、環境変数 LANGUAGE, LC_CTYPE, LC_ALL, LANG を順番に調べて行き、いずれかが設定されていた場合は、 対応する gettext の RPM.mo ファイルを /usr/lib/locale/<lang>/LC_MESSAGES/ に読みに 行きます。

ところが、通常の日本語環境(JE)では、LANG=ja_JP.ujis に設定して いるので、/usr/lib/locale/ja_JP.ujis/LC_MESSAGES/RPM.mo を読みに行くと、そこに RPM.mo が無いために Segmentation Faultしてしまう、という事になっているようです。

従って、``export LANG=''とやって、LANG を 空にしてみて RPM --help が正常に動作すれば、こういう 問題ですので、

export LANGUAGE=C
とやっておけば良い筈です。 もしくは、日本語化した RPM.mo(筆者の一人が作成しました) を
/usr/lib/locale/ja/LC_MESSAGES/
に置き、
export LANGUAGE=ja
などとやっても解決できる筈です。

10.2 /etc/rpmrc が無い!

Q :

RPM をアップグレードしたら /etc/rpmrc が入ってないのですが。

A :

恐らくバージョン 2.2.8 以降をお使いなのでしょう。 バージョン 2.2.8 以降は、望ましいディフォルト設定値が /usr/lib/rpmrc 中に全て記述されているため、 /etc/rpmrc は配付されなくなりました。 勿論、自分で /etc/rpmrc を作成して設定を書いておく事は 有効です。

10.3 RPM をアップグレードした際にエラーが出る

Q :

RPM をアップグレードする際にエラーが表示されるのですが。

A :

バージョン 2.2.8 では、/usr/lib/rpmrc ファイル中に typo があり、

bad option 'arch_cnaon' at /usr/lib/rpmrc:50
と怒られてしまいます。

/usr/lib/rpmrc の上記 ``arch_cnaon'' となって いる箇所を ``arch_canon'' に訂正して下さい。

11. 謝辞

この文書を書く上で、多くの方の方からの協力を頂きました。 ここに感謝の意を表したいと思います。

山縣 敦 氏(山縣@都立大さん)

本文書に記述した大部分の事柄の情報源となっている RPM-HOWTO の翻訳の労を取られるとともに、 原稿を通してお読み下さった上で非常に有益な示唆・指摘を 頂きました。

佐藤 大輔 氏(佐藤@東邦大さん)

原稿をお読み頂き、非常に有益な示唆・指摘を頂きました。

瑞慶覧 辰 氏(``ず'' さん)

%patch マクロの隠れた機能に関する情報を お寄せ頂きました。

package-ML の皆さん

本文書の元となる多くの貴重な情報及び経験をお寄せ下さいました。

西森 信行 氏

たまたま第一筆者の近くで Slackware を使っていたが為に、 第一筆者の実験台とされ、 文句も言わずに(筆者が耳を貸さなかっただけ?) 数多くのテストを行なって下さいました。