ebuild読み 01

今日は media-libs/libmpeg2/libmpeg2-0.5.1-r1.ebuild を読みます。

# Copyright 1999-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/media-libs/libmpeg2/libmpeg2-0.5.1-r1.ebuild,v 1.7 2011/09/09 18:05:02 scarabeus Exp $

EAPI=4

EAPI 4を使っています。EAPIはebuildで使われる基本ライブラリ(API)みたいなもんですね。いまのところ4が最新になっています。できるだけ4使うといろいろ嬉しいんじゃないかと思います。ただ一部4対応してないeclass(ライブラリみたいなもの)あるので気をつけましょう。

inherit autotools eutils libtool

3つのeclassを継承します。まあ、ライブラリを読みこんでるようなもんですね。この3つは特にインストールに直接関わるような関数は定義していませんが、ユーティリティ関数を定義しています。

「インストールに直接関わるような関数」といいました。 ebuildは「パッケージの情報を現す変数」と「どうやってビルドし、どうやってインストールするか」を書いた関数を記述するものです。一般には

  • pkg_setup パッケージの前準備 環境変数を設定したりすることに使われたりする…
  • src_unpack ソースコードの展開 EAPI=0,1 ではここでパッチなども行なう
  • src_prepare (EAPI 2以上) パッチをあてたり、sedでコードを変更したりする
  • src_configure (EAPI 2以上) ビルド設定を行なう ./configure とか
  • src_compile makeなどでコンパイルを行なう EAPI=0,1ではここでビルド設定も行なう
  • src_test テストケースを実行する
  • pkg_preinst インストール前に実行しておくこと
  • src_install 「一時インストールディレクトリに」インストールを行なう ようするにまだシステムにはインストールされていない! EAPI=4ではデフォルト動作ができた
  • pkg_postinst インストール後に実行すること たとえばインストールしたelispを元にしてロードされる site-gentoo.el を再生成する、とか

というふうに実行される。全て自分で書くのはやってられないので、デフォルトの動作がいろいろと定義されていて、変えたい部分だけを自分で書いていく、というようになっている。デフォルト動作はいわゆる ./configure; make; make install をしているのだけれど、世の中にはcmakeなどなど他のビルドツールもある。それに対応するために cmake-utilsなどのeclassがあってこいつがcmake用のデフォルト動作などを定義してくれている。

DESCRIPTION="library for decoding mpeg-2 and mpeg-1 video"
HOMEPAGE="http://libmpeg2.sourceforge.net/"
SRC_URI="http://libmpeg2.sourceforge.net/files/${P}.tar.gz"

パッケージの説明・ホームページ・ソースコードURI

${P} はパッケージの名前とバージョン "libmpeg2-0.5.1" に展開される。こうしておけばファイル名を変えるだけで簡単にバージョンアップできていいね!

LICENSE="GPL-2"
SLOT="0"
KEYWORDS="~alpha ~amd64 arm ~hppa ~ia64 ppc ppc64 ~sh ~sparc ~x86 ~x86-fbsd ~x86-freebsd ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-solaris"
IUSE="sdl static-libs X"

RDEPEND="sdl? ( media-libs/libsdl )
	X? ( x11-libs/libXv
		x11-libs/libICE
		x11-libs/libSM
		x11-libs/libXt )"
DEPEND="${RDEPEND}
	X? ( x11-proto/xextproto )"

USEフラグによる依存関係。 sdl を使う時は media-libs/libsdl に、 Xを使う時は x11-libs/libXv などに…という依存関係になっている。 DPENDがビルド時依存で、RDEPENDが実行時依存。

DOCS=( AUTHORS ChangeLog NEWS README TODO )

EAPI=4ではDOCS変数に設定したもの(または設定しなければデフォルトでREADME* ChangeLog AUTHORS NEWS TODO CHANGES THANKS BUGS FAQ CREDITS CHANGELOG)がインストールされるようになった。ということで、インストールするドキュメントを設定している。

src_prepare() {
	epatch \
		"${FILESDIR}"/${P}-arm-private-symbols.patch \
		"${FILESDIR}"/${P}-global-symbol-test.patch \
		"${FILESDIR}"/${P}-armv4l.patch
	elibtoolize
	### PowerPC fix for altivec
	epatch "${FILESDIR}"/${P}-altivec.patch
	eautoconf
}

まずepatch によってpatchをあてている。patch は普通 -p0 とか -p1 とかをつけてやらないといけないが epatch は -p0 から順番に試していってうまくあたったらそこで終わる、というようなラッパー。あとはディレクトリをあたえたり、.bz2,.gzなどで圧縮されているようなパッチも渡せるようになっているのが便利なところか。

${FILESDIR} はebuildのおいてあるディレクトリの中のfiles/というディレクトリへのパスが入る。 ここでは /usr/portage/media-libs/libmpeg2/files/ になっている。patchなどの小さいファイルはこの ${FILESDIR}において使えばいい。一般には patchとか起動(init)スクリプトとか設定ファイルのサンプルとかが置いてある。

elibtoolize (libtool eclass) は libtoolというportableにライブラリを生成するスクリプトGentoo用のパッチをあててくれる。たとえば一般にFreeBSDのライブラリ作成ルールとLinuxのライブラリ作成ルールは違っている(バージョン番号のつき方とか)が、Gentoo/FreeBSDではライブラリ作成ルールをLinuxにあわせている。しかし、普通のパッケージはGentoo/FreeBSD用の対策なんてしてない。そこで、FreeBSDの判定部分にpatchをあててGentoo/FreeBSDでもLinux用判定させたりしている。

そしてまた別のpatchをあてて…eautoreconf (autotools eclass)している。

ここで autotools のお話。自分でいろいろコンパイルしている人はきっと ./configure とかに出会ったことがあるかと思う。あれはビルド環境を自動判定してビルドの設定をいろいろ行なってくれるshスクリプトになっている。中を見てみるとわかるけれど、とうてい自分で手で書いていたら日が暮れて朝になって授業なんて忘れきってしまいそうなほどの長くてしつこいコードになっている…portableにするためにしかたのないことなのだけれど。まあ、こんなのは自分では書けないので configure.ac というファイルにいろいろ書いてそこからコマンドで自動生成することになっている。

ということで、ここでpatchしている "${FILESDIR}"/${P}-armv4l.patch では configure.ac の内容を変更している。これで patchあてたで!と満足していてはいけない。configureを再生成しなければ実際に実行されるコードは変わらないのだから…。ということで eautoreconf によってその再生成するコマンドを実行している。

configureあたりの挙動を詳しく知りたかったら Autotools Mythbuster を読もう!

src_configure() {
	econf \
		$(use_enable static-libs static) \
		--enable-shared \
		$(use_enable sdl) \
		$(use_with X x)
}

パッケージ設定。 use_enable hoge は USE=hoge であれば --enable-hoge に、そうでなければ --disable-hoge という文字列を返すような関数になっている。$()の中にコマンド書けばその出力で置換されるのでそれを使っている、というわけ (`use_enable hoge`と同じ感じ)。 ここではさらにもう一つ引数を与えているものもある。use_enable は --enable-hoge とかの hoge部分に第二引数か、指定されてなければ第一引数を使う。

ということで USE="X sdl" なうちの環境では econf --disable-static --enable-shared --enable-sdl --enable-x ということになる。

econf は ./configure のラッパーになっていて、クロスビルド用のあれこれとかインストール先ディレクトリの設定とかをやってくれる。 しかも、 ${EXTRA_ECONF}とかいうものもつけてくれるらしい。これはユーザが指定する引数になっている。 ./configure の挙動いじりたかったらこれつけてemergeするといいみたい。知らなかったよ…。

src_compile() {
	emake OPT_CFLAGS="${CFLAGS}" \
		MPEG2DEC_CFLAGS="${CFLAGS}" \
		LIBMPEG2_CFLAGS=""
}

コンパイルを実行。 emake は基本的に "make ${MAKEOPTS}" などをしているだけである。 MAKEOPTSのデフォルトは -j2 だと…知らなかったよ…。

src_install() {
	default

	find "${ED}" -name '*.la' -exec rm -f {} +
}

インストール。 EAPI=4 からはdefaultというコマンドが使えるようになった。そのフェイズ(src_configureとかsrc_compileとか)のデフォルトの動作を実行する。

そのあとの find では ${ED} の下の "*.la" というファイルを削除している。 ${ED} は prefixを考慮した一時インストールディレクトリのパスをしめしている。 *.la というのは……まあ libtools で使われるリンクのためのファイルで(portableには便利なんだけどLinuxでは)いろいろと問題をひきおこすだけなので削除してしまう。 くわしくは http://blog.flameeyes.eu/tag/lafiles を見るがよい。