openSUSE:Build Service で複数のディストリビューションのパッケージを扱うための手順

移動先: 案内, 検索

概要

この HOWTO には、 1 つの spec ファイルで複数のディストリビューションに対応させるためのヒントが記されています。なお、これはパッケージ作成に関する初心者向けのガイドではありません。初心者向けの文書をご希望の場合は、 Build Service チュートリアル をお読みください。また、本 HOWTO では Debian 形式のパッケージ に関しては言及していません。

Build Service は openSUSE 向けの信頼に足る RPM パッケージを作成するだけでなく、 SLES, CentOS, Fedora, RedHat Enterprise Linux, Ubuntu, Debian, Mandriva/Mageia などのディストリビューションに対応するパッケージを作成することができます。

制限事項について SUSE 系のディストリビューションでは、他の Build Service プロジェクトとリンクしたり統合したりすることで、簡単に依存関係を解決できるのに、 Fedora や Mandriva では解決が容易ではない場合があります。たとえば Qt4 や GTK2 の最新バージョンを必要とするパッケージを構築する場合、 SUSE や SLES では古いバージョンに対しても新しい Qt4 がバックポート (旧バージョン対応) されているため、対応する Build Service を利用することで容易に構築することができますが、それ以外のディストリビューションには用意されていないことが多く、それぞれ必要なものを独自に構築しなければならない場合があります。もちろんこれは、できる限り多くのディストリビューションに対応したい場合にのみ、発生する問題です。

複数のディストリビューションに対応するにあたって、注意しておかなければならないポイントは下記のとおりです:

  • デスクトップファイルをインストールする際には、それぞれのディストリビューションで異なるインストール形態やメニュー項目の作成手法などがありますので、それぞれの方式に合わせて設定してください。たとえば Mandriva の場合、 Debian のようなセットアップで特殊な RPM マクロである %update_menus を利用することで、メニューの更新を行なうことができます。これは SUSE や Fedora とは異なる方式です。たとえば下記のようになります:
%post
%update_menus

%postun
%clean_menus
  • Package naming for dependencies. See below for more specific hints and tricks to make this work in your spec file.
  • 依存関係を指定する際に使用するパッケージ名が、ディストリビューションによって異なる場合があります。下記の章では、 spec ファイル内でこれを解決する際の各種ヒントを示しています。

複数プラットフォーム対応のパッケージを作成する際の例

Amilcar 氏の KDevelop パッケージ をご覧になるとよいでしょう。

ディストリビューション固有の構築手順を設定する

たとえば SUSE 系のディストリビューションの場合、下記のコードを追加することで固有の構築手順を設定することができます:

%if %{defined suse_version}
%if %{undefined suse_version}

よりわかりやすくしたい場合は、下記のように記述することもできます:

%if 0%{?suse_version}
  <SUSE 固有の構築手順>
%else
  <その他のディストリビューションでの構築手順>
%endif

上記のようにすると、 SUSE の構築時とそれ以外のディストリビューションの構築時で、手順を分けることができるようになります。なお、同様の条件分岐を複数並べたい場合は、 '%elseif' をお使いください。また、 Fedora では "_version" を付けない "%{fedora}" を使用します。 SUSE のバージョンごとに手順を分けたい場合は、下記のようにしてください:

%if 0%{?suse_version} > 1130

上記のようにすると、 SUSE Linux 11.3 以降のバージョンだけで処理するものを記述することができます。同様のチェックが他のディストリビューションにもあります:

%if %{defined fedora}
%if %{defined mdkversion}
%if 0%{?fedora} < 5
%if 0%{?mdkversion} > 2006

なお、 RPM では

=>

よりも

>= 

のほうが好まれます。

特定のバージョンだけを除外したいような場合は、下記のようにします:

%if 0%{?rhel_version} != 406

複数のディストリビューションを一括で指定したいような場合は、下記のようにします:

%if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos_version}
 <yourstuff>
%endif

複数の条件を複数の行に分けて記述することもできます:

# mono は SUSE のバージョン 10 以降にしか用意されていないため
%if 0%{?suse_version}
%if 0%{?suse_version} >= 1010
BuildRequires:  mono-core
%endif
%endif

もう 1 つの方法としては、括弧を使用する方法もあります:

# mono は SUSE のバージョン 10 以降にしか用意されていないため
%if 0%{?suse_version} && ( 0%{?suse_version} == 0 || 0%{?suse_version} >= 1010 )
BuildRequires:  mono-core
%endif

なお括弧による指定は、 Fedora や RHEL, CentOS など、古い RHEL ベースのディストリビューションではうまく動作しないことに注意してください。 RHEL-5 もしくはそれ以降のバージョンをベースにしたものであれば、括弧を使用することができます。 古いバージョンの場合は、条件を区切って入れ子にしてください。

このほか、下記のようにしてアーキテクチャを選択することもできます:

%if 0%{?suse_version} == 1310
%ifarch x86_64
 <yourstuff>
%endif
%endif

警告: 下記のバージョン指定は、ディストリビューションの新しいバージョンが公開されるたびに追加されることに注意してください。最新バージョンを確認するには、それぞれのプロジェクトのページに移動して設定ファイルをご確認ください。たとえば RedHat 5 であれば、 https://build.opensuse.org/project/prjconf?project=RedHat%3ARHEL-5 にアクセスして "%rhel_version 505" の行を確認してください。また、新しくバージョンが追加された場合は、この内容も更新しておいてください。

Note: "sles_version" マクロは SLE 12 では 設定されなくなった ことにもご注意ください。


openSUSE:Leap_への貢献方法#RPM_Distro_Version_Macros には、 openSUSE/SUSE で正しい設定を選ぶための方法を示しています。

下記に (非 SUSE 系を含む) バージョンを判別するための記述を示します:

ディストリビューション 記述 コメント
openSUSE Tumbleweed  %if 0%{?suse_version} > 1500 将来のリリース向け (随時変更されます)
openSUSE Leap 15.2  %if 0%{?sle_version} == 150200 && 0%{?is_opensuse}
openSUSE Leap 15.1  %if 0%{?sle_version} == 150100 && 0%{?is_opensuse}
openSUSE Leap 15.0  %if 0%{?sle_version} == 150000 && 0%{?is_opensuse} Backports:SLE-15 と同じです'
openSUSE Leap 42.3  %if 0%{?sle_version} == 120300 && 0%{?is_opensuse} "leap_version" は廃止される予定です (後述)
openSUSE Leap 42.2  %if 0%{?sle_version} == 120200 && 0%{?is_opensuse} "leap_version" は廃止される予定です (後述)
openSUSE Leap 42.1  %if 0%{?sle_version} == 120100 && 0%{?is_opensuse}
openSUSE Leap 42.x  %if 0%{?suse_version} == 1315 && 0%{?is_opensuse} 各バージョンの判別方法については上記をご覧ください
openSUSE 13.2  %if 0%{?suse_version} == 1320
openSUSE 13.1  %if 0%{?suse_version} == 1310
openSUSE 12.3  %if 0%{?suse_version} == 1230
openSUSE 12.2  %if 0%{?suse_version} == 1220
openSUSE 12.1  %if 0%{?suse_version} == 1210
openSUSE 11.4  %if 0%{?suse_version} == 1140
openSUSE 11.3  %if 0%{?suse_version} == 1130
openSUSE 11.2  %if 0%{?suse_version} == 1120
openSUSE 11.1  %if 0%{?suse_version} == 1110 SLE11 と同じです*
openSUSE 11.0  %if 0%{?suse_version} == 1100
openSUSE 10.3  %if 0%{?suse_version} == 1030
openSUSE 10.2  %if 0%{?suse_version} == 1020
SUSE Linux 10.1  %if 0%{?suse_version} == 1010 SLE10 と同じです*
SUSE Linux 10.0  %if 0%{?suse_version} == 1000
SUSE Linux 9.3  %if 0%{?suse_version} == 930
Backports:SLE-15  %if 0%{?sle_version} == 150000 && 0%{?is_backports}
Backports:SLE-12-SP5  %if 0%{?sle_version} == 120500 && 0%{?is_backports}
Backports:SLE-12-SP4  %if 0%{?sle_version} == 120400 && 0%{?is_backports}
Backports:SLE-12-SP3  %if 0%{?sle_version} == 120300 && 0%{?is_backports}
Backports:SLE-12-SP2  %if 0%{?sle_version} == 120200 && 0%{?is_backports}
Backports:SLE-12-SP1  %if 0%{?sle_version} == 120100 && 0%{?is_backports}
Backports:SLE-12  %if 0%{?sle_version} == 120000 && 0%{?is_backports}
SLE 12 SP5  %if 0%{?sle_version} == 120500 && !0%{?is_opensuse}
SLE 12 SP4  %if 0%{?sle_version} == 120400 && !0%{?is_opensuse}
SLE 12 SP3  %if 0%{?sle_version} == 120300 && !0%{?is_opensuse}
SLE 12 SP2  %if 0%{?sle_version} == 120200 && !0%{?is_opensuse}
SLE 12 SP1  %if 0%{?sle_version} == 120100 && !0%{?is_opensuse}
SLE 12 GA  %if 0%{?sle_version} == 120000 && !0%{?is_opensuse}
SLE 12  %if 0%{?suse_version} == 1315 && !0%{?is_opensuse} Leap 42 と SLE 12 の両方を含めたい場合は、 "is_opensuse" のテストを外してください
SLE 11  %if 0%{?sles_version} == 11 "suse_version" が 1110 と等しいかどうかをテストしてもかまいません
SLE 10  %if 0%{?sles_version} == 10 "suse_version" が 1010 と等しいかどうかをテストしてもかまいません
SLES 9  %if 0%{?sles_version} == 9 "suse_version" が 910 と等しいかどうかをテストしてもかまいません
CentOS 5  %if 0%{?centos_version} == 505
CentOS 6  %if 0%{?centos_version} == 600
CentOS 7  %if 0%{?centos_version} == 700
RHEL 4  %if 0%{?rhel_version} == 406
RHEL 5  %if 0%{?rhel_version} == 505
RHEL 6  %if 0%{?rhel_version} == 600
RHEL 7  %if 0%{?rhel_version} == 700
Scientific Linux 6  %if 0%{?scientificlinux_version} == 600
Scientific Linux 7  %if 0%{?scientificlinux_version} == 700
Fedora 6 with Extras  %if 0%{?fedora_version} == 6
Fedora 7 with Extras  %if 0%{?fedora_version} == 7
Fedora 8 with Extras  %if 0%{?fedora_version} == 8
Fedora 9 with Extras  %if 0%{?fedora_version} == 9
Fedora 10 with Extras  %if 0%{?fedora_version} == 10
Fedora 11 with Extras  %if 0%{?fedora_version} == 11
Fedora 15  %if 0%{?fedora_version} == 15
Fedora 16  %if 0%{?fedora_version} == 16
Fedora 17  %if 0%{?fedora_version} == 17
Fedora 18  %if 0%{?fedora_version} == 18
Fedora 19  %if 0%{?fedora_version} == 19
Fedora 20  %if 0%{?fedora_version} == 20
Fedora 21  %if 0%{?fedora_version} == 21
Mandriva 2006  %if 0%{?mdkversion} == 2006
Mandriva 2007  %if 0%{?mdkversion} == 2007
Mandriva 2008  %if 0%{?mdkversion} == 2008
Mandriva 2009.0  %if 0%{?mdkversion} == 2009
Mandriva 2009.1  %if 0%{?mdkversion} == 200910
Mandriva 2010.0  %if 0%{?mdkversion} == 201000
Arch Linux  %if 0%{?arch_linux} もちろんプロジェクト設定内でのみ動作します
Debian  %if 0%{?debian} もちろんプロジェクト設定内でのみ動作します

* SLE と区別したい場合は、 0%{?is_opensuse} をお使いください

¹ Leap 15 と Backports:SLE-15 を区別したい場合は、 %if !0%{?is_backports} をお使いください

leap_version マクロ (廃止予定)

"leap_version" マクロは廃止予定とされているもので、 Leap 15.0 からは実際に削除されています。

このマクロは新しく作成する RPM spec ファイル内では使用すべきではありません。代わりに "sle_version" と "is_opensuse" のマクロを組み合わせて指定してください。

下記の表には、各ディストリビューションでの leap_version マクロの値を示しています。

ディストリビューション
openSUSE Leap 42.1 未定義
openSUSE Leap 42.2 420200
openSUSE Leap 42.3 420300
openSUSE Leap 15.0 未定義

サービスパックについては SLES 12 でのみ判別することができます。 SLES 11 SP1 は SLES 11 と同じ変数が設定されます。

Leap/SLES の関係性については、下記もお読みください: openSUSE:Leap_への貢献方法

info ファイルのインストール

info ファイルは %info_add および %info_del の各マクロを利用してインストールする必要があります。たとえば下記のようになります:

%post
%info_add %{name}.info
%preun
%info_del %{name}.info

なお、ディストリビューションによっては info ファイルを .gz や .bz2, .lzma (新しい Mandriva/Mageia) の形式に圧縮する場合があります。ファイルリストでは、 %ext_info マクロを利用することで、ファイルの拡張子を取得することができます。

man ファイルのインストール

ディストリビューションによっては、 man ファイルを .gz や .bz2, .lzma (新しい Mandriva/Mageia) の形式に圧縮する場合があります。 %ext_man マクロを利用することで、ファイルの拡張子を取得することができます。

Megeia や Fedora などで ext_info や ext_man のマクロが定義されていない場合は、下記のようにして prjconf 内で設定してください:

%if 0%{?mageia} == 6
Macros:
%ext_info .xz
%ext_man .xz

:Macros
%endif

%if 0%{?fedora_version} && 0%{?fedora_version} >= 25
Macros:
%ext_info .gz
%ext_man .gz

:Macros
%endif

依存関係の処理

ディストリビューションが異なるとパッケージの名前付けルールも異なることから、 Requires: や BuildRequires: のタグに指定するパッケージの名前も違ってきます。そのような問題に直面した場合は、下記のような置き換え (Substitute) ルールを作成してください:

%if 0%{?fedora_version}
  Substitute: libnetcdf-devel netcdf
%endif

上記のように設定すると、影響する spec ファイルに対して libnetcdf-devel を netcdf に置き換えるようになります。

プロジェクトの設定を変更するには、 osc meta prjconf <プロジェクト名> -e のように実行してください。これにより $EDITOR 環境変数で指定したエディタが起動します。 Web クライアントの場合は、プロジェクトの Advanced セクション内に隠されています。

このような置き換えを build.opensuse.org で使用していて、置き換えルールを他のユーザにも公開したいと考えていらっしゃる (つまり、中央の設定ファイル内に統合してもらいたい) 場合は、 opensuse-buildservice@opensuse.org 宛に英語でご連絡ください。

ディストリビューションに対してすでに設定されている Substitutes: ルールを確認したい場合は、それぞれのディストリビューションに対応したプロジェクトの設定ファイルをお読みください。たとえば CentOS 6 であれば https://build.opensuse.org/project/prjconf?project=CentOS%3ACentOS-6 になります。

Recommends:Suggests:

Suggests は SUSE (>=10) および Fedora (>=24) 固有の機能です。これは "Requires:" をより弱い依存関係を示すものです。

# 必ずしも vim や graphwiz が必要となるプログラムではないが、
# あったほうがより適切であることを示します。
%if 0%{?suse_version} >= 1000
Suggests:       vim graphviz
%endif

Recommends: についても同様です。

update-alternatives パッケージについて

update-alternatives は SUSE 固有のパッケージであり、 Fedora/RHEL では提供されていません。これらのディストリビューションでは、同様の機能が chkconfig パッケージで提供されています。そのため、:

# Requires(post):   update-alternatives
# Requires(postun): update-alternatives


ではなく、下記のようにバイナリのフルパスを記述すると、共通化できます:

Requires(post):   /usr/sbin/update-alternatives
Requires(postun): /usr/sbin/update-alternatives

もう 1 つの方法として、 プロジェクト全体の設定 に追加する方法もあります:

%if ! 0%{?suse_version}
Substitute: update-alternatives chkconfig
%endif

Fedora/RHEL での Qt 3.x の検出

RedHat や Fedora では、 Qt を利用してアプリケーションを構築する際、パッケージの命名ルールや構築設定が他のものとは異なっています。下記は、 Qt ベースのアプリケーションを SUSE と Fedora の両方で、かつ 1 つの spec ファイルで構築する場合の例です:

BuildRequires:  cups cups-devel python-devel shared-mime-info libart_lgpl-devel libtiff-devel libxml2-devel
BuildRequires:  fontconfig-devel openssl-devel pkgconfig desktop-file-utils qt-devel

%if 0%{?fedora} >= 5
BuildRequires:  libstdc++-devel gcc-c++ lcms-devel >= 1.12 qt
%endif

%if 0%{?suse_version} > 910
BuildRequires:  update-desktop-files 
%endif

BuildRequires 以下には下記のように指定します:

%if 0%{?fedora} >= 5
source "%{_sysconfdir}/profile.d/qt.sh"
%endif
%configure \
%if 0%{?fedora} >= 5
--with-xinerama \
--with-extra-libs=%{_libdir} \
%endif
%if 0%{?suse_version} > 910
--with-qt-libraries=/usr/%_lib/qt3/%_lib \
--with-docdir=%{prefix}/share/doc/packages/scribus \
%ifarch x86_64 ppc64 s390x
 --enable-libsuffix=64 \ 
%endif
%endif
<programoptions>

Mandriva での Qt4 の検出

既定では Qt4 よりも前に Qt3 が見つかってしまうため、 spec ファイル内の %build セクションに下記のように指定します:

%build  
 
%if 0%{?mandriva_version} > 2006  
export PATH=/usr/lib/qt4/bin:$PATH  
export QTDIR=%{_prefix}/lib/qt4/  
%endif  
  • Mandriva 2008 以降で変更されているかもしれません

Mandriva での Provides/Obsoletes の取り扱い

CentOS や RHEL, Fedora, SUSE などとは異なり、 Mandriva を取り扱う際は特別に注意する必要があります。これらは対象のライブラリがアプリケーション内でしか使用されないものであっても、アプリケーションとは別にライブラリ用の RPM を作成することが多いためです。一般的なライブラリの取り扱いと同じく、アプリケーション側ではライブラリへの依存関係を設定する (foo -> libfoo) だけですが、他のディストリビューションとは依存関係が異なるため、 Provides や Obsoletes を明示的に指定して、矛盾が起こらないようにする必要があります。 RPM では依存関係を自動的に処理しますが、場合によっては下記のように明示的な指定をしたほうがより便利な場合もあります:

%if 0%{?mandriva_version}
Provides: foo libfoo-0
Obsoletes: foo libfoo-0
%endif

古いディストリビューションの取り扱い

パッケージ内のソースコードは古いディストリビューションにも対応している場合がありますが、パッケージを構築するにあたっては、古いディストリビューションとの互換性確保が面倒になる場合があります。

たとえば autoreconf -fi を呼び出す際 (一般的な spec ファイルではよく用いられます) 、インストールを意味する -i を指定していることから、 tar ボール内に同梱されている config.sub, config.guess, ltmain.sh は、ターゲットとなるディストリビューションの autoconf パッケージが提供するものに置き換えられます。これはつまり、ソースコードが 2007 年に作成されたものであっても、 SLE 10 用に構築する場合は 2005 年のものに置き換えられることになり、うまく動作しなくなってしまう場合がありうることを示しています。これはたとえば、 SLE10 で libapr1 をコンパイルしたいような場合に当てはまります。

このような場合は、 autoheader, autoconf を呼び出すように設定するのが適切 (場合によっては必須となるかもしれません) であるほか、 autoreconf の代わりに必要な処理を記述するように指定するのがよいでしょう。たとえば下記のようになります:

%if 0%{?suse_version} > 1010
  autoreconf -fi
%else
  autoheader
  autoconf
%endif

Debian および xUbuntu のパッケージ

これらのパッケージを作成する際は、 Debian ビルド をお読みください。

CentOS や RHEL EPEL のリポジトリについて

CentOS や RHEL の場合、 EPEL リポジトリを使用する必要があるかもしれません。このような場合は、 Fedora:EPEL:7 にある OBS プロジェクトをお使いください。

Arch Linux でのパッケージ構築

パッケージの作成Arch パッケージガイドライン をお読みください。

ディストリビューションごとの RPM マクロとドキュメンテーション

パッケージングガイドライン

Fedora Packager's Guide (英語)

ROSA's Build RPMs - Quick Start Guide (英語)

Mageia's Packaging for Beginners (英語)