Gentoo Documentation - eclass HOWTO
1. eclassの紹介
eclassはebuildの構成要素です。ebuildや他のeclassに読み込まれ(継承され)、同種のebuild全体に標準設定や関数を提供します。OOPと同じように、同種のebuild間で可能な限りコードの再利用ができるようにしてくれます。
最初のセクションではeclassの書き方を簡単に紹介します。次に既存のeclassを詳しく見ていきます。続いて、KDE関連のeclassを使ってKDE ebuildを書く方法を説明します。
例題
仮想のsourceforge.eclassを定義し、sourceforge.netで管理されているプロジェクトのホームページとダウンロード場所のデフォルトを提供するように設計します。
Code Listing 1.1: E-classの例題 |
# Copyright 2001-2002 Gentoo Technologies, Inc.
# Distributed under the terms of the GNU General Public License, v2 or later
# Author Dan Armak <[email protected]>
# $Header: /var/www/www.gentoo.org/raw_cvs/gentoo/xml/htdocs/doc/ja/eclass-howto.html,v 1.3 2003/07/30 20:41:49 hagi Exp $
# この eclass は $HOMEPAGE と $SRC_URI をsourceforge.net上で管理されているプロジェクトの標準設定に設定します。
# (訳註: ここは説明のため翻訳しましたが、現実のeclassでここに日本語を書いてしまうのはお勧めしません)
ECLASS=base
HOMEPAGE="http://${PN}.sourceforge.net/"
SRC_URI="http://download.sourceforge.net/${PN}/${P}.tar.gz"
|
最初の4行はヘッダで、ほかのebuildにも同様に書かれています。続く2行はeclassの簡単な説明です。7行目はECLASSにeclassの名前をセットしています。この例には出てきませんが、いくつかのアプリケーションで便利です。約束事ですので、これらには従わなければなりません。
残りのコードが実際に動作する部分です。SRC_URIとHOMEPAGEをセットします。
There you go
以上が、eclassを書くために知っておかなければならないこと全部です。作成したeclassを/usr/portage/eclass/に置き、ebuildの先頭に以下に示す行を追加してください:
Code Listing 1.2: eclassの継承の仕方 |
inherit sourceforge
|
複数のeclassを同時に継承するには、次のようにします。
Code Listing 1.3: 複数のeclassの継承 |
inherit eclass1 eclass2 ...
|
この場合は並び順に注意してください。
2. ebuild.shと全体的な構成
inherit()
この関数はeclassの継承(読み込み)を処理します。次のように呼び出されます: inherit
現在、inherit()は単純にあらかじめ指定された場所からファイルを読み込みます。将来、我々がeclassを別の場所に移すことに決めた場合は、eclass名とファイル名の名前の解決をするためのコードがここに入ります。
EXPORT_FUNCTIONS()
foo.eclassとbar.eclassがどちらもsrc_compileを定義していると仮定します。fooとbarの両方を継承した場合、どのような順番でそれらを継承したかによって、有効になるsrc_compileが変わります。この事は問題ではありませんが、利用者が継承順を把握しているということが前提となります。ただし、明示的にどちらのsrc_compileでも呼び出すことができます。
すべてのeclassは定義する関数にプレフィックスを付加します。たとえば、A.eclassはA_src_compile()を、B.eclassはB_src_compile()を定義します。これによって、ebuildはどの関数でも呼び出すことができ、どんな結果が得られるかもわかることになります。
これは新たな問題を引き起こします。明示的にsomething_src_compileを呼び出さなくてもよいように、src_compileとして呼び出すことができる関数が必要です。これを解消するため、EXPORT_FUNCTIONS()が登場します:
Code Listing 2.1: EXPORT_FUNCTIONSの例 |
EXPORT_FUNCTIONS() {
while [ "$1" ]; do
eval "$1() { ${ECLASS}_$1 ; }" > /dev/null
shift
done
}
|
すべてのeclassは最初にECLASSに自分の名前をセットします。それから提供する関数のリストを引数としてEXPORT_FUNCTIONSを呼び出します。
Code Listing 2.2: ECLASSに名前をセットしEXPORT_FUNCTIONSを実行 |
ECLASS=foo
EXPORT_FUNCTIONS src_unpack
|
すると、EXPORT_FUNCTIONSは次のような文字列をeval(訳註:文字列をコードとして評価すること)します。
Code Listing 2.3: EXPORT_FUNCTIONS Eval |
src_unpack() { foo_src_unpack() ; }
|
これで、どちらのeclassが後に継承されてデフォルトのsrc_compileを定義しても、必要ならばどちらの関数もebuildから直接呼び出すことができます。eclassではデフォルトではないsrc_compile()関数を定義することも可能ですが、そうする必要はないでしょう。
関数のセクション
よく出来た定義済関数はしばしばそのまま利用されます。とはいえ、変更(あるいは拡張)することもできます。
一意な名前(foo_src_unpack)がつけば、容易にその関数が実行される前後にコードを追加できます。
Code Listing 2.4: コード実行順 |
src_compile() {
run_my_code
base_src_compile
run_my_other_code
}
|
関数をセクションに分けることによって高い自由度が得られます。関数を分解することで、任意の二つのセクション間にコードを書くことができるようになります。
実装は単純です。題材として、base.eclassからsrc_compile()を取り上げます(base.eclassはもう無くなってしまいましたが、よい例題です)。まずは以下をご覧下さい。
Code Listing 2.5: base.eclassの例 |
base_src_compile() {
./configure || die
emake || die
}
|
同じ関数を二つに分解してみると次のようになります。
Code Listing 2.6: 同じ関数をセクションに分ける |
base_src_compile() {
[ -z "$1" ] && base_src_compile all
while [ "$1" ]; do
case $1 in
configure)
./configure || die;;
make)
emake || die;;
all)
base_src_compile configure make;;
esac
shift
done
}
|
コードはconfigureとmakeの二つのセクションに分解されました。この単純な例では、それぞれ元の関数の二つのコマンドに対応します。
新しい関数の中には while;case...esac;shift;done というコードブロックがあります。この部分で、関数のパラメータと定義されたセクションの名前をマッチングして対応するコードを実行します。
特別なケースとしてallは、セクションを実行順に並べたリストを引数として、同じ関数を再起的に呼び出します。このリストを維持するのはeclassの作者に任されています。
先ほどのコードブロックの前の行は、パラメータなしで呼び出されたときに、allだけをつけて呼び出されたのと同じように扱うためのものです。お分かりのように、この関数には再帰呼び出しが使われています。それでもbase_src_compile configure all make は文法上許されます。この場合はbase_src_compile configure configure make makeが実行されることになります。
base.eclassを継承したebuildでは、base_src_compileをパラメータなしで呼び出すstub関数src_compileが利用できます。これはbase_src_compileをall、つまりすべてのセクションを実行します。これはこのまま利用できます。もし拡張したいのであれば、新しいsrc_compileを定義して、base_src_compileのセクションを適宜呼び出してください。
Code Listing 2.7: 新しいsrc_compileを定義する |
src_compile() {
run_my_code1
base_src_compile configure
run_my_code2
base_src_compile make
run_my_code3
}
|
見てわかるように、関数分解によって自由度が生まれ、二つのセクションの間にコードを書いたり、セクションの順番を変えて実行したり、特定のセクションだけを実行するようにしたりできるようになります。これは全体的に、コードの再利用を促進します。
最後になりますが、allやパラメータなしで呼び出されたときに、すべての関数がそのセクションすべてを実行するわけではないことに注意してください。いくつかのセクションはデフォルトでは実行されず、明示的に呼び出す必要があるかもしれません。そのようなセクションは今のところひとつだけ(base_src_unpack patch)です。
debug-print-* 関数
これらの関数は冗長なデバッグメッセージを出力する機能を提供します。すべてのeclassはこれらの関数を何度も呼び出します。bashスクリプトには私が知る限り(bash -x を除き)デバッガ、IDE、逐次実行などがありませんので、見苦しくはなりますが、追跡をするときに大いに役立ちます。
debug-print()はその引数を、"debug: prefix"に続けて表示します。debug-print-function()は"debug: entering function 1, parameters: 2 3 ....."と表示します。debug-print-section()は"debug: new in section 1."を表示します。
デバッグメッセージは通常 T/eclass-debug.log に出力されます。ECLASS_DEBUG_OUTPUT変数にセットすると(make.conf、ebuild/eclass、あるいは環境変数)、そちらに出力されるようになります。特別な値"on"を設定すると、他のemergeメッセージと一緒に、標準出力に出力させることもできます。
例題の関数に、典型的なデバッグメッセージを出力する文を追加してみましょう。
Code Listing 2.8: デバッグメッセージの追加 |
base_src_compile() {
debug-print function $FUNCNAME $*
[ -z "$1" ] && base_src_compile all
while [ "$1" ]; do
case $1 in
configure)
debug-print-section configure
./configure || die;;
make)
debug-print-section make
make || die;;
all)
debug-print-section all
base_src_compile configure make;;
esac
shift
done
debug-print "$FUNCNAME: result is $RESULT"
}
|
なお、FUNCNAMEはbashの組み込みの機能で、現在実行中の関数の名前を保持しています。
newdepend()
この関数は単純にすべてのパラメータをDEPENDとRDEPENDに追加するものです。二つの依存リストのメンテナンスをする際のトラブルから解放してくれます。
特別なパラメータを指定したときは、あらかじめ定義してある依存関係を追加します。この特別なパラメータには、現在以下のものがあります。
newdepend /autotools: sys-devel/autoconf sys-devel/automake sys-devel/make をDEPENDのみに追加(RDEPENDには追加しない).
newdepend /c: virtual/glibc sys-devel/ld.so をDEPENDとRDEPENDに追加。sys-devel/gccをDEPENDのみに追加。
この関数は累積的なDEPEND文字列のメンテナンスをする開発者を助けます。Especially,
many ebuilds have no RDEPEND strings, which will be a problem once we have unmerge functionality that knows
about dependencies.
3. さまざまなeclass
base.eclass
このeclassはいくつかの変数のデフォルトと関数を定義しています。これらは継承をしないebuildでデフォルトで使える変数や関数と似ています。たとえば、src_unpack() unpack A といったものです。
結局、これは削除され、デフォルトの関数がebuild.shに取り込まれました。
これは、KDEの様に高いレベルのeclassから継承されています。
base_src_unpackにはデフォルトで実行されないセクション(つまり、allを指定しても実行されない)があることに注意してください。それは、patchと呼ばれているセクションで、次のようなものです。
Code Listing 3.1: Patchセクション |
cd ${S}
patch -p0 < ${FILESDIR}/${P}-gentoo.diff
|
base_src_unpackにはひとつ注意を払うべきセクションがあります。それはautopatchセクションです。これはpatchセクションとは違い、展開(unpack)の後デフォルトで実行されます。Sのなかで、パッチレベル0でPATCHES(絶対パス)に指定されたパッチファイルを適用します。これによって、ebuildはsrc_unpackを拡張する変わりに、PATCHES=DISTDIR/foo.diff FILESDIR/bar.patchという行を書けば良いことになります。
cvs.eclass
このeclassはソースをcvsから持ってくることができるようにします。cvs ebuildはまだ正式なものではありませんので、私の作った kde3pre ebuildでしか使われていませんし、ここで詳細を述べることもしません。(訳註: 2002年12月現在では、cvs.eclassを使うebuildがいくつか存在します。)
cvsup.eclass
cvsと同じです。
4. KDE専用eclass
kde.eclass
これがもっとも重要なKDE eclassです。KDEに関連するコードの大部分が含まれます。すべてのKDE ebuildが何らかの方法でこれを継承します。
ほかのeclassと同じように、コードを読んでどのようなことをしているのか理解してください。抜粋して読みやすくしたものを以下に示します。(一部省略しています)
Code Listing 4.1: KDE eclassの改良 |
inherit base kde-functions
ECLASS=kde
newdepend /autotools
HOMEPAGE="http://www.kde.org/" |
上のコードは既に明白でしょう。
kde_src_unpack()はありませんが、base_src_unpack()関数がしっかり機能します。kde_src_compile()を見てみましょう。
Code Listing 4.2 |
kde_src_compile() {
local myconf;
myconf="$myconf --host=${CHOST} --with-x --enable-mitshm --with-xinerama;
case $KDEMAJORVER in
2) myconf="$myconf --prefix=${KDE2DIR}";;
3) myconf="$myconf --prefix=${KDE3DIR}";;
*) echo "!!! $ECLASS: $FUNCNAME: myconf: could not set --prefix based on KDEMAJOVER=\"$KDEMAJORVER\"" && exit 1;;
esac
use qtmt && myconf="$myconf --enable-mt"
[ -n "$DEBUG" ] && myconf="$myconf --enable-debug=full --with-debug" \
|| myconf="$myconf --disable-debug --without-debug"
|
myconf変数はconfigureに渡す引数を保持しています。ここには上書きではなく常に追加されていきますので、自分で作ったebuildでも自由に追加できます。myconfセクションでは、デフォルトの引数をセットします。
セクションの最初の部分は決め打ちの引数をセットします。
次のセクションでは、set-kdedir()でセットされるKDEMAJORVERに基づいてprefixをセットします。(kde-functions.eclassを説明したセクションを見てください)
3番目のセクションでは、USEフラグ(qtmt)とDEBUGを見ながら、引数を追加します。
Code Listing 4.3: More of the CVS eclass |
section configure:
# This can happen with e.g. a cvs snapshot
if [ ! -f "./configure" ]; then
for x in Makefile.cvs admin/Makefile.common; do
if [ -f "$x" ] && [ -z "$makefile" ]; then makefile="$x"; fi
done
emake -f $makefile
[ -f "./configure" ] || die "no configure script found, generation unsuccessful"
fi
export PATH="${KDEDIR}/bin:${PATH}"
./configure ${myconf} || die "died running ./configure, $FUNCNAME:configure"
|
configureセクションはmyconfの引数を使って、実際にconfigureスクリプトを実行します。configureスクリプトを生成する必要がある場合は、最初のセクションはさらにmake -f Makefile.cvsかmake -f admin/Makefile.commonを実行します。
Code Listing 4.4: Make configuration |
section make:
export PATH="${KDEDIR}/bin:${PATH}"
emake || die "died running emake, $FUNCNAME:make" |
このセクションはmakeを実行します。
次のkde_src_installはdodocセクションが追加されていること以外はbase_src_installとそれほど違いません。
Code Listing 4.5 |
kde_src_install() {
section make:
make install DESTDIR=${D} destdir=${D} || die
section dodoc:
dodoc AUTHORS ChangeLog README* COPYING NEWS TODO
}
|
kde-functions.eclass
このeclassにはKDE関連の補助関数が収められています。ebuildから直接呼び出してはいけないものがいくつかありますが、ここでは解説しません。
kdedirの多重化
現在使われている、kdedirを多重化する方法について簡単に説明します。
KDE2,3DIRとKDELIBS2,3DIRはどちらもmake.globalsでセットされ、make.confで上書きしてセットすることができます。デフォルト値は、それぞれ/usr/kde/2,3になります。
自分自身をkde2パッケージ(後の記述を見てください)であると識別したパッケージは、KDELIBS2DIRにあるライブラリを使い、KDE2DIRにインストールします。kde3に対しても同じように動作します。注意: kdelibsをkdeアプリケーションやデフォルトではないKDEDIRを使うアプリケーションはテストされていませんし、サポートもされません。
qtについては、最新の2.xと3.xのバージョンがそれぞれ/usr/qt/2,3に導入されています。
need-kde(), need-qt(), set-kdedir(), set-qtdir()
このeclassは関数のペアを二つ提供します: need-kde(), need-qt() and set-kdedir(), set-qtdir()。これらはqtとkdedirの多重化を実現するための実装です。
need-*関数は要求されるバージョンを引数にして呼び出されます。そこでは必要な依存関係を追加し、set-*dir関数を呼びます。引数が指定されなければ、0(ゼロ)が使われますが、これはすべてのバージョンが依存関係を満たすことを意味します。
set-*dir関数はKDEDIRとQTDIRをセットし、さらにKDEMAJORVER (=2 または =3)をセットします。ebuildから必ず呼ぶ必要があるのは以上のものです。
ここで重要なのは、これらの関数をebuildの関数の中からではなく主要部(訳註:ヘッダの下の部分)から呼び出すということです。そうすることで、DEPENDとRDEPENDに加えた変更がemergeに反映されます。
kde_sandbox_patch()
いくつかのKDE makefileは間違って生成されています。それらは、インストールの際にPREFIX内のファイルに対してchmodやchownを実行しますが、DESTDIR(D)が考慮されていません。このためsandbox(訳註:sandboxはPortageの機能です)がそれをエラーとして検出してしまいます。この関数は、既知の問題を解消するようにmakefileに対してsedを実行します。引数として、その処理をすべきディレクトリを受け取り、そこにあるMakefile, Makefile.in, Makefile.amを処理します。
Code Listing 4.6: Processing |
src_unpack() {
base_src_unpack
kde_sandbox_patch ${S}/dir1 ${S}/dir2/dir3
}
|
kde-base.eclass
標準的なkdeアプリケーション用です。ほとんどすべてのebuildが使っています。kdeを継承し、newdepend /cを実行し、HOMEPAGEにapps.kde.comをセットします。
kde-i18n.eclass
kde-i18n-*パッケージ用です。限定的に使われます。
すべてのkde-i18n ebuildは全く同じですので、しなければならないのは、このeclassを継承することだけです。あとはPが処理してくれます。
koffice-i18n.eclass
koffice-i18n-*パッケージ用です。kde-i18n.eclassとよく似ています。
すべてのkoffice-i18n ebuildは全く同じですので、しなければならないのは、このeclassを継承することだけです。
kde-dist.eclass
kde-base/*にあるコアKDEディストリビューションパッケージ用です。kde-baseとkde.orgを継承します。また、正しいDESCRIPTIONとHOMEPAGEを追加し、need-kde PVを呼び出します。さらに、myconfに--enable-finalを追加します。単純で小さい kde-base/ パッケージ(たとえばkdetoys)はこれを変更する必要はありません。ほとんどは依存関係を追加するだけです。
kde.org.eclass
kde-base/ コアパッケージ用と他のftp.kde.orgやそのミラーで提供されているパッケージ用(kdevelop, koffice, kdoc)です。SRC_URIをセットし、ftp.kde.orgのミラーを追加します。
kde-pre.eclass
これはkde3pre ebuildからのみ、継承されます。ただし、すでにportageからは消えています。
これはプレリリースのebuildで使われます。このような場合、portage名には下線がついています(3.0_beta1)がソースアーカイブにはついていません(3.0beta1.tar.gz)。この下線をSRC_URIとSから取り除きます。
kde-i18n-pre.eclass
上のものと似ていますが、kde-i18nのプレリリース用です。
kde-source.eclass
As above, only available in kde3pre.
これも同じく、kde3preでのみ利用可能です。
kde-base/*コアパッケージ用で、cvsまたはcvsupを使ってソースを取得します。cvs.eclassとcvsup.eclassを利用します。これらの三つのeclassはともに強力で、ebuildはただkde-sourceを継承するだけで、cvsサーバの切替や、cvs checkout/update/offlineモードの切替などが、自動的に働きます。ただし、cvsを使ったebuildはまだありません。
kde-patch.eclass
cvsスナップショットパッチ、たとえば、3.0.1.20020604といったパッケージで使います。何をするものか知るには、eclassを読んでみてください。
5. KDE ebuildsを書く
典型的なKDE ebuild
このhowtoを読んだ後なら、このコードが何をしているのかは明白でしょう。
Code Listing 5.1: 例題 |
<header lines>
inherit kde-base |
いくつかのebuildはここまでで終わりになります。もう少しカスタマイズが必要なものもあります。
依存関係を追加します。*常に*追加してください。決して上書きしないように!
Code Listing 5.2: 依存関係の追加 |
DEPEND="$DEPEND foo/bar"
RDEPEND="$RDEPEND bar/foo"
|
以下はDEPENDとRDEPENDの両方に依存関係を追加します。
Code Listing 5.3: RDEPENDとDEPENDに依存関係を追加 |
newdepend "foo? ( bar )"
|
以下はmyconfに引数を追加します。myconfはconfigureの引数として使われます。
Code Listing 5.4: myconfに引数を追加 |
myconf="$myconf --with-foobar" |
src_unpackを拡張します。
Code Listing 5.5 |
src_unpack() {
base_src_unpack all patch # Patch from ${FILESDIR}/${P}-gentoo.diff
# some more changes
cat foo > ${S}/bar
}
|
KDEをオプションにする典型的なebuild
基本的に、KDE専用の行は use kde を先頭に付加するか、if `use kde` ; then; fiブロックで括るかしてください。
一般的なセクション(訳註:ヘッダの下の部分のこと。関数内に書いてはいけない)には、以下のコードが追加されます(USE kde がセットされている場合)
Code Listing 5.6: 別の例題 |
if [ "`use kde`" ]; then
inherit kde-functions
need-kde $version # minimal version of kde your app needs
fi
|
さらにコードを追加する場合は、次のようにしてください。
Code Listing 5.7: コードを追加する |
use kde && myconf="$myconf --with-my-parameter"
|
KDEを使うアプリケーションに対して、need-kde()を呼び出した後利用可能になるKDEDIRを見るように指示してください。
|