RPMパッケージの作成方法 Jun Nishii Yasumichi Akahoshi Kazutaka HARADA Takuya Kobayashi はじめに このドキュメントは、rpmパッケージの作り方の初歩を解説するように書きはじめたものです。 特に、他のドキュメントでは分かりにくかったり、触れられていなかったりする点に注意して書くようにしていますので、これまで何気なくrpmパッケージを作ってきた人にも、役に立つ点があると思います。 間違いの指摘・コメント・要望等は、ML(メーリングリスト)や BTS(バグトラッキングシステム)で知らせていただければ、できるだけ反映していくつもりですので、ご協力をお願いします。また、specファイルを書く時にこういうことがわからなかったという意見や情報も募集中です。 このドキュメントでは、rpmパッケージの作り方に関する知識は無いが、rpmパッケージのインストール方法や、シェルスクリプトや基本的なコマンドの使い方は知ってると仮定して、説明を省いてるところが多くあります。 rpmパッケージの作り方についてさらに知りたい人は、 RPM-BUILD-HOWTO (古高さん、石岡さん著、JFにあります)や Maximum-RPM(英語です。)を読みましょう。 どちらも、書かれてからだいぶ時間が経っていますが、参考になると思います。 RPM-BUILD-HOWTO は JF というパッケージがインストールされていれば、 /usr/share/doc/JF/archive/RPM-BUILD-HOWTO.txt.gz にあります。 また、rpm付属のドキュメントが /usr/share/doc/rpm-version/ 以下にあります。(英語です。) 細かなことについて知りたい場合は、apt-get source rpm , rpm -bp rpm.spec などとして、rpm 自体のソースを読むのもよいでしょう。 Vine Linux では パッケージングに関する指針 というドキュメントもあります。Vine Seed や Vine Plus のパッケージを作成する場合にはこの指針に従ってください。 なお、この文書の最新版はhttp://vinelinux.org/documentations.html から入手できます。 更新記録(1999/2/16以降) 2007/10/3 Appendix B で desktop file に関して修正 2007/9/10 Appendix B で desktop-file-install を使うよう修正 2007/7/21 Appendix B に desktop-file-validate について追記 2007/6/26 Copyright と Serial について追記 2007/6/25 %prep での %{SOURCE数字} の利用例を記載 %post での install-info の例で、install時にのみ処理を行うように if文 を追加 %files と Requires の探し方のヒントを記載 ExclusiveArch と ExcludeArch の説明を記載 Appendix B にalternatives を利用するパッケージについて追加 2007/5/23 Requires( ),BuildRequires( ) の説明を追加 Prereq の代わりに Requires(pre,post) 等の使用を推奨 %verifyscript について記載 %verify について記載 パッケージ作成後に確認することを記載 リンクの修正 2006/12/8 Epoch の使用について記載 install-info --delete の記述を修正 Group 一覧、説明 の typo を修正 2006/11/17 Group 一覧、説明を rpm-4.4.2-0vl16 にあわせて修正 2006/11/8 License の説明を修正 %check の説明を追記 rpmbuild -bi で %check も実行されることを記述 Vine Linux 4.x での Group 一覧、説明を修正 Appendix B にGNOMEのメニューについて追加 2006/11/3 Vine Linux 4.x での Group 一覧、説明を追加 BuildRequires と BuildConflictsの説明を追加 Requires と Prereq、BuildRequires と BuildPrereq の説明を修正、それぞれの違いを追記 %config に noreplace,missingok の説明を追加 マクロの説明を追加 spec の例を修正、マクロを使用した spec の例を追加 %check の説明を追加 %post,%postun に info ファイルの例を追加 タグの -p の説明を追加 Appendix B パッケージ固有の作法等についてを作成 2006/10/26 全体を見直し 2004/9/19 rpmbuildを推奨する様、追加。 2004/6/30 tex形式から、DocBook SGML形式に変更。 2000/10/30 細かい修正をすこし rpm-3.0.5 以降で binary が strip されることと、man/info がgzされることを記述 Prereq の説明追加 rpm -bp の説明追加 2000/3/7 minor なタイポや記述の修正 %setup の記述修正(-a,-b)および追加(-q) .rpmmacros の説明に .rpmrc の場合も併記 1999/9/3 .rpmmacros の記述追加(rpm-3.0.x 対応) BuildPrereq に関する記述を追加 1999/2/16 Summary(ja), %description -l ja, %changelog に関する記述を追加 その他細かい修正 rpm関連ファイルの説明 rpmパッケージ バイナリパッケージ。これの作り方をこのドキュメントでは解説します。 srpmパッケージ ソースパッケージ。rpmパッケージを作るために必要なソースやパッチ、 specファイルを含んでます。rpm -ivh <hoge.src.rpm> で展開できます。(次節も参照) specファイル ソースからrpmをつくための、makeの手順やパッケージの情報を書いたファイル。 これを書くと、rpmコマンドによってrpmパッケージとsrpmパッケージをつくれます。 以下では主にspecファイルの書き方を説明します。 rpmパッケージをつくるための準備 環境設定 Vine Linuxでは、インストール直後から一般ユーザ権限でrpmパッケージが作れるように配慮されています。 通常ユーザーのホームディレクトリにはrpmパッケージを作る為のディレクトリが以下のように用意されているはずです。 ~/rpm |-- BUILD |-- RPMS | |-- alpha | |-- athlon | |-- i386 | |-- i586 | |-- i686 | |-- noarch | |-- ppc | `-- sparc |-- SOURCES |-- SPECS `-- SRPMS またユーザー毎のマクロを記述する.rpmmacrosファイルもホームディレクトリに用意されているはずです。 もし必要なファイルやディレクトリが無い、または削除してしまった場合は、端末上で mkrpmdir コマンドを実行してください。 $ mkrpmdir ~ このコマンドによりホームディレクトリ(~)配下に必要なrpmディレクトリツリーと.rpmmacrosを作成できます。 mkrpmdirコマンドは、既存の .rpmmacros ファイルを上書きしません。 上記のコマンドは、Vine Linux特有のvutilsパッケージに含まれています。 言語設定は LANG=ja_JP.eucJP もしくは LANG=C にする必要があります。 各ディレクトリはそれぞれ次のように使われます。 RPMS/i386:できあがったrpmパッケージが収納されます。 (architectureによってi386の所がppcやsparcだったりします) SRPMS :できあがったsrpmパッケージが収納されます。 SPECS :srpmパッケージをrpm -ivhで展開した時のspecファイルがここに出力されます。 SOURCES :rpmパッケージをつくるのに必要なソースやパッチのデフォルトの置場所です。 またsrpmパッケージをrpm -ivhで展開した時のソースファイルはここに出力されます。 BUILD :rpmパッケージをつくるときに、rpmコマンドがソースを展開したり、 makeしたりするための作業に使うディレクトリです。tmpみたいなところです。 このディレクトリの位置を変更したいときには、 /usr/lib/rpm/macros~/.rpmmacrosで設定します。 例えば、上にあげたディレクトリを全て/usr/public/rpm以下に用意するときには、 以下のように設定します。 %_topdir /usr/public/rpm/ また、個別に以下のように設定することもできます。 %_rpmdir /usr/public/rpm/RPMS %_srcrpmdir /usr/public/rpm/SRPMS %_specdir /usr/public/rpm/SPECS %_sourcedir /usr/public/rpm/SOURCES %_builddir /usr/public/rpm/BUILD rpmdirやtopdirを設定したときには、RPMS/i386(architectureによってはRPMS/sparcなど) という名前の書き込み可能なディクレトリを作っておくのを忘れないようにしましょう。 また、rpmパッケージを作る時にroot権限で行うとなんでもできてしまいますが、 パッケージのビルド中にインストール先を間違って既存のファイルを上書きしてしまったり、 あるいは消去してしまったりという危険を伴います。 可能な限り、一般ユーザ権限で作成することを推奨します。 以下では、上で説明したディレクトリを単にBUILDとか、SOURCESと呼びます。 makeの準備 まず、作成したいrpmパッケージをつくるための、ソースを手にいれて、 それを make, make install できるように、手直しして、パッチを用意します。 オリジナルのソース・ディレクトリをhoge.org/、 修正したソース・ディレクトリをhoge/とすると、 $ diff -uNr hoge.org/ hoge/ > hoge.patch とかしてpatchをつくります。 Makefileだけとか個別にdiffをとっても良いです。 ソースとパッチは前節で設定したSOURCESのディレクトリにおきます。 rpmを作る時には、一度ソースを make install して、 その出力ファイルをかき集めることによって、rpmを構築することになります (この作業は自動的に行われます。後述)。 しかし、この make install で、 システム上の既存ファイルが上書きされたりしたら、とても悲しいですね。 このようなことを避けてrpmパッケージを構築するために、 ある指定ディレクトリをルートディレクトリ"/"とみなして、 その下にインストールを行なえば、 そこにインストールされたファイルをもとにrpmを構築することができます。 ソースによっては、例えばMakefileのオプション指定で、 $ make DESTDIR=/tmp/rpm-root/usr/local install と指定して/tmp/rpm-root/以下にバイナリ・ツリーをつくったりできるものも増えてきましたが、 多くの場合Makefileをちょっと修正することになります。 そのパッチも用意しましょう。 specファイルを書く さて、rpmパッケージを作成するためには、specファイルを記述しないといけません。 specファイルを書き方を知るための、おすすめは、Maximum-RPMを読むことです。 分厚いですが、よくまとまってて、英語も読みやすいです。 てきとうに拾い読みすればいろいろわかります。 それから、古高さんと石岡さんのRPM-BUILD-HOWTOにも説明があります。 rpm -ivh fugafuga-version-revision.src.rpm とかして、 出てきたspecファイルを見るってのも良いです。 以下にサンプルとして簡単なspecファイルをあげ、その内容について説明をします。 なんとなくわかったら、小さなパッケージを作ってみて、 さらにいろいろ作りたくなったら上にあげたようなdocumentを読んでください。 より多くのマクロを使ったspecファイルの例が にありますのでそちらも参照してください。 ---------spec ファイルの例 (#から始まる行は、コメント行です)-------- #(1)データ定義部 Summary: hoge is a harehare horehore Name: hoge Version: 1.1 Release: 2 Source: hoge-1.1.tar.gz Patch: hoge.patch.gz License: distributable Group: Local Packager: Jun Nishii <jun@vinelinux.org> Buildroot: %{_tmppath}/%{name}-%{version}-root Summary(ja): hoge は harehare な horehore です。 %description Hoge is a harehare horehore and convenient for fugafuga. Enjoy! %description -l ja hoge は harehare な horehore で、fugafuga するときなどとても便利なツー ルです。みんなでなかよく使いましょう。 %changelog * Tue Feb 16 1999 Jun Nishii <jun@vinelinux.org> 1.1-2 - added Japanese messages * Mon Feb 15 1999 Jun Nishii <jun@vinelinux.org> 1.1-1 - first release for version 1.1 #(2)スクリプト部 %prep #rpmを構築する前の準備です。 rm -rf $RPM_BUILD_ROOT %setup #ソースをBUILDに展開します。 %patch -p1 #パッチをあてます。 %build #makeのための手順を書きます。 make (cd man; make man) %install #installのための手順を書きます。 make prefix=${RPM_BUILD_ROOT}/usr/local install (cd man; make prefix=${RPM_BUILD_ROOT}/usr/local install.man) %clean #rpmを作ったあとの後始末です。 rm -rf $RPM_BUILD_ROOT #(3)ファイルリスト部 -------------- %files %defattr(-,root,root) %doc README %doc docs/ /usr/bin/hoge.bin /usr/lib/hoge/ /usr/man/man1/hoge.1.gz %dir /usr/lib/hoge/ %config /usr/lib/hoge/fuga.conf ---------specの例はここまで----------------------------------------- specファイルは、(1)データ定義部と、(2)さまざまな作業をするためのscriptを書くスクリプト部、 そして、(3)バイナリパッケージであるrpmを構成するファイル名を列挙するファイルリスト部からなります。 では、上の例をみながら、各部分の説明をしましょう。 データ定義部 データ定義部はパッケージに関する情報を記入する部分です。 例の各タグの意味は以下の通りです。 スクリプト部で環境変数に代入されて用いられるものは、その環境変数名も書いてます。 パッケージングに関する指針 も参照してください。 パッケージの名前やバージョンなど、パッケージに関する情報を扱うタグです。 Summary パッケージの説明を簡単に一行で書きます。 タイトルのようにspecファイルの一行目に書くことが多いです。 英語で簡潔に書きましょう。Summaryは、国際化機能をもっており、 Summary(ja)のように、日本語のサマリーを書いておくと、 環境変数 LANGUAGE が ja な時には、日本語のほうが表示されます。 ただし、Summary(ja)を用意したときにも、英語のSummaryは必ず用意してください。 また、日本語がspecファイルの始めの方にあると、 rpmコマンドがエラーを出すことがあるので、 Summary(ja)はデータ定義部の下のほうに書くほうがいいようです。 また、日本語メッセージは必ず EUC で入れてください。 Name つくるrpmパッケージの名前です。 環境変数RPM_PACKAGE_NAMEに設定されます。 Version ソースのバージョン名を入れます。 環境変数RPM_PACKAGE_VERSIONに設定されます。 Release 同じソースからつくるrpmパッケージのリリース番号です。 環境変数RPM_PACKAGE_RELEASEに設定されます。 rpmver というパッケージに含まれている rpmver というコマンドで、バージョンやリリース番号の比較ができます。 $ rpmver -v 1-a 1-1 RPM version 1-a is lesser than version 1-1. License 作成するrpmパッケージのライセンスを書きます。 もとのソースの COPYING などのファイルを参照し、 できるだけ簡潔に書きましょう。 rpm 4.1 以降では Copyright ではなく License を使うようになりました。(rpm 4.4 で Copyright は obsolete となりました。) Copyright を使っている場合は License に書き変えましょう。 Group 作るパッケージのグループ名を書きます。 このグループ名は、 rpmコマンドオプションで利用したり、 Synaptic分類に用いることができます。 にGroup一覧を示します。 自分で作ったパッケージのグループ名をとりあえず Local にしておくなどグループ名はこの一覧に無いものでも自由に付けられますが、 分類ということを考え適切なグループ名を選択しておきましょう。 Packager rpmパッケージを作ってるあなたの名前です。Email addressを入れておくと、 思わぬとこからバグ報告とかもらえて嬉しいこともあります。 %description このタグの下に、rpmパッケージの解説を書きます。 rpm -qip <rpm-name>で出てくる説明です。 このタグも国際化機能をもってます。日本語メッセージを表示させたいときには、 %description -l ja を用います。ただし、日本語メッセージを用意したときにも、 必ず英語メッセージは書いておきましょう。 %description は、 specファイルの一番下(ファイルリスト部の下)に持って来ることもできます。 Distribution 作成したrpmパッケージがなんらかのディストリビューションに含まれる時、 そのディストリビューション名を書きます。 Vendor 作成したrpmパッケージに関する責任を負うVendor名です。 なんらかのプロジェクトでrpmパッケージを作ってる時には、 そのプロジェクト名を書きましょう Url ソースの情報を提供しているURLを書きます。 例えば以下のように書きます。 URL: http://www.fugahogo.com/hogehoge.html 次にパッケージ作成時に必要となる情報に関するタグです。 Source rpmパッケージをつくるソース名です。 で設定したSOURCESのディレクトリに置いておきましょう。 ソースの入手先を明示するために、 Source: ftp://ftp.hogehoge.org/hoge-1.1.tar.gz と書いておくと便利です。自分でつくったソースならば、 サンプルのようにファイル名のみを書いておきます。 複数のソースファイルがあるときには、 Source0: ftp://ftp.hogehoge.org/hoge-1.1.tar.gz Source1: ftp://ftp.hogehoge.org/hoge-devel.tar.gz というふうに番号をふって列挙します。(Source0 と Source は同じ意味です) Souce数字 で指定したファイルは %{SOURCE数字} というマクロとして の %prep や %install などの部分で利用できます。 %{ } の中の SOURCE は全て大文字にしてください。%{Source数字} のように小文字を利用することはできません。 Patch 上で設定したソースにあてる、パッチファイルです。書式はSourceと同じです。 このパッチファイルもディレクトリSOUCESに置いておきましょう。 複数あるときにも、Sourceと同様に番号をふって列挙できます。 Buildroot で説明した、 仮想インストールのためのディレクトリ名を書きます。 Buildrootの設定を行わなければ、RPM_BUILD_ROOTはnullです。 例では、%{_tmppath}, %{name}, %{version}というマクロを利用して、 Buildrootが定義されています。%{_tmppath}は/usr/lib/rpm/macrosで定義されており、 /var/tmpを指します。%{name}はパッケージの名前を、%{version}はパッケージのバージョンを示すマクロです。 直接ディレクトリ名を書くのではなく、マクロを利用することを推奨します。 例の場合の Buildroot は/var/tmp/hoge-1.1-rootというディレクトリを指すことになります。 %changelog ここには、更新のログを書いておきます。最新の更新情報が上にくるように書きます。 必須ではありませんが、バージョンアップの履歴や設定変更などといった更新情報は、 トラブル解決の重要なヒントにもなりますので必ず書いておきましょう。 %changelogは、specファイルの一番下(ファイルリスト部の下)に持って来ることもできます。 一行目の最初に * を書き、日付と変更を加えた人の名前を書きます。 二行目以降に - を書き、更新内容を書きます。 今日の日付は date コマンドLANG=C date +'%a %b %d %Y' とすると確認できます。 12月1日のように日の部分が一桁の場合は 0 をつけ 01 のようにします。 Vine Linux でのパッケージングルールでは 一行目に日付、パッケージャーの名前、メールアドレス、パッケージのバージョン,、リリース番号を書くことになっています。 * 曜日 月 日 西暦年 パッケージャーの名前 <メールアドレス> バージョン-リリース番号 - 更新内容 更新内容の部分でもマクロは展開され %{name} は hoge になります。 マクロを展開せずにそのまま %{name} と書きたい場合は %%{name} のように % を二つ続けて書いて下さい。 日本語を使うことも可能になっていますが、Summary や description のように環境変数に応じて日本語や英語のどちらかを表示するという仕組みは無いので、 英語だけで書くほうがよいでしょう。 サンプルのspecファイルのような指定で、rpmパッケージをつくると、 hoge-1.1-2.i386.rpm という名前のrpmができます (architectureがi386の場合)。 サンプルには書かれてませんが、他にも以下のようにいろいろなタグがあります。 いろいろ設定したい時に参考にして下さい。 パッケージの依存情報など、他のパッケージとの関係を扱うタグです。 Requires 作成しているrpmパッケージが動作するのに必要なパッケージ名を書きます。 例えば、 Requires: gs として、動作にgsがインストールしていることが必要なことを示します。 <, >, =, >=, <=といった演算子を使って必要なバージョン、 リリース番号を示すことも出来ます。演算子の両側には必ずスペースを入れてください。 (入れないと一つの名前として認識されてしまいます) Requires: ghostscript = 5.10 とするとghostscriptのバージョン5.10が必要なことを示し、 Requires: ghostscript >= 5.10 として5.10以上が必要なことを示します。必要なライブラリ名を書くこともできます。 Requiresしたいものが複数あるときには、 Requires: ghostscript >= 5.10, ghostscript-fonts, VFlib = 2.24 などのように、'','' や '' ''(スペース)で区切って並べます。 また、 Requires: ghostscript >= 5.10, ghostscript-fonts, VFlib = 2.24 Requires: tetex, tetex-extra のように複数行で書くこともできます。 たくさんのパッケージが必要となる場合や、 それらのパッケージがいくつかのグループに分類できる場合には、 複数行に書いた方がわかりやすくなります。 rpmパッケージをbuildするときには、 そのパッケージに含まれるバイナリの実行に必要なライブラリ名も、 自動的にRequiresに加えられます(正確には必要なライブラリのsonameが加えられます)。 rpmパッケージをinstallするときに、必要なライブラリがシステム上にないと、 libhoge.so is neededとかいって、おこられますが、 libhoge.soがなんというパッケージに入ってるかわからずに困ることがよくあるので、 必要なパッケージ名をきちんとRequiresに書くように心がけましょう。 筆者はbuildした時に出力されるメッセージの Requires: /bin/sh libICE.so.6 libORBit-2.so.0 といった部分を、(bash の for文 を利用して)slocaterpm -qf で処理してパッケージ名を調べています。 $ for i in libICE.so.6 libORBit-2.so.0 ; do slocate $i |xargs rpm -qf ; done | sort -u Requires( ) Requires には、従来の Requires: だけではなく Requires(pre): などのように ( ) をつけて厳密に指定することもできるようになりました。 バージョン、リリース等を演算子を用いて指定することや、複数のパッケージをまとめて指定、複数行に分けて書くなど、書式は Requires: と同じです。 ( ) の中にはにあるものが入ります。 ( ) の中に入る項目は のタグ等に対応しています。どの部分で必要になるかを書きます。 Requires( ): のように ( ) の中に何も書かなかった場合は、Requires: として扱われます。 ( ) の中は、Requires(pre,preun,post,postun): のように , を用いることで複数を同時に指定できます。 Requires の ( ) の中で利用できるもの 項目対応するタグ等pre%pre で必要になるものpreun%preun で必要になるものpost%post で必要になるものpostun%postun で必要になるものprereqインストール時に必要になるものverify%verifyscript で必要になるものinterpスクリプト部を解釈(interpret)するために必要になるものrpmlibrpmのデータベース等を扱うために必要なもの
Requires(pre): などを指定した場合には、PreReq: の時と同様に、インストール、アンインストールされる順番が保証されます。 指定されたパッケージは先にインストールされ、後にアンインストールされます。 prereq は pre,preun,post,postun などよりも曖昧な書き方ですが、PreReq で書かれていたものを Requires に機械的に置き換える場合には利用できると思います。 rpmlib については、通常、build 時に自動的に追加されるものなので、特別な機能を利用するのでなければ、記述する必要はありません。 interp も、自動的に追加されますが、特別な shell などを利用する場合には記述しておいた方がよいでしょう。
PreReq rpm 4.0. から 4.0.[12] の間の変更で、PreReq: の代わりに Requires(prereq): 等を用いるようになりました。 PreReq: もまだ利用できますが legacy という扱いなので、Requires(prereq): 等の使用を推奨します。 Requiresと同様に必要とするパッケージ名を書きます。バージョンの指定もできます。 Requiresとの違いはインストールされる順番が保証されるということだけです。 Prereqで指定されたパッケージは先にインストールされます。 A というパッケージが Prereq: B として B というパッケージを要求した場合には、 B のパッケージが A のパッケージより先にインストールされているかチェックが行われるので、 rpm -ivh A B のように A と B を同時にインストールするように指定した場合にも B が A より先にインストールされるようになります。 パッケージのインストール時アンインストール時に必要となるパッケージは、 Prereq で指定してください。 Requiresと重複してもかまいません。 例えば、infoファイルをもったパッケージでは、 パッケージインストール時(%post)の infoファイルのインストールに install-info が必要となるので、Prereq で指定する必要があります。 パッケージの動作自体には直接必要なくても、 %pre,%post,%preun,%postun などで必要になるコマンドやパッケージは、Prereq で指定する必要があります。 Conflicts Requiresと逆の意味を持ちます。すなわち、共存できないパッケージ名を指定できます。 バージョンやリリース番号指定もRequiresと同様にできます。 例えば以下のように指定します。 Conflicts: fugefuge >= 1.0, fugafuga = 1.2-1 Provides パッケージが提供する機能を書きます。 日本語化されたgsであるgsjというパッケージがあるとします。 このパッケージはもともとのgsと同等の機能を持っています。 インストールしたいhoge-1.1-2.rpmがgsを必要(Requires)としてるとしましょう。 しかし、gsjがインストールされているためにgsはインストールされていません。 このとき、hoge.rpmをインストールしようとするとrpmコマンドは gsが無いためにエラー・メッセージを出します。 このようなトラブルをさけるためには、gsjを作るときに、 Provides: gs と書いておくと、gsjはgsパッケージを提供することができます。 また、あるパッケージ A がpdfを読むツールをRequiresするときに、 xpdf と gs(pdf対応) のように複数の選択肢がある場合、 xpdf と gs の Providesに Provides: pdf-reader と仮想的なパッケージ名(仮想パッケージ virtual package)を書いておいて、 A で Requires: pdf-reader としておけば、パッケージ名を限定せずに、 なんらかのpdf-readerがインストールされてることを要求できます。 たとえば emacs lisp のパッケージでは emacs や xemacs ではなく emacsen という仮想パッケージを要求するものが多いです。 Obsoletes 仮に、pLaTeX2eのrpmをインストールするときには、 古いTeXのパッケージであったptexはアンインストールしたいとしましょう。 こんなときには、pLaTeX2eのspecファイルには、 Obsoletes: ptex と書いておくと、pLaTeX2eのインストール時にptexは消去されます。 BuildRequires パッケージの作成の時に必要になるパッケージを書きます。 例えば、 BuildRequires: zlib-devel として、パッケージの作成に zlib-devel パッケージが必要なことを示します。 コンパイラなどのパッケージや、 ヘッダーファイルやライブラリなどを含んだ hoge-devel などのパッケージで不足するものがないか確認しましょう。 また、Source: で指定されたファイルが hoge.zip のように zip 形式の場合は、 ソースの展開に unzip のパッケージが、 同様に lzh 形式なら lha のパッケージが必要になります。 Vine Linux では build-essential という仮想パッケージがあり、 このパッケージをインストールすることでたくさんのパッケージがインストールされます。 参照 環境設定 パッケージの作成時には build-essential をインストールすることを前提としているので、 build-essential に含まれている make,gzip,bzip2,tar,patch,findutils,coreutils,file,libtool,automake,autoconf などは省略してかまいません。 gcc や gettext などは、ソースが C言語であることや、メッセージが国際化されていることなどを示す意味もあるので、必要であれば書いておいた方がいいかもしれません。 %prep,%setup,%build,%install で必要になるコマンドやパッケージを指定します。 BuildRequires( ) Requires( ): と同じように、BuildRequires も ( ) をつけて詳細な指定をすることができます。 ( ) の中にはにあるものが入ります。 ( ) の中に入る項目は のタグ等に対応しています。どの部分で必要になるかを書きます。 BuildRequires の ( ) の中で利用できるもの 項目対応するタグ等prep%prep,%setup で必要になるものbuild%build で必要になるものinstall%install,%check で必要になるものclean%clean で必要になるもの
BuildPrereq BuildRequiresと同様にパッケージの作成の時に必要になるパッケージを書きます。 BuildRequiresとの違いは必要とするパッケージを作成する順番を決めるということです。 BuildRequiresと同様、BuildPrereq(prep) のように prep,build,install,clean を指定できます。 A というパッケージがパッケージ作成時に B と C の二つのパッケージを必要としているとします。 この場合 B と C をインストールすれば、A というパッケージを作成することができます。 このときに B と C のパッケージがなくて、それぞれ作る必要があったとします。 B と C がそれぞれ独立したものではなく、C のパッケージ作成時に B が必要で、 できあがった C は B の特定のバージョンを必要とするパッケージになるということがあります。 このような場合には BuildPrereq に B を BuildRequires に C を指定し、 B を C よりも先に作成する必要があるということを示しておきます。 BuildConflicts BuildRequiresと逆の意味を持ちます。 パッケージ作成時にはインストールしておけないパッケージ名を指定できます。 例えば以下のように指定します。 BuildConflicts: huga Prefix このタグを使うと、 rpmパッケージをインストールする時にインストールディレクトリをコントロールできます。 例えば、 Prefix: /usr としていて、ファイル定義部で %files /usr/bin/fuga と定義してたとしましょう。このパッケージをインストールする時に、 --prefix /usr/local とオプション指定すると、 fugaは/usr/local/bin/fuga.binにインストールされます。 BuildArch 書いたspecファイルを使って生成されるrpmパッケージのアーキテクチャを指定できます。 例えば、elファイルとかシェルスクリプトとかばかりを含むrpmパッケージを作るときには、 i386やalphaなどのアーキテクチャに依存しないnoarchであることを、 BuildArch: noarch というふうに明示します。 このような指定をしておくとnoarch.rpmという拡張子のつくrpmパッケージが作成できて、 いろいろなアーキテクチャ上で共用できます。 ExclusiveArch specファイルや src.rpmパッケージから、パッケージを生成 できる アーキテクチャーを指定します。 たとえば、ExclusiveArch: i386 とすると、i386 以外の ppc,i486,i586,i686,x86_64 といったアーキテクチャーではバイナリパッケージを生成できなくなります。 ExcludeArch specファイルや src.rpmパッケージから、パッケージを生成 できない アーキテクチャーを指定します。 たとえば、ExcludeArch: ppc とすると、ppc ではバイナリパッケージを生成できなくなります。ppc 以外の i386,i486,i586,i686,x86_64 といったアーキテクチャーではバイナリパッケージを生成できます。
データ定義部には、さらにいろいろな情報を付け加えることもできます。 MaximumRPM等を見てください。
スクリプト部 データ定義部の次の部分は、以下のような%が頭に付くタグからはじまる、 一連のscriptで構成されます。重要なのは、各タグから始まる次のタグの前までの部分は、 独立したbashスクリプトとして実行されるということです。 (注:以下で、%setup, %patchはスクリプトのはじまりを表すタグではなく、 スクリプト中で記述を簡略するためのマクロです。) より正確には、各タグが現れた時に #!/bin/sh -e が起動され(Vine Linuxでは/bin/shは/bin/bashにsym.linkされてる)、 各環境変数(RPM_SOURCE_DIRやRPM_PACKAGE_NAMEなど)が定義された後、 次のタグが出てくるまで、記述されているスクリプトが実行されます。 %prep ソースのmakeやインストール作業前の準備の開始を示すタグです。 以下で説明する%setup,%patchなどのマクロを用いたり、 シェルスクリプトを記述して、ソースの展開などを行います。 ここで、 %prep rm -rf ${RPM_BUILD_ROOT} として、${RPM_BUILD_ROOT}(先のBuildrootで指定したディレクトリ) を掃除することが多いです。ただし、このときには、 Buildrootの設定には十分気をつけて下さい(何故かわかりますね?) %setup %prepからはじまるスクリプト中で、ソースを展開するためのマクロです。 %setupとオプションなしで書くと、以下が順に行われます。 で指定したディレクトリ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にはさまざまなオプションがありますが、 代表的なものを以下に示します。 -n <ディレクトリ名> %setupを実行した後(もしくは前)にcdするディレクトリ名(name)を指定する。 このオプションを省略したときの、デフォルトのディレクトリ名は、 ${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}。 -c 指定ディレクトリ(上の-nオプションで指定したディレクトリ) を作成し(create)、そこにcdした後にソースの展開をします。 -a <#> Source0を展開した後、 指定ディレクトリ(上と同じ)にcdした(after)、 #番目のソース(Source#)の展開をします。 %setup -a 2 -a 3 と複数-aオプションが指定された時には、 Source0 が展開された後、指定ディレクトリに cd し、 Source2、Source3を展開します。 (Source0の展開は最初の一回だけです。) -b <#> Source0を展開した後、 指定ディレクトリ(上と同じ)にcdする前に(before)、 #番目に指定されてるソース(Source#)の展開をします。 -D 先に述べたように、%setupは、まず、指定ディレクトリ(上と同じ)が、 ディレクトリBUILDの下にあるかどうかをチェックして、もし存在していたら、 それを削除してから、ソースの展開などの作業を行います。 %setupを複数回呼びたい場合、 2回目に%setupを呼んだ時に最初の%setupで展開したディレクトリを削除されては困ります。 この-Dオプションは、このような削除を行わないようにします。(あまり使いません) -T ソースの展開を行いません。先に述べたように、 オプション指定を -a 2 や -b 2 とすると、 Source0とSource2で指定したものが展開されます。 Source2だけを展開したいときには、このオプションを使って、 %setup -T -a 2 とします。また、 %setup -T -c hoge とすると、パッケージの展開は行わず、ディレクトリhogeを作って、 そこにcdします。 -q ソースの展開のとき、展開中の情報を表示しません。 たとえば 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コマンド で . (カレントディレクトリcurrent directory, 現在のディレクトリ) を指定すると . は 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): で指定します。 %patch %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)などのオプ ションがあります。 %build ソースをmakeするスクリプトの開始であることを示し、また、 %setupで指定したディレクトリにcdするマクロとしてはたらきます。 以下には、makeを行うときの手順をスクリプトとして書きます。 ここでの処理で必要となるパッケージ等は、 BuildRequires(build): で指定します。 %install ファイルをinstallするスクリプトの開始であることを示し、また、 %setupで指定したディレクトリにcdするマクロとしてはたらきます。 以下には、installを行うときの手順を示します。 ここで、で述べたように、 データ定義部の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): で指定します。 %check install が正しく実行されたかをcheckするスクリプトの開始であることを示します。 %setupで指定したディレクトリにcdするマクロとしてはたらきます。 以下には、make test や make check などを実行するときの手順を示します。 GNOME などが利用する desktopファイルの書式チェックなどを行うこともできます。 のGNOME,KDE,Xfce のメニューに追加するためにを参照してください。 rpm-4.2以降で実装された機能です。 ここでの処理で必要となるパッケージ等は、 BuildRequires(install): で指定します。 %clean rpmを作ったあとの後始末をこのタグの下に記述します。 ここでの処理で必要となるパッケージ等は、 BuildRequires(clean): で指定します。 スクリプト部に入れることができるタグは、ほかにも、いろいろあります。たとえば、 以下のタグはそれぞれインストール時やアンインストール時に起動するシェルスクリプトを記述するためのものです。 %pre rpmパッケージをinstallするとき、パッケージの展開前に行うことを書く。 -pオプションについては%postの場合(以下)参照。 ここでの処理で必要となるパッケージ等は、 Requires(pre): で指定します。 %post 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 の行は、 アップグレード時には実行せず、インストール時だけに実行させるための記述です。 を参照してください。 %{_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 として登録される。 正確にいうと、タグに オプションをつけた場合は、 /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 を実行、# 以下はコメントなので無視します。 %preun 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 の行は、 アップグレード時には実行せず、アンインストール時だけに実行させるための記述です。 を参照してください。 %postun rpmパッケージをuninstallするとき、各ファイルを削除した後に行うことを書く。 ここでの処理で必要となるパッケージ等は、 Requires(postun): で指定します。 -pオプションについては%postの場合と同様です。Requires(interp): と Requires(postun): に登録されます。 以上のタグは、作成したrpmパッケージをinstallやuninstallするときの、 実行されるスクリプトの設定になるので、 specファイルからrpmパッケージを作るときには、実行されることはありません。 さらに、他のパッケージがインストールされた時に起動するスクリプトも記述できます。 %triggerin あるパッケージがインストールされていた、 もしくは、された時に起動するスクリプトを書く。たとえば、 %triggerin -- hoge echo "hoge is installed" と書いておくと、パッケージhogeをインストールしたときに、 上記メッセージが表示されます。以下のように、バージョン指定もできます。 %triggerin -- hoge > 3.0 echo "hoge is installed" 同様にして、あるパッケージの削除前に実行される%triggerun、 あるパッケージの削除後に実行される%triggerpostunがあります。このタグについては、 /usr/share/doc/rpm-<version>/triggers に詳しい説明があります。 %pre %post %preun %postun %triggerin %triggerun %triggerpostun といったタグを使うのは、ちょっと注意が必要です。 詳しくは、を参照してください。 パッケージが正しくインストールされているかを検証するには、rpm コマンドで -V オプションを用いますが、-V オプションでできることを増やすためのタグもあります。 %verifyscript 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 とします。 ファイルリスト部 %filesはじまる部分で、rpmパッケージにつめこむファイル名を列挙します。 このとき以下に注意してください。 ここに書くファイル名は重複したらいけません。 列挙されたファイルは、%docで指定するものを除いて、 %installまでのスクリプトの実行によって、 記述した通りの場所(${RPM_BUILD_ROOT}を''/''とみなす) にinstallされるものでないといけません。 列挙されたファイルがおかしな userID/groupID を持っていると、 rpmパッケージが正常にbuildできないことがあります。 ファイルを含まないバーチャルパッケージRequires で他のパッケージをまとめてインストールしたり、%post, %preun, %postun などで何らかのコマンド処理を行うようなパッケージ。task-gnome や task-tetex などのように task- という名前が使われます。を作る場合でも、%files という行だけは必要になります。%files という行を省略してしまうと、rpmbuild コマンドで処理しても src.rpm しか作れません。 rpmコマンドは、specファイルに基づいてrpmパッケージを作るときに、 で設定した一連のスクリプトを実行した後、 ${RPM_BUILD_ROOT}をとみなして%files以下で指定されたファイルを回収し、 それを指定位置にinstallするようなrpmパッケージをつくります。 ドキュメント・ファイルの指定 %docというマクロを用います。specファイルの例のように、%doc READMEとすると、 %setupで指定したホームディレクトリ下のREADMEが、 ${RPM_BUILD_ROOT}/usr/doc/hoge-1.1-2/にcpされたのち、 rpmパッケージに回収されます。つまり%docは、 ドキュメントファイルのインストールとパッケージングのためのファイル指定を同時に行うマクロとしてはたらきます。 以下のように、ディレクトリごと指定もできます。 %doc doc/ rpmに含めるファイルの指定 その絶対パスで指定します。 個別ファイルはそのまま指定。(/usr/bin/hoge.bin など) あるディレクトリ以下の全てのファイルをrpmパッケージにいれたいときには、 そのディレクトリ名を書きます。(タグなし、/usr/hoge/ など)。 アンインストール時には、そのディレクトリごとなくなります。 ワイルドカードも使えます。(/usr/hoge/* など) rpm-3.0.5以降では、man ファイルや info ファイルは自動的にgzipで圧縮されます。 %filesにmanやinfoのファイル名を書くときには拡張子.gzをつけるのを忘れないようにしましょう。 タグを用いたファイル指定 %dir <dir name> 指定したディレクトリだけをパッケージに含める。 ``/usr/hoge/'' = ``%dir /usr/hoge/'' + ``/usr/hoge/*'' ってかんじです。 %config <file name> configファイルであることを示す。 ファイルが書き換えられていた場合、 アンインストール時には .rpmsaveをつけた名前で保存されます。 アップグレード時には新しいファイルと置き換えられ、 元のファイルは .rpmsaveをつけた名前で保存されます。 ファイルが変更されていた場合、 アップグレード時に新しいファイルに置き換えずにもとのファイルをそのまま使う場合には、 %config(noreplace) を指定します。 %config(noreplace) <file name> この場合新しいパッケージに入っている設定ファイルは、 .rpmnew をつけた名前で保存されます。 また、アップグレードではなく、同じバージョンをインストールし直した時には、 .rpmorig をつけた名前で保存されます。 存在しなくても問題ないファイルの場合は、 %config(missingok) を指定します。 %config(missingok) <file name> これは、rpmコマンドの -V オプションでチェックした時に、 ファイルが無くてもエラーにならないようにするためのものです。 %attr(<mode>,<owner>,<group>[, dirmode]) <file name> %filesに列挙するファイルのパーミッションやuser ID、group IDを設定する。 例えば、 %attr(755,root,root) /usr/lib/hoge とする。一部の属性を省略(書き換えない)したいときには - を使って、 %attr(755,-,root) /usr/lib/hoge とする。このタグを用いることによって、 root権限を持ってない人もrpmのパッケージ化を行える。 %attr(755,root,root) のように( )の中には 3つしか書かないことが多いですが、 %attr(755,root,root,755) のように 4つ書くこともできます。 4つ目の数字(dirmode)は、 ディレクトリとサブディレクトリのパーミッションになります。 %defattr(<mode>,<owner>,<group>[, dirmode]) それ以降の行に書かれた属性のデフォルト値を設定する。 %attr が出てきた行を除いて、それ以降に書かれたものに共通になります。 %defattr も %attr も何度でも使えます。 次の例だと、/usr/bin/hoge と /usr/lib/hoge は一つ目の %defattr の 755 になり、 /usr/share/locale/ja 以降は二つ目の %defattr の 644 になります。 %defattr(755,-,-) /usr/bin/hoge /usr/lib/hoge %defattr(644,-,-) /usr/share/locale/ja /usr/share/locale/lv %attrと同様、4つ目の数字は、 ディレクトリとサブディレクトリのパーミッションになります。 %verify( ) <file name> %filesに列挙するファイルについて、rpm -V でパッケージを検証する時に、検証する項目を指定する。 ( ) の中にはにあるものが入ります。 複数指定する場合には、, もしくは スペース で区切ります。 %verify の ( ) の中で指定できるもの 項目内容sizeサイズmodeパーミッションとファイルの種類md5md5 値rdevデバイスファイルのモードビットなどlinkリンク先userファイルの所有者 usergroupファイルのグループ groupmtimeファイルの更新時刻 mtime(modification time)
not とすると検証しない項目だけを指定できます。 書き換えることが前提となる設定ファイルなので、ファイルサイズ と md5値 と 更新時刻 は検証する必要がないといった場合には、 %verify(not size,md5,mtime) /etc/hoge.conf のように指定します。
%defverify( ) それ以降の行に書かれたファイルについて検証する項目を設定します。 %verify と %defverify は、%attr と %defattr と同じような関係です。
%config %attr %verify などは、次のようにスペースを入れることで一つのファイルに複数指定できます。 %config %verify(not size,md5,mtime) /etc/hoge.conf この%filesの指定は少々面倒なとこかもしれません。 新しくパッケージをつくる場合などは、%install までのスクリプト部を書いたところで、%files以下は何も書かないまま、一度、そのspecファイルから rpm をbuildしてみるとよいかもしれません。(rpm -bi hoge.spec これについては次節)。 そのあとで、${RPM_BUILD_ROOT}以下にinstallされてるファイルを、find コマンドで見てみて%filesの指定をします。 %filesで書かれていないファイルがある場合には、build 時に パッケージに未収録のファイルを検査中: /usr/lib/rpm/check-files /var/tmp/hoge-1.1-root 警告: パッケージに未収録のインストール済みファイルが見つかりました: と未収録のファイルの名前などが表示されます。 この部分を利用して %files の部分を作成するのもよいでしょう。 ソースのバージョンアップなどで、作成されるファイルが増減したり、ディレクトリが変わったりする場合があります。未収録のファイルがあっても、build が途中で終了せず、パッケージを作成できてしまう場合があるので、build 時のメッセージは必ず確認してください。
書いたspecファイルをもとにrpmパッケージをつくる Vine Linux 3.0以降で採用されているrpm-4.xではパッケージのビルドはrpmbuildコマンドを利用するようになりました。過去との互換性のためVine Linuxでは、rpmコマンドも利用できるようになっていますが、将来的に廃止の予定であるため今後はrpmbuildコマンドをお使いください。 specファイルを書いた後は、以下のようにして、rpmパッケージをつくります。 rpmとsrpmをつくりたいときには、(build all) $ rpmbuild -ba hoge.spec とりあえず、rpmだけつくりたいときは(build binary) $ rpmbuild -bb hoge.spec srpmだけつくりたいときは(build srpm) $ rpmbuild -bs hoge.spec rpmもsrpmもつくらずに、パッケージの展開だけしてみる (%buildの前までを実行)(build prep、%prepが実行される。) $ rpmbuild -bp hoge.spec これは、パッチをつくるときに便利です。 rpmもsrpmもつくらずに、ちょっとmakeがうまくいくかテスト (build compile、%prep,%buildが実行される。) $ rpmbuild -bc hoge.spec オプションをつけると %build 以前の部分(%prep) を省略して %buildが実行されます。 $ rpmbuild --short-circuit -bc hoge.spec rpmもsrpmもつくらずに、ちょっとinstallまでうまくいくかテスト (build install、%prep,%build,%install,%checkが実行される。) $ rpmbuild -bi hoge.spec オプションをつけると %install 以前の部分(%prep,%build) を省略して %install,%checkが実行されます。 $ rpmbuild --short-circuit -bi hoge.spec %files が正しく書かれているか確認できます。 次のように | (パイプ) と tee コマンドを利用して、ビルド中のメッセージをファイルに残しておくと、エラーの確認や、%files の確認、Requires の確認といった作業がやりやすくなります。 $ rpmbuild -ba hoge.spec 2>&12>&1 はエラーメッセージ(2:標準エラー出力の内容)を (tee コマンドに渡すために) 標準出力(1) にリダイレクトする(2に流れるメッセージを 1と合流させる)というものです。これで、tee で指定したファイル hoge-build.log に、標準出力のメッセージと一緒にエラーメッセージも書き込まれるようになります。 |tee hoge-build.log 以上のコマンドを実行すると、segmentation faultを起こす時には、 で述べたLANGの指定を再確認してください。 うまくいけば、ディレクトリRPMS/i386にrpmパッケージが、 ディレクトリSRPMSにsrpmパッケージができるはずです。 他に、 tar.gz 形式のソースの中に含まれている spec ファイルを用いて build するときには、 -b のかわりに -t を用いて、 $ rpmbuild -ta hoge.tar.gz などとします。 変数とマクロを利用する 環境変数 スクリプト部の各タグからはじまる部分は、先にも述べた通り独立したbash scriptとして働くので、 その範囲内で、 TEXMF="/usr/share/texmf" と変数を定義して用いることができます。 定義した変数は ${ } で囲んで ${TEXMF} のようにすると利用できます。 $TEXMF のように { } を省略することもできます。 /usr/share というディレクトリは標準で %{_datadir} というマクロが定義されているので TEXMF="%{_datadir}/texmf" とすることができます。 マクロについては、次節以降で説明します。 また、以下の変数は各タグ毎に環境変数として定義されます。 RPM_SOURCE_DIR ディレクトリSOURCESを表す。参照。 デフォルトは、 RPM_SOURCE_DIR="/usr/src/redhat/SOURCES" RPM_BUILD_DIR ディレクトリBUILDを表す。参照。 デフォルトは、 RPM_BUILD_DIR="/usr/src/redhat/BUILD" RPM_DOC_DIR %docで指定されたドキュメントファイルをインストールするためのディレクトリを表す。 rpmrcファイルの、defaultdocdirで指定する。デフォルトは、 RPM_DOC_DIR="/usr/doc" RPM_OPT_FLAGS コンパイル時にコンパイラにわたすデフォルトのオプション指定を表す。 rpmrcファイルの、optflagsで指定する。 アーキテクチャ毎に指定ができる。 例えば、%buildにおいて以下のように使う make CFLAGS=${RPM_OPT_FLAGS} デフォルトはarchitectureがi386のときには、 RPM_OPT_FLAGS="-O2 -m486 -fno-strength-reduce" RPM_ARCH_FLAGS buildを行なっているシステムのアーキテクチャを表す変数。 アーキテクチャがi386なら、 RPM_ARCH_FLAGS="i386" RPM_OS buildを行なっているシステムのOSをあらわす変数。Linuxなら、 RPM_OS="Linux" RPM_BUILD_ROOT Buildrootで設定された仮想インストールのためのディレクトリを表す。 (のBuildrootの項参照) RPM_PACKAGE_NAME Nameで設定されたパッケージ名を表す。 (のNameの項参照) RPM_PACKAGE_VERSION Versionで設定されたバージョン名を表す。 (のVersionの項参照) RPM_PACKAGE_RELEASE Versionで設定されたリリース番号を表す。 (のReleaseの項参照) specファイル中のマクロ定義 マクロは %define マクロの名前 内容 のように書くことで定義できます。 %{マクロの名前} のように書くことで利用できます。 {} を省略して %マクロの名前 と書くこともできますが、 {} をつけて利用したほうが、 に出てきた %prep や %build などといったタグと区別しやすくなります。 マクロは、%setupや%installなどのスクリプト部やファイル定義部など、 specファイル全体で使えるので、 うまく使うとバージョンアップに追随してspecファイルを書くときに楽ができます。 %define で定義せずに使えるマクロとして %{name} , %{version} , %{release} があります。 にでてきた、Name Version Release の値が、 それぞれ %{name} , %{version} , %{release} の内容になります。 %define name hoge として name を定義し Name: %{name} のように利用しているspecファイルを見かけることがありますが、 Name の値を参照するのが %{name} なので、本来とは逆の使い方になり問題を起こす場合があるかもしれません。 このような場合は %define pkg_name hoge , Name: %{pkg_name} のように %{name} とは違う名前のマクロを利用したほうがよいでしょう。 のspecファイルの例のデータ定義部は、 %{name} と %{version} というマクロを利用して、以下のように書くことができます。 Name: hoge なので %{name} は hoge に、Version: 1.1 なので %{version} は 1.1 になります。 Name: hoge Version: 1.1 Release: 1 Source: %{name}-%{version}.tar.gz Patch: %{name}.patch specファイルの中(どこでもいいです)に %dump と書いておくと、 rpmbuild コマンドでパッケージを作る時に、 すべてのマクロが標準エラー出力に出力され、確認することができます。 マクロの定義を取り消したいけれど、行を削除するのではなくコメントとして残しておきたいという場合には、 %define に % をつけて、%%define にし、さらに # をつけます。 %define hoge hige# %%define hoge hige のようにします。 # %define hoge hige ではだめです。 # 以降はコメントになるという処理よりも、マクロの %define の方が先に処理されるので、 %define hoge hige が解釈されてしまいます。 標準で定義されているマクロ よく利用されるコマンドやディレクトリなどにはあらかじめマクロが定義されています。 自分で定義した変数と同様にspecファイル全体で使えます。 標準で定義されているマクロは /usr/lib/rpm/macros に書かれています。 ユーザー毎のマクロを記述するファイルは~/.rpmmacrosです。 ~/.rpmmacros に書く場合には %マクロの名前 内容 とします。 で出てきた %_topdir などもマクロです。 ユーザー毎のマクロと、標準で定義されているマクロをあわせたものは、 rpmコマンドの オプションで確認できます。 $ rpm --showrc また、それぞれのマクロがどんなものかは、 $ rpm --eval "%{マクロ}" のようにすると確認できます。 標準で定義されているマクロについてはなるべく利用してください。 specファイルのメンテナンスしやすさの向上につながります。 たとえば、%{configure} や %{makeinstall} といったマクロを利用することで、 %build や %install の部分を簡潔に書くことができる場合があります。 %build %{configure} %{__make} %install %{makeinstall} $ rpm --eval "%{configure}" などとやってそれぞれのマクロがどんなものか確認して下さい。 rpm 4.x および Vine Linux 4.1 で定義されているマクロを使うと のspecファイルは次のようになります。 ---------spec ファイルの例 (#から始まる行は、コメント行です)-------- #(1)データ定義部 Summary: hoge is a harehare horehore Name: hoge Version: 1.1 Release: 2 Source: %{name}-%{version}.tar.gz Patch: %{name}.patch.gz License: GPL2 Group: Local URL: http://www.fugahogo.com/hogehoge.html Packager: Jun Nishii <jun@vinelinux.org> Requires: hige BuildRequires: hige-devel Buildroot: %{_tmppath}/%{name}-%{version}-root Summary(ja): hoge は harehare な horehore です。 %description Hoge is a harehare horehore and convenient for fugafuga. Enjoy! %description -l ja hoge は harehare な horehore で、fugafuga するときなどとても便利なツー ルです。みんなでなかよく使いましょう。 %changelog * Tue Feb 16 1999 Jun Nishii <jun@vinelinux.org> 1.1-2 - added Japanese messages * Mon Feb 15 1999 Jun Nishii <jun@vinelinux.org> 1.1-1 - first release for version 1.1 #(2)スクリプト部 %prep #rpmを構築する前の準備です。 %{__rm} -rf $RPM_BUILD_ROOT %setup #ソースをBUILDに展開します。 %patch -p1 #パッチをあてます。 %build #makeのための手順を書きます。 %{__make} (cd man; %{__make} man) %install #installのための手順を書きます。 %{__make} prefix=${RPM_BUILD_ROOT}/%{_prefix}/local install (cd man; %{__make} prefix=${RPM_BUILD_ROOT}/%{_prefix}/local install.man) %clean #rpmを作ったあとの後始末です。 %{__rm} -rf $RPM_BUILD_ROOT #(3)ファイルリスト部 -------------- %files %defattr(-,root,root) %doc README %doc docs/ %{_bindir}/hoge.bin %{_libdir}/hoge/ %{_mandir}/man1/hoge.1.gz %dir %{_libdir}/hoge/ %config %{_libdir}/hoge/fuga.conf ---------specの例はここまで----------------------------------------- サブパッケージの作成について 大きなソースをmakeしてrpmパッケージを作るときなど、 幾つかのrpmパッケージに分割したくなることがよくあります。 たとえば、muleのrpmパッケージをつくるときに、 baseのrpmパッケージがelcを含んでいれば、 そのソースであるelファイルはなくてもmuleの実行には問題ないですから、 mule.rpm と mule-el.rpm みたいにわけたほうがよいかもしれません。 また、ライブラリや開発用インクルードファイルもソースに含まれるアプリケーションをrpm化する時は、 アプリ本体の hoge.rpm と、開発者用にlibhoge.a や hoge.hを入れたhoge-devel.rpmにわけたいこともあるでしょう。 ドキュメントが大きいと、hoge-docs.rpmも別に作りたいこともあるでしょう。 こういうときには、ちょっとspecファイルを変更するだけで、 サブパッケージの作成をすることができます。 具体的には、 サブパッケージ(ここでは、hogeのサブパッケージhoge-docsとする)のための、 データ定義部(%package docsではじまり、GroupやSummary、%description docsなどを書く部分)と、 そのサブパッケージにいれるファイルを列挙した%files docs から始まるファイルリストを付け加えます。 具体例は、RPM-BUILD-HOWTOにもありますので、興味のある人はそちらを参照してください。 ただし、次節でものべるように、 サブパッケージの作成は必要最小限にとどめるよう心掛けましょう。 rpmパッケージをつくるときの注意 重要: シンボリック・リンク等を%postとかで張らない。 間違えてもそれ(%postではったリンクなど)を%preunや%postunで削除してはいけない。 シンボリック・リンクを含む全てのファイルを%installまででインストールして、 %filesに加えるべきである。(詳しくは後述) 重要: むやみに Epoch を使わない。 Epoch については説明しませんが、 パッケージのバージョン管理に混乱を引き起こす場合があるので、 絶対に必要という場合以外は利用しないでください。 なお、Serial は rpm 4.4 で obsolete となっています。 あまり細かくサブパッケージに分けない サブパッケージの作り方を覚えると、やたら沢山のサブパッケージをつくる人がいるが、 アップグレード時のメンテ(rpm -Uやspecの書き直し)が面倒になるばかりか、 どれがなんだか分からなくなったりする。分割は必要最小限に。 %configは乱用しない %configを多くすると、%filesが非常にわかりづらくなることがあり、 version up等の時にこの部分のメンテに労力がかかるようになりよくない。 デフォルトのままで出来るだけ多くの人が利用できるようなconfigファイルを用意し、 ユーザの%configの設定は必要最小限ですむように心掛けると、 多くの人が利用しやすいものができ、多くの場合に%fileの記述もすっきりする。 patchを使いすぎない configファイルの設定やMakefileなどを変えたりするために頑張ってpatchをいろいろつくるよりも、 別にファイルを用意してSourceに加えておき、%installあたりで %{__cp} ${RPM_SOURCE_DIR}/hoge.conf . とかしてしまったほうが、すっきりすることが多い。srpmをばらしても、 そのファイルがすぐ出てきてわかりやすく、 アップデートのためにspec修正するときも楽だったりする。 specファイルはわかりやすく。第三者にもわかるようコメントを入れて。 specファイルはソースのアップデートに対応して修正をしたり、 第三者が見て必要に応じて書き直したりすることがある。 凝っていろいろな設定をしたりする複雑なものを書くより、 ポータビリティを重視して簡潔に書いた方が後のメンテのためには吉。また、 違った環境でbuildができなくなるようなことが無いよう、 specファイル中のスクリプトで、特殊なコマンドを呼ぶようなことは避け、 一般的なコマンド使用にとどめるべき。 注意1は特に重要です。よく、%post で、シンボリック・リンクをはって、 %preun でそのリンクを削除するようなspecファイルがあります。 これを行うと、アップデート時に問題が生じることがあります。以前、 libcのパッケージでこういう記述が入ってるものがあって、 深刻な問題が生じたこともありました。 その理由は、rpm -U <new-rpm> としたときに、 rpm -e <old-rpm> rpm -i <new-rpm> ではなく、 rpm -i <new-rpm> rpm -e <old-rpm> とはたらくためです。 つまり、%post で、シンボリック・リンクをはって、 %preun でそれを削除するような rpm のバージョンアップをしようと、 rpm -U (アップデート)を実行すると 新しいパッケージのインストールが行なわれ、 %postでシンボリック・リンクがつくられる。 古いパッケージのアンインストールが行なわれる。 このとき、%preunでさっき新しいパッケージが作ったシンボリック・ リンクが削除される。 この仕様は、libcとかのアップグレードの途中でlibcとかがなくなってトラブルが生じるのを避けようとしたためのものと思われます。 実はこの問題は解決法があります。 %pre, %post, %preun, %postunのスクリプト実行時には、スクリプトに対して以下の引数が与えられます。 rpm -iでインストールを行うとき %pre, %postに対して$1=1 rpm -Uでアップデートを行うとき 新しいrpmのインストール時に、 %pre, %postに対して$1=2 古いrpmをアンインストール時に、 %preun, %postunに対して$1=1 rpm -eでアンインストールを行うとき %preun, %postunに対して$1=0 すなわち、はじめてインストールするときには、引数として1がわたされ、 rpm -eでアンインストールするときには0がわたされるわけです。 これを利用すると、 %post if [ $1 = 1]; then echo ``First installation!'' fi %preun if [ $1 = 0]; then echo ``Good bye!'' fi とかできるわけです。 (それでも%postなどでシンボリック・リンクをはったりすると、 出どころ不明のファイルが増えることになります。その他トラブルをさけるため、 できるだけファイルは%filesに加えるようにし、 %postなどに書くスクリプトはできるだけ少なくしましょう) パッケージ作成後に確認すること SPEC ファイルのエンコーディング等を確認する。 $ rpm -qpi hoge.rpm で文字化けしないかどうか、また、バージョンなど、記述した内容にミスが無いか確認する。 $ LANG=C rpm -qpi hoge.rpm として英語での出力でも確認する。 Changelog の記述を確認する。 $ rpm -qp --changelog hoge.rpm | head などで、追記した部分を確認する。 依存関係(Requires)を確認する。 $ rpm -qpR hoge.rpm パッケージがシェルスクリプトのファイルなどを含んでいる場合、その中で利用されるコマンド(もしくはパッケージ)が Requires: で指定されているかを確かめる必要もあります。これは、実際にシェルスクリプトを実行するなどして確かめる必要があります。 build 時の依存関係(BuildRequires)を確認する。 できあがった src.rpm を、BuildRequires で指定していない devel などのパッケージをアンインストールした状態で rebuild してみる。 *-devel というパッケージをアンインストールするのに、筆者は(bash で)次のようなコマンド(for文)を利用しています。sed や awk で処理してる部分はもう少し上手なやり方があるかもしれません。 # for i in `rpm -qa --last |grep devel |\ sed s/devel-/"devel "/ |awk '{print $1}'` ; do echo $i ; rpm -q $i && rpm -e $i ; rpm -q $i && apt-get remove $i ; done ローカルに apt のリポジトリを作成しておくと、apt-get install や apt-get build-dep で、依存関係のチェック等が行えて便利です。 Vine Linux で使用できるGroup一覧 /usr/share/doc/rpm-*/GROUPS_for_vine.txt に記述されています。 Applications/Accessories Applications/Administration Applications/Archiving Applications/Development Applications/Documentation Applications/Editors Applications/Editors/Emacs Applications/Edutainment Applications/Games Applications/Graphics Applications/Internet Applications/Multimedia Applications/Other Applications/Productivity Applications/Publishing Applications/Services Applications/System Applications/Text Development/Languages Development/Libraries Development/Tools System Environment/Base System Environment/Daemons System Environment/Kernel System Environment/Libraries System Environment/Shells User Interface/Desktops User Interface/X それぞれの Group の簡単な説明です。 /usr/share/doc/rpm-*/GROUPS-DESC_for_vine.txt に記述されています。 Applications/Accessories ちょっとした小物や単機能のシンプルなアプリケーション 例) 電卓、辞書等 Applications/Administration システムやデスクトップの設定、管理の為のアプリケーション (動作に root 権限が必要) 例) synaptic、gnome-system-tools 等 Applications/Archiving ファイルの圧縮や解凍、書庫(アーカイブ)の作成に使用する アプリケーション 例) bzip2, cpio, file-roller 等 Applications/Development アプリケーションの開発に使用するアプリケーション 例) xxgdb、IDE 等 Applications/Documentation ドキュメントのみのパッケージ 例)Vine-manual、JF 等 Applications/Editors テキストエディタ 例) GEdit、Emacs、Vi 等 Applications/Editors/Emacs Emacs 及び Emacs 用のアプリケーション Applications/Edutainment 教育あるいは科学に関連したアプリケーション 例) gnuplot、dia 等 Applications/Games ゲーム Applications/Graphics 画像を扱うアプリケーション 例) GIMP、Inkscape 等 Applications/Internet インターネットを利用するアプリケーション 例) firefox、Sylpheed、gFTP 等 Applications/Multimedia 動画や音楽を扱うアプリケーション 例) Totem、BMP 、XMMS 等。 Applications/Other Applications の他のどの Group にも割り当てられないもの Applications/Productivity ワープロや表計算、PIM等のアプリケーション 例) abiword、Gnumeric 等 Applications/Publishing 印刷やフォントに関連したアプリケーション 例) ghostscript, tetex 等 Applications/Services ウェブサーバーやメールサーバー及び各種 Daemon 例) Apache、Postfix 等 Applications/System システムを設定したり監視したりするアプリケーション 例)gnome-system-monitor、mtools 等 (ユーザー権限で動作可能) Applications/Text テキストの処理に使用するアプリケーション 例) less, nkf, namazu 等 Development/Libraries 開発に必要なヘッダファイル等を含むパッケージ 例) *-devel Development/Languages 開発に使用する各種言語用のパッケージ 例) perl、php、ruby 等 Development/Tools 開発に必要な各種 Tool を含むパッケージ 例) automake、gettext 等 System Environment/Base システムの動作に必要な最小構成のパッケージ ※(インストーラでいうところの最小構成に該当) System Environment/Daemons システムの動作で必要なサービス及びデーモン 例) dbus、hal 等 System Enviroment/Kernel カーネル System Environment/Libraries システムの動作に必要な各種ライブラリ 例) gtk2、libpng 等 System Environment/Shells 各種シェル User Interface/Desktops デスクトップ環境やウィンドウマネージャのアプリケーション 例) KDE、Xfce 、Fluxbox 等 User Interface/X XOrgと、それに付属するパッケージApplications/Accessories パッケージ固有の作法等について 目次 GNOME,KDE,Xfce のメニューに追加するために Emacs Lisp のパッケージ alternatives を利用するパッケージ GNOME,KDE,Xfce のメニューに追加するために GNOME,KDE,Xfce のメニューに追加するためには、ディレクトリ/usr/share/applicationsアプリケーションの名前.desktop というファイル(以降 desktopファイルと呼びます)をインストールする必要があります。 desktopファイルを取り扱う desktop-file-installコマンド、desktop-file-validateコマンド、update-desktop-databaseコマンドは、desktop-file-utilsというパッケージに含まれています。 desktopファイルの扱いは次のような手順になります。 %installタグの部分で次のようにして desktopファイルを%{buildroot}/%{_datadir}/applicationsにインストールしておきます。 %install %{__mkdir_p} %{buildroot}/%{_datadir}/applications %{_bindir}/desktop-file-install --dir=%{buildroot}/%{_datadir}/applications hoge.desktop %checkタグの部分で次のようにして desktopファイルが書式にしたがって正しく書かれているかをチェックします。 %check %{_bindir}/desktop-file-validate %{buildroot}/%{_datadir}/applications/hoge.desktop ソースから make する、make install するなどの部分ではこのチェックが行われないことも多いので、%checkタグの部分でチェックを行うようにしておきます。 desktop-file-validateコマンドは複数のファイルをまとめて処理できないので、*.desktop のようにはできません。desktopファイルの数だけ、コマンドを書いてください。もちろん、for文などを使ってもかまいません。 %postタグや%postunタグの部分で %post if [ -x %{_bindir}/update-desktop-database ] ; then %{_bindir}/update-desktop-database %{_datadir}/applications fi %postun if [ -x %{_bindir}/update-desktop-database ] ; then %{_bindir}/update-desktop-database %{_datadir}/applications fi のように処理します。 update-desktop-database コマンドがインストールされていなければ実行しない、という形にすることで、twm や icewm や WindowMaker など、GNOME等のメニューとは直接関係ないウィンドウマネージャを使用しているときに、deskto-file-utils に依存せずにすむようになります。 他のファイルと同じように %filesの部分に入れておきます。 %files %{_datadir}/applications/hoge.desktop BuildRequires で desktop-file-utils を指定します。 BuildRequires(install,check): desktop-file-utils Emacs Lisp のパッケージ Emacsen には emacsen-common というパッケージがあり、 インストールされている Emacsen の FLAVOR の情報や、 FLAVOR ごとに、その FLAVOR で byte compile された Emacs Lisp パッケージのリストを管理するという仕組みがあります。 この仕組みを用いることで以下のようなことが可能となっています。 パッケージのインストール時に、すでにインストールされている Emacsen の FLAVOR ごとにそれぞれ byte compile して elc ファイルを作成する。 パッケージのアンインストール時に、すべての FLAVOR からパッケージの elc ファイルを削除する。 Emacsen の FLAVOR のインストール時、アンインストール時に、その FLAVOR で byte compile する、FLAVOR で byte compile した elc を削除する。 この仕組みを利用するために、Emacs Lisp のパッケージでは以下のようなことをしておきます。 %installタグの部分では byte compile していない el ファイルを %{_datadir}/emacs/site-lisp/%{name} 以下にインストールします。 Source2 や Source3 などに byte-compile と install を行うためのスクリプトAと、 byte-compile してできた elc ファイルを削除するためのスクリプトBを用意します。 インストールに使える Makefile 等がある場合は %installタグの部分で %{_datadir}/emacs/site-lisp/%{name} 以下に Makefile 等をインストールしておき、 スクリプトの中から利用できるようにします。 install 用のスクリプトAでは、 Emacsen の FLAVOR に応じて %{_datadir}/FLAVOR/site-list/%{name}/ 以下に bytecompile した elc ファイルをインストールするようにします。 uninstall 用のスクリプトBでは、 Emacsen の FLAVOR に応じてスクリプトAでインストールした elc ファイルを削除するようにしておきます。 %installタグの部分で次のようにして、スクリプトAとスクリプトBをインストールします。 %_installemacsenscript %{name} %{SOURCE2} %_removeemacsenscript %{name} %{SOURCE3} スクリプトA,B はそれぞれ /usr/lib/emacsen-common/packages/install/ , /usr/lib/emacsen-common/packages/remove/ に、 %{name} という名前でインストールされます。 これによって、スクリプトA,B は、Emacs の FLAVOR がインストール、アンインストールされた時に実行されるようになります。 %files の部分でそれぞれのスクリプトを記述しておきます。 %{_libdir}/emacsen-common/packages/install/%{name} %{_libdir}/emacsen-common/packages/remove/%{name} %postタグの部分は次のように記述しておきます。 if [ "$1" = 数字 ]; then ; fi は、インストール時、アップグレード時、アンインストール時、それぞれで違う動作をさせるためのものです。を参照してください。 %post # # bytecompile and install # if [ "$1" = 2 ]; then %_emacsenPackageRemove %{name} fi %_addemacsenlist %{name} %_emacsenPackageInstall %{name} %preun if [ "$1" = 0 ]; then %_emacsenPackageRemove %{name} %_removeemacsenlist %{name} fi %_emacsenPackageInstall と %_emacsenPackageRemove は スクリプトA,B を実行するためのマクロです。 %_addemacsenlist と %_removeemacsenlist は、インストール済み Emacs Lisp パッケージのリストにパッケージを登録する、削除するというマクロです。 %_installemacsenscript, %_removeemacsenscript, %_emacsenPackageRemove, %_addemacsenlist, %_removeemacsenlist の行の次の行は、空行にしておかないとエラーとなるようです。 alternatives を利用するパッケージ alternatives については update-alternatives による標準コマンドの切り替え にまとめられています。 alternatives に登録する場合には %post と %preun で次のようにします。 %post if [ "$1" = "1" ]; then %{_syssbindir}/update-alternatives --install リンク名 総称名 選択候補 優先度 fi %preun if [ "$1" = "0" ]; then %{_syssbindir}/update-alternatives --remove 総称名 選択候補 fi Provides と Requires を指定します。 Provides: 総称名 リンク名 Requires: update-alternatives Requires(post,preun): %{_syssbindir}/update-alternatives とします。 Provides の リンク名 については、無くても問題はありませんが、%files には書かれないファイルなので、Provides に書いておいたほうがよいと思います。 %post での登録と %preun での削除は、インストール時とアンインストール時だけに必要で、アップグレード時に実行してしまうと問題があるので、"$1" が 1 の場合(インストール時)と 0 の場合(アンインストール時)だけ処理するように if 文 にしておきます。 %post での処理を、パッケージのアップグレード時にも行ってしまうと、パッケージのインストール後にユーザが優先度を変更していた場合、それを無視してパッケージ側で優先度を勝手に変更してしまうことになります。 新規パッケージではなく、既存のパッケージの %post,%preun に update-alternatives の処理を追加する場合には、次のようにするとよいかもしれません。 %post if [ "$1" = "1" ]; then if [ "`%{_sysbindir/update-alternatives --list '総称名' | grep -c 'リンク名'`" = "0" ]; then %{_syssbindir}/update-alternatives --install リンク名 総称名 選択候補 優先度 fi fi %preun if [ "$1" = "0" ]; then %{_syssbindir}/update-alternatives --remove 総称名 選択候補 fi %triggerin と %triggerpreun と %preun を用いることで、他のパッケージが持っているファイルを alternatives で登録するようなパッケージを作ることもできます。 Provides: 総称名 リンク名 Requires: update-alternatives Requires(preun,triggerin,triggerpreun): %{_syssbindir}/update-alternatives %preun if [ "$1" = "0" ]; then %{_syssbindir}/update-alternatives --remove-all 総称名 fi %triggerin -- 対象となるパッケージ if [ "$1" = "1" ]; then echo triggerin scriptlet by %{name} start %{_syssbindir}/update-alternatives --install リンク名 総称名 選択候補 優先度 echo triggerin scriptlet by %{name} end fi %triggerpreun -- 対象となるパッケージ if [ "$1" = "0" ]; then echo triggerpreun scriptlet by %{name} start %{_syssbindir}/update-alternatives --remove 総称名 選択候補 echo triggerin scriptlet by %{name} end fi