試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

x86_64版Gentoo Linuxの32bitライブラリを自前で管理(chroot無しでemul-linux-x86-xlibsをビルド)

X関係のライブラリは基本的にCHOST/ABI指定で通るが、一部例外もある。64bit版とのバージョンの開きが大きく、「libX*」をビルドするだけでも価値はある。

  1. 準備
  2. 順番
  3. freetype
  4. glut
  5. openmotif
  6. 32bitでもxcbを使用するようにする
  7. x86_64システムへインストールするebuildの例
  8. うまくパッケージが入らない?

準備

ライブラリをビルドするときにリンクエラーになるのを防ぐため、「emul-linux-x86-xlibs」をあらかじめ入れておく。

順番

ビルドした順番をメモ。xcbを使用したのでlibxcbとxcb-utilが入っている(使用しない場合は除外)。
[任意]ファイル名: emul-linux-x86-xlibs.txt

x11-libs/libXau
x11-libs/libXdmcp
x11-libs/libxcb
x11-libs/xcb-util
x11-libs/libICE
x11-libs/libSM
x11-libs/libdrm
x11-libs/libX11
x11-libs/libXext
x11-libs/libXt
x11-libs/libXfixes
x11-libs/libXrender
media-libs/freetype
x11-libs/libXmu
x11-libs/libXpm
x11-libs/libXp
x11-libs/libXxf86vm
x11-libs/libXi
x11-libs/libXdamage
x11-libs/libXv
x11-libs/libXcomposite
x11-libs/libXcursor
x11-libs/libXinerama
x11-libs/libXrandr
x11-libs/libXScrnSaver
x11-libs/libXtst
x11-libs/libXxf86dga
x11-libs/libXvMC
x11-libs/libXaw
media-libs/fontconfig
x11-libs/libXft
media-libs/mesa
media-libs/glut
x11-libs/openmotif

以下は実行例だが、そのままでは完走はしないので注意。

$ sudo bash -c 'FEATURES="noman noinfo" CHOST=i686-pc-linux-gnu ABI=x86 PKGDIR=[出力先] USE="-X xcb" emerge -avOB $(cat emul-linux-x86-xlibs.txt)'

freetype

freetype(2.3.4-r2で実験)では、USE="-X"でエラーを回避できる。このUSEフラグを付けなくても、得られるライブラリ(libfreetype.so)は同じ。

glut

glut(3.7.1で実験)では、libtool絡みで、64bitの.soファイルにリンクしようとしてエラーが出てしまうため、Makefile中の「lib64」を「lib32」へ置換して対処。

--- /usr/portage/media-libs/glut/glut-3.7.1.ebuild.orig
+++ /usr/portage/media-libs/glut/glut-3.7.1.ebuild
@@ -44,6 +44,9 @@
        # --without-glut flag actually refers to whether mesa would build with or
        # without *external* glut, in this case we want the internal one
        econf --without-glut || die
+       if use amd64 && [[ "${ABI}" = "x86" ]]; then
+               find . -name Makefile | xargs sed -i -e 's/lib64/lib32/g'
+       fi
        cd "${S}"/src-glut
        emake || die "emake failed"
 }

ebuild修正後、

$ sudo ebuild /usr/portage/media-libs/glut/glut-3.7.1.ebuild digest

をしてからビルドを実行。他のものも、ebuild修正後にはdigestを取る必要がある。
無理にビルドしなくても、バージョンが新しいわけでもないので、「emul-linux-x86-xlibs」のものをそのまま使用してもよい。

openmotif

openmotif(2.2.3-r9で実験)でも、libtoolのエラーの他、下のようなエラーが出るが

/bin/sh ../../libtool --mode=link x86_64-pc-linux-gnu-gcc  [CFLAGS] -I/usr/include/gentoo-multilib/x86 -fno-strict-aliasing -Wall -Wno-unused -Wno-comment   -o wmluiltok  wmluiltok.o  
x86_64-pc-linux-gnu-gcc [CFLAGS] -I/usr/include/gentoo-multilib/x86 -fno-strict-aliasing -Wall -Wno-unused -Wno-comment -o wmluiltok wmluiltok.o   
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/../../../../lib32/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
make[2]: *** [wmluiltok] Error 1
make[2]: Leaving directory `/var/tmp/portage/x11-libs/openmotif-2.2.3-r9/work/openMotif-2.2.3/tools/wml'
make[1]: *** [install-recursive] Error 1
make[1]: Leaving directory `/var/tmp/portage/x11-libs/openmotif-2.2.3-r9/work/openMotif-2.2.3/tools'
make: *** [install-recursive] Error 1

32bitライブラリの生成と無関係なので、このエラーを無視するため、makeを無理やり通すよう修正。

--- /usr/portage/x11-libs/openmotif/openmotif-2.2.3-r9.ebuild.orig
+++ /usr/portage/x11-libs/openmotif/openmotif-2.2.3-r9.ebuild
@@ -75,11 +75,20 @@

        econf --with-x || die "configuration failed"

-       emake -j1 || die "make failed, if you have lesstif installed removed it, compile openmotif and recompile lesstif"
+       if use amd64 && [[ "${ABI}" = "x86" ]]; then
+               find . -name Makefile | xargs sed -i -e 's/lib64/lib32/g'
+               emake -j1 -k
+       else
+               emake -j1 || die "make failed, if you have lesstif installed removed it, compile openmotif and recompile lesstif"
+       fi
 }

 src_install() {
-       make DESTDIR=${D} install || die "make install failed"
+       if use amd64 && [[ "${ABI}" = "x86" ]]; then
+               make -k DESTDIR=${D} install
+       else
+               make DESTDIR=${D} install || die "make install failed"
+       fi

        # cleanups
        rm -fR ${D}/usr/$(get_libdir)/X11

このライブラリを使用する32bitアプリケーションを使用するのでもなければ、わざわざここまでする必要はない気がする。「emul-linux-x86-xlibs」パッケージのものをそのまま使うか、もしくは容量節約のために消してしまってもよい。

32bitでもxcbを使用するようにする

32bitライブラリ(libX11やmesa)側でxcbを有効にして使いたいのであれば、「USE=xcb」を指定し、

  1. libxcb
  2. libX11
  3. mesa

の順でビルドするのはもちろん、libX11のビルド時に32bit版libxcbを要求してくるので

$ tar jxf [tbz2の保存先]/x11-libs/libxcb-1.0.tbz2
$ sudo cp -d ./usr/lib32/libxcb*.so* /usr/lib32/

のようにして直接.soファイルとシンボリックリンクをコピー*1してからlibX11をビルド。その後、mesaのビルドの前に

$ tar jxf [tbz2の保存先]/x11-libs/libX11-1.1.2-r1.tbz2
$ sudo cp -d ./usr/lib32/libX11*.so* /usr/lib32/

のように、同様にlibX11の共有オブジェクトファイルを入れる(ファイルコピー時、一部アプリが落ちる場合があるので注意)。
最後までビルドが終わったら、emul-linux-x86-xlibsのebuildのSRC_URIの中にlibxcbを含める。

x86_64システムへインストールするebuildの例

emul-linux-x86-xlibs-10.1.ebuildをベースにして、主にバージョン部分をいじったもの。インストールの際には、実際に手元でビルドしたtbz2ファイルのバージョンに合わせる。

ファイル名: emul-linux-x86-xlibs-9999.ebuild

# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/app-emulation/emul-linux-x86-xlibs/emul-linux-x86-xlibs-10.1.ebuild,v 1.1 2007/08/18 15:28:04 tester Exp $

inherit emul-libs

SRC_URI="mirror://gentoo/fontconfig-2.4.2.tbz2
	mirror://gentoo/freetype-2.3.4-r2.tbz2
	mirror://gentoo/glut-3.7.1.tbz2
	mirror://gentoo/libICE-1.0.3.tbz2
	mirror://gentoo/libSM-1.0.2.tbz2
	mirror://gentoo/libX11-1.1.2-r1.tbz2
	mirror://gentoo/libXScrnSaver-1.1.2.tbz2
	mirror://gentoo/libXau-1.0.3.tbz2
	mirror://gentoo/libXaw-1.0.3.tbz2
	mirror://gentoo/libXcomposite-0.4.0.tbz2
	mirror://gentoo/libXcursor-1.1.8.tbz2
	mirror://gentoo/libXdamage-1.1.1.tbz2
	mirror://gentoo/libXdmcp-1.0.2.tbz2
	mirror://gentoo/libXext-1.0.3.tbz2
	mirror://gentoo/libXfixes-4.0.3.tbz2
	mirror://gentoo/libXft-2.1.12.tbz2
	mirror://gentoo/libXi-1.1.2.tbz2
	mirror://gentoo/libXinerama-1.0.2.tbz2
	mirror://gentoo/libXmu-1.0.3.tbz2
	mirror://gentoo/libXp-1.0.0.tbz2
	mirror://gentoo/libXpm-3.5.6.tbz2
	mirror://gentoo/libXrandr-1.2.1.tbz2
	mirror://gentoo/libXrender-0.9.2.tbz2
	mirror://gentoo/libXt-1.0.5.tbz2
	mirror://gentoo/libXtst-1.0.2.tbz2
	mirror://gentoo/libXv-1.0.3.tbz2
	mirror://gentoo/libXvMC-1.0.4.tbz2
	mirror://gentoo/libXxf86dga-1.0.1.tbz2
	mirror://gentoo/libXxf86vm-1.0.1.tbz2
	mirror://gentoo/libdrm-2.3.0.tbz2
	mirror://gentoo/libxcb-1.0.tbz2
	mirror://gentoo/mesa-6.5.2-r1.tbz2
	mirror://gentoo/openmotif-2.2.3-r9.tbz2
	mirror://gentoo/xcb-util-0.2.tbz2"

LICENSE="fontconfig FTL GPL-2 LGPL-2 glut libICE libSM libX11 libXScrnSaver
		libXau libXaw libXcomposite libXcursor libXdamage libXdmcp libXext
		libXfixes libXft libXi libXinerama libXmu libXp libXpm libXrandr
		libXrender libXt libXtst libXv libXvMC libXxf86dga libXxf86vm
		libdrm libxcb xcb-util"
KEYWORDS="-* ~amd64"
IUSE="opengl nodevelop"

DEPEND="opengl? ( app-admin/eselect-opengl )"
RDEPEND=">=app-emulation/emul-linux-x86-baselibs-10.0
	x11-libs/libX11"

QA_TEXTRELS="usr/lib32/dri/*.so usr/lib32/opengl/xorg-x11/lib/libGL.so*"

src_unpack() {
	! use nodevelop \
		&& ALLOWED="(^${S}/etc/env.d|^${S}/usr/lib32/pkgconfig|.*lib32.*\.l?a$)"
	emul-libs_src_unpack
}

pkg_postinst() {
	#update GL symlinks
	use opengl && eselect opengl set --use-old
}

(2007/10/10).pcファイルと.a形式のライブラリ、更に、libtoolが使用する.laファイルに関して、インストールするかどうかを「develop」USEフラグで選択できるようにした。更に、mesaのバージョンを変更。${ALLOWED}は、Portage${S}/以下へ展開したtbz2ファイルの中身の内、残す*2(後に/以下にマージされる)ファイルのパス名の正規表現パターン(egrepで処理され、初期値は「^${S}/etc/env.d」。詳しくは/usr/portage/eclass/emul-libs.eclassを参照)。この値をカスタマイズする際には、64bit版のパッケージが使用するファイルとかぶらないように十分注意する。${ROOT}を一時ディレクトリにしてテストするのもよい。ファイルがかぶってしまったら、「emul-linux-x86-*」のインストール情報を消した*3後、portage-utilsのqcheckで、MD5ダイジェストが変わった(=内容が変わった)ファイルを調べていく。*4
(2007/10/11)自分で32bitライブラリを管理する上で有用と分かってきたものの、「develop」USEフラグの形だとデフォルトで無効になるため、逆の意味にして「nodevelop」を指定したときにのみ.soファイルと一部のファイル以外を消し、デフォルトでは.pcファイルなどがインストールされるように修正


これをローカルOverlayに入れてインストール。下は例。別途PORTDIR_OVERLAYを設定しておく。

$ sudo mkdir /usr/local/overlays/local/app-emulation/emul-linux-x86-xlibs/files -p
$ sudo cp emul-linux-x86-xlibs-9999.ebuild /usr/local/overlays/local/app-emulation/emul-linux-x86-xlibs/
$ sudo cp [tbz2ファイル...] /usr/portage/distfiles/
$ sudo ebuild /usr/local/overlays/local/app-emulation/emul-linux-x86-xlibs/emul-linux-x86-xlibs-9999.ebuild digest
$ sudo emerge -avu emul-linux-x86-xlibs

うまくパッケージが入らない?

上のebuildからのパッケージインストールがうまくいかず、tbz2ファイルをダウンロードしにいくことがある。その場合、

  • files/digest-*ファイルを消す
  • tbz2ファイルが/usr/portage/distfiles/以下にあることを確認

をしてからdigestを取り直して再試行。

$ sudo cp [tbz2ファイル...] /usr/portage/distfiles/
$ sudo ebuild /usr/local/overlays/local/app-emulation/emul-linux-x86-xlibs/emul-linux-x86-xlibs-9999.ebuild digest
$ sudo emerge -av emul-linux-x86-xlibs
...
[ebuild  N    ] app-emulation/emul-linux-x86-xlibs-9999  USE="opengl" 0 kB [1]

のように「0 kB」になっていればOK。

(2007/10/9)追記として、パッケージ検出システムpkgconfig用の.pcファイルは、あっても無くても、CHOST/ABI指定でのビルドでは変わらないことが分かった。これは元々インストールしないようになっているが、結局そのままにすることにする。選択できるようにした。

*1:後でemergeするときに上書きされ、その後はPortageで管理されることになるので、「システムのディレクトリに手動でファイルを配置する」ということを気にすることはない

*2:「残す」指定をしていないファイルは、共有オブジェクトの.soファイル以外全て消されることになっている

*3:/var/db/pkg/app-emulation/emul-linux-x86-*-9999ディレクトリを消す。そうしないと、次にインストールしたりアンインストールしたりすると、かぶったファイルが失われる

*4:MD5-DIGEST」という表示が出る(64bit版)パッケージは、再インストールする必要がある