wiki:docs/making-rpm/make-spec

Version 1 (modified by yasumichi, 11 years ago) (diff)

--

Vine Linux ドキュメント / RPM パッケージの作成方法 / SPEC ファイルの記述

SPEC ファイルの記述

パッケージ作成の肝となる SPEC ファイルの記述について説明します。

SPEC ファイルの内容は、以下の主要部分に分類できます。

  • パッケージ情報
  • パッケージの作成やインストール等の手順(スクリプト部)
  • インストールされるファイルの一覧
  • パッケージの変更履歴

SPEC ファイルの文字コード

SPEC ファイルの文字コードは UTF-8 にしてください。

マクロの定義

SPECファイルの冒頭にパッケージのバージョンなど頻繁に使用されるものをマクロとして定義しておくと後々の修正が楽になります。

%define macro   literal

ようにするとパッケージ作成時に %{macro} と書かれた部分を literal に置換して処理します。

標準で定義されているマクロも参照して下さい。

パッケージ情報の記述

rpmコマンドでパッケージに関する問い合わせを実行した場合に表示される情報やパッケージの依存情報などを記述します。

以下にパッケージ情報の記述例を示します。(# を記述すると # から行末までがコメントとして扱われます。)

# 基本情報
Summary: hoge is a harehare horehore
Summary(ja): hoge は harehare な horehore です。
Name: hoge
Version: 1.1
Release: 1%{?_dist_release}
License: GPL2
Group: Applications/Internet
URL: http://www.fugahogo.com/hogehoge.html
Vendor: Project Vine
Distribution: Vine Linux
Packager: yourid,otherid

# パッケージの作成時に必要となる情報
Source: %{name}-%{version}.tar.gz
Patch: hoge.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-root

# 依存情報
Requires:       piyo
BuildRequires:  piyo-devel

# 詳しい解説
%description
Hoge is a harehare horehore and convenient for fugafuga.
Enjoy!

%description -l ja
hoge は harehare な horehore で、fugafuga するときなどとても便利なツー
ルです。みんなでなかよく使いましょう。

基本情報から依存情報の部分は、1行につき1つの情報を記述する構成となっています。

各行は「Summary:」のようにタグとそれに続くコロンで始まり、さらにタグに対応する情報が続く形式になっています。

基本情報

パッケージ情報の問い合わせ時に表示される情報

下記の情報は、rpm -qi などでパッケージに関して問い合わせを行った場合に表示されます。

タグ 内容
Summary パッケージの簡単な説明を英語で記述します。
Summary(ja) Summaryを日本語で翻訳します。
Name パッケージの名前です。定義以降、%{name} というマクロで参照できます。
Version パッケージのバージョンです。定義以降、%{version} というマクロで参照できます。
Release 冒頭の数字は同じバージョンで何回目のリリースになるかを意味します。%{?_dist_release} は、vl7 の様に対象となる Vine Linuxのバージョンに置き換えられます。定義以降、%{release} というマクロで参照できます。
License アプリケーションのライセンス
Group アプリケーションの種類。Vine Linux で使用できる Group 一覧を参照してください。
Packager パッケージメンテナ。http://trac.vinelinux.org/ へのログインユーザ名を使用してください。複数のメンテナがいる場合、カンマで区切ります。
Distribution VinePlusやVineSeedのパッケージは、Vine Linuxを指定します。
Vendor 作成した rpm パッケージに関する責任を負う Vendor 名です。VinePlusVineSeed のパッケージは、Project Vine を指定します。
Url アプリケーションの情報を提供している URL

パッケージ作成時に必要となるタグ

タグ 内容
Source パッケージ化するアプリケーションのソースファイル名。ソースの入手先を明示するために URL 形式で記述することも可能。
Patch パッチの用意で用意したパッチファイルを指定します。書式は Source と同じです。
BuildRoot 仮想インストールのためのディレクトリ名を書きます。直接ディレクトリ名を書くのではなく、例のようにマクロを利用してください。

複数のソースファイルやパッチがあるときは Source0、Source1、... や Patch0、Patch1、... というふうに番号をふって列挙します。(Source0 は、Source と省略できます。)

Souce数字 で指定したファイルは %{SOURCE数字} というマクロとしてスクリプト部の %prep や %install などの部分で利用できます。

依存情報

パッケージの依存情報など他のパッケージとの関係を示すには、以下のようなタグを使用します。

タグ 内容
Requires 作成している RPM パッケージが動作するのに必要なパッケージ名
BuildRequires パッケージの作成時に必要となるパッケージ名
Conflicts 共存できないパッケージ名
Provides 作成するパッケージが他のパッケージの代替となる場合、そのパッケージ名を記述
Obsoletes パッケージをインストールする際にアンインストールしたいパッケージ名
BuildConflicts パッケージ作成時にはインストールしておけないパッケージ名

<, >, =, >=, <= といった演算子を使うとパッケージのバージョン、リリース番号を限定することもできます。

複数のパッケージが関係する場合は、カンマ(,)やスペースで区切って列挙したり、複数行に分けて記述できます。複数行に分ける場合は、各行にタグが必要です。

パッケージがいくつかのグループに分類できる場合には、複数行に書いた方がわかりやすくなります。

例: ghostscriptのバージョン5.10がパッケージの動作に必要な場合
Requires: ghostscript = 5.10
例: gtk2-develのバージョン2.16.0以上がパッケージの作成に必要な場合
BuildRequires: gtk2-devel >= 2.16.0
演算子の両側には必ずスペースやタブを入れてください。

演算子の両側にスペースやタブを入れない場合、パッケージ名からバージョンまでが一つのパッケージ名として認識されてしまいます

例えば、

BuildRequires: gtk2-devel>=2.16.0

とすると「gtk2-devel>=2.16.0」というパッケージ名だと認識してしまいます。

例: 一行で記述する例
Requires: ghostscript >= 5.10, ghostscript-fonts, VFlib = 2.24, tetex, tetex-extra
例: 複数行に分けて記述する例
Requires: ghostscript >= 5.10, ghostscript-fonts, VFlib = 2.24
Requires: tetex, tetex-extra

詳しい解説

Summaryよりも詳しいパッケージの解説を

%description

の次の行から、英語で記述します。

Summary タグの場合と違い、複数行にわたる解説を書くことができます。

なお、日本語による翻訳を追加する場合は、

%description -l ja

として、同様に記述できます。

スクリプト部

スクリプト部では、パッケージの作成やインストール等の手順を記述します。

# スクリプト部
%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

スクリプト部は、下の表で示すセクションに分かれます。

セクション名 概要
%prep ソースをビルドする前に実施する準備事項
%build ソースのビルド手順
%install ソースからのインストール手順
%check インストールが正しく実行されたかを検査する手順
%clean パッケージ作成後の後始末
その他 パッケージのインストール等の前後に実行する手順(「スクリプト部で使用できるその他のセクション」参照)

各セクションは、独立したbashスクリプトとして実行できるように記述します。

rpmbuild時の内部の仕組み

各セクション名が現れた時に #!/bin/sh -e が起動され(Vine Linux では /bin/sh は /bin/bash にシンボリックリンクされている)、 各環境変数(RPM_SOURCE_DIR や RPM_PACKAGE_NAME など)が定義された後、 次のセクション名が出てくるまで、記述されているスクリプトが実行されます。

環境変数の詳細については、環境変数を参照してください。

%prepセクション

ソースをビルドする前に実施する準備事項をシェルスクリプトで記述します。

以下で説明する %setup, %patch などのマクロを用いて、ソースの展開やパッチの適用などを行います。

なお、このセクションの最初で

rm -rf ${RPM_BUILD_ROOT}

として、 ${RPM_BUILD_ROOT} (パッケージ情報の記述BuildRoot? で指定したディレクトリ) を掃除することが多いです。ただし、このときには、BuildRoot? の設定には十分気をつけて下さい(何故かわかりますね?)

%setup
tarでアーカイブされ、 gzipまたはbzip2圧縮されたソースを展開します。%setup とオプションなしで書くと、以下が順に行われます。
  1. ~/rpm/BUILD に cd する。
  2. 指定ディレクトリ(-nで指定できる。デフォルトのディレクトリ名は、 ${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}、後述) がカレント・ディレクトリ(BUILD)に存在すれば消去する。
  3. Source で指定したソースのアーカイブを展開する。
  4. 指定ディレクトリ(2の指定ディレクトリ名と同じ)にcdする。 %setupの動作を制御する必要がある場合は、%setupマクロの詳細を参照してください。
%patch
%setup で展開したソースにパッチをあてるためのマクロとしてはたらきます。 オプションなしで%patchと書くと、
patch -p0 -s < ${RPM_SOURCE_DIR}/<Patchで指定したファイル>
が起動されます。 スクリプト部の冒頭の例のように書くと、
patch -p1 -s < ${RPM_SOURCE_DIR}/<Patchで指定したファイル>
と同じことをします。 パッチファイルが複数ある場合、Patch0, Patch1,...に対して、
%patch0 -p1
%patch1 -p1
と実行することも出来ます。%patchには -b <name> (バックアップ・ファイルの拡張子指定、デフォルトは .orig)などのオプションがあります。

%buildセクション

ソースを make するスクリプトの開始であることを示し、また、%setup で指定したディレクトリに cd するマクロとしてはたらきます。 以下には、make を行うときの手順をスクリプトとして書きます。

ここでの処理で必要となるパッケージ等は、BuildRequires(build): で指定します。

ソースにconfigureスクリプトが用意されている場合

autoconf 化されたソースなど make の前に

$ configure --prefix=/usr

などとしてインストールするディレクトリなどを制御できるソースがあります。

configure スクリプトが用意されている場合には、%configure マクロを利用すると便利です。

%configure マクロは、/usr/lib/rpm/macros で次のように定義されており、 Vine Linux 推奨のコンパイルフラグやインストールディレクトリを設定できます。

%configure \
  CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ; \
  CXXFLAGS="${CXXFLAGS:-%optflags}" ; export CXXFLAGS ; \
  FFLAGS="${FFLAGS:-%optflags}" ; export FFLAGS ; \
  ./configure --host=%{_host} --build=%{_build} \\\
        --target=%{_target_platform} \\\
        --program-prefix=%{?_program_prefix} \\\
        --prefix=%{_prefix} \\\
        --exec-prefix=%{_exec_prefix} \\\
        --bindir=%{_bindir} \\\
        --sbindir=%{_sbindir} \\\
        --sysconfdir=%{_sysconfdir} \\\
        --datadir=%{_datadir} \\\
        --includedir=%{_includedir} \\\
        --libdir=%{_libdir} \\\
        --libexecdir=%{_libexecdir} \\\
        --localstatedir=%{_localstatedir} \\\
        --sharedstatedir=%{_sharedstatedir} \\\
        --mandir=%{_mandir} \\\
        --infodir=%{_infodir}

ここで定義されていないオプション、例えば --disable-scrollkeeper というようなオプションが必要な場合には

%configure --disable-scroolkeeper

のように追加でオプションを指定できます。

%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): で指定します。

ファイルリスト部

%files はじまる部分で、RPM パッケージに収録するファイル名を列挙します。

# ファイルリスト部
%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

このとき以下に注意してください。

rpmbuild コマンドは、SPEC ファイルに基づいて RPM パッケージを作るときに、スクリプト部で設定した一連のスクリプトを実行した後、 ${RPM_BUILD_ROOT} を / とみなして %files 以下で指定されたファイルを回収し、それを指定位置に install するような RPM パッケージをつくります。

ドキュメント・ファイルの指定

%doc というマクロを用います。上記の例のように、%doc README とすると、%setup で指定したホームディレクトリ下の README が、${RPM_BUILD_ROOT}/usr/doc/hoge-1.1-2/ に cp されたのち、RPM パッケージに収録されます。つまり %doc は、ドキュメントファイルのインストールとパッケージングのためのファイル指定を同時に行うマクロとしてはたらきます。以下のように、ディレクトリごと指定もできます。

%doc doc/

パッケージに収録するファイルの指定

その絶対パスで指定します。

  • 個別ファイルはそのまま指定。(/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
とする。
%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 でパッケージを検証する時に、検証する項目を指定する。 ( ) の中には以下の表にあるものが入ります。 複数指定する場合には、, もしくは スペース で区切ります。
項目 内容
size サイズ
mode パーミッションとファイルの種類
md5 md5 値
rdev デバイスファイルのモードビットなど
link リンク先
user ファイルの所有者 user
groupファイルのグループ group
mtimeファイルの更新時刻 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 時のメッセージは必ず確認してください。

パッケージの更新履歴

%changelog 以下にパッケージの更新履歴を英語で記述します。最新の更新情報が上にくるように書きます。

# 更新履歴
%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

一行目の最初に * を書き、日付と変更を加えた人の名前を書きます。二行目以降に - を書き、更新内容を書きます。今日の日付は date コマンドで

$ LANG=C date +'%a %b %d %Y'

とすると確認できます。 12月1日のように日の部分が一桁の場合は 0 をつけ 01 のようにします。

Vine Linux でのパッケージングルールでは 一行目に日付、パッケージャーの名前、メールアドレス、パッケージのバージョン,、リリース番号を書くことになっています。

* 曜日 月 日 西暦年 パッケージャーの名前 <メールアドレス> バージョン-リリース番号
- 更新内容

更新内容の部分でもマクロは展開され %{name} は hoge になります。 マクロを展開せずにそのまま %{name} と書きたい場合は %%{name} のように % を二つ続けて書いて下さい。

日本語を使うことも可能になっていますが、Summary や description のように環境変数に応じて日本語や英語のどちらかを表示するという仕組みは無いので、 英語だけで書くほうがよいでしょう。