x86_64版Gentoo Linuxの32bitライブラリを自前で管理(概要と、ビルド方法について)
Gentoo Linuxでは、「emul-linux-x86-*」パッケージにより、x86_64環境においても、事情により64bit版として動作させられないプログラム*1を実行することができるのだが、最近このバージョンがJavaのランタイムを除き、あまり更新されていない。
(2007/11/16)最近新しいバージョンが入った。少しだけ変わった新しいインストールシステムになり、自前管理もしやすくなった。→「新しいemul-linux-x86-*パッケージと、これを利用した32bitライブラリの自前管理について」
最近ビルドしたWineは、挙動が変なところがあり、32bitライブラリのバージョンを64bit側に合わせたところ、改善されたものがある。*2ビルド時に参照するヘッダファイルが64bit側のものなので、これと大きく離れたバージョンの32bitライブラリを使用するのは良くないということになる。
自分でパッケージをビルドしてインストールできれば、このような問題に対処できるだけでなく、ビルド時に最適化もできるし、インストールする項目を多少調整することも簡単にできる(例: 32bitでのGTK+のテーマエンジンを追加)。インストールするバージョンが細かく選択できるのも便利(例: ALSAのライブラリだけ最新版にして、他のサウンド関連のライブラリは安定版のまま)。
これ以外にも、freetypeライブラリのように、実行形式(バイナリ)として配布されているものに制約がある場合でも、ソースからビルドすることで、その制約を回避できるし、他には、binutils 2.18から使用できるhashstyleをいち早く導入できるというメリットもある。
デメリットは、手間と時間がかかることと、その割に得られるものが大きいのかが怪しいこと。ただ、Wineを使用しているのであれば、不具合が改善されることがあるため、やってみる価値はあると思う。
大まかな流れ
これを行う方法は何通りか考えられるのだが、最も手っ取り早いのは- 32bitビルドしたtbz2パッケージファイルを作成
- 既存の「emul-linux-x86-*」パッケージのebuildをベースにして、構成するパッケージ名とバージョンの部分を編集、そのカスタムebuildをローカルOverlayへ入れる
- tbz2ファイルをdistfilesのディレクトリへ入れて、カスタムパッケージをインストール
という流れ。
一番の問題は、32bit向けのtbz2パッケージを用意するところで、
- として、emulパッケージビルド用のchrootを用意して、その中で普通にパッケージをビルドし、tbz2ファイルを作成
- chrootを使用せず、「CHOST=i686-pc-linux-gnu」と「ABI=x86」を付けて、emerge -Bでパッケージ作成
- 公式の「emul-linux-x86-*」パッケージの中に含まれるバージョンのtbz2ファイルをそのまま使用(自分が滅多に使いそうにないものに対しては効果的)
のいずれかで用意することになる。
chrootを使用する場合、amd64のstage2を使用して、プロファイルには/usr/portage/profiles/default-linux/amd64/dev/32bit-userland/を使用する。詳細は
http://www.gentoo.org/proj/en/base/amd64/emul/index.xml
を参照。
emul用chrootよりも、x86-chrootでビルドするほうが手間もかからず、より確実な気もするのだが、詳しいこと(emul用chroot上でビルドされたものととx86-chroot上でビルドされたものの違い)はよく分からない(更に言うと、「CHOST=i686-pc-linux-gnu」と「ABI=x86」だけでビルドが通ったものではダメなのかすら分からない)。
(2007/10/8)ライブラリのディレクトリ名が違うというのはある。x86-chrootでは、「32」の付かない/libのような名前になっているのに対し、emul用chrootは、x86_64環境と同様、/lib32のような「32」付きの名前となる。
(2007/11/13)上の追記にも書いたように、x86-chrootを使用すると「/lib」「/usr/lib」などに入る形でconfigureやビルドがされるため、問題がある。「CHOST=i686-pc-linux-gnu」と「ABI=x86」(QT4など、必要に応じてlinux32も必要)でパッケージを作る分には問題ないと思われるが、GLib 2、GTK+ 2、D-BUSなどを使用するパッケージにおいて、32bit版固有のヘッダファイル(/usr/lib32/以下に配置されるヘッダファイル)が使用されるようにしなくてはならず、64bit環境上でビルドする際にはその点に注意が必要。emul用chrootは、一度作ってしまえば、そのあたりのことや、ビルド時の色々な修正などを行ったりすることなく、普通にビルドしていけるので好ましい、ということになる。
[引用]ファイル名: /usr/portage/profiles/default-linux/amd64/dev/32bit-userland/make.defaults より
FEATURES="multilib-strict" MULTILIB_STRICT_DIRS="/lib32 /lib /usr/lib32 /usr/lib /usr/kde/*/lib32 /usr/kde/*/lib /usr/qt/*/lib32 /usr/qt/*/lib /usr/X11R6/lib32 /usr/X11R6/lib" MULTILIB_STRICT_DENY="64-bit.*shared object"
CHOSTやABI以外では、この辺りが重要なのかもしれないが、詳しい情報は見付けられない。
関連している可能性があるのは
http://archives.gentoo.org/gentoo-dev/msg_142909.xml
ぐらい。
「CHOST=i686-pc-linux-gnu」「ABI=x86」の動作原理と注意点
# FEATURES="noman noinfo" CHOST=i686-pc-linux-gnu ABI=x86 PKGDIR=[出力先] emerge -avB [パッケージ名] $ sudo bash -c 'FEATURES="noman noinfo" CHOST=i686-pc-linux-gnu ABI=x86 PKGDIR=[出力先] emerge -avB [パッケージ名]'
の形では、64bit版GCCが使用され、-m32で実行したのと同様に処理され、リンク時には32bit版ライブラリが使用され、32bitバイナリとなる。ヘッダファイルに関しては、/usr/include/以下が使用される。Wineをビルドする際にも、これと同様の原理で32bitの実行ファイルとライブラリが生成される。
注意点として、「emul-linux-x86-*」パッケージに含まれないライブラリに依存するようなUSEフラグを有効にしないようにする。それが使用したい機能の場合は、依存するライブラリ側も別途32bitのライブラリとして用意する必要がある。USEフラグでも外せないものが出たらebuildに手を加えるしかない。
ライブラリパスの誤検出とlibtool
ビルドするパッケージ自体、他のパッケージに依存しないものであれば問題はないのだが、別のライブラリに依存するパッケージをビルドする際、リンク時のコマンドラインに/usr/lib64/lib[名前].soというファイル名が突然現れることがあり、これに対してリンクを試みるため、形式が合わないとエラーになる。下は、openMotifの例。/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 -version-info 3:2:0 -o libXm.la -rpath /usr/lib32 XmStrDefs.lo (中略) ComboBox2.lo -L/usr/lib64 -lXmu -lXt -lSM -lICE -lXext -lXp -lX11 x86_64-pc-linux-gnu-gcc -shared .libs/XmStrDefs.o (中略) .libs/ComboBox2.o -L/usr/lib64 /usr/lib64/libXmu.so /usr/lib64/libXt.so /usr/lib64/libSM.so /usr/lib64/libICE.so /usr/lib64/libXext.so /usr/lib64/libXp.so /usr/lib64/libX11.so [CFLAGS] -Wl,-soname -Wl,libXm.so.3 -o .libs/libXm.so.3.0.2 /usr/lib64/libXmu.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[3]: *** [libXm.la] Error 1 make[3]: Leaving directory `/var/tmp/portage/x11-libs/openmotif-2.2.3-r9/work/openMotif-2.2.3/lib/Xm'
これは、configureスクリプトで(誤)検出された/usr/lib64などのディレクトリ名が、スクリプトの実行後に生成されるMakefileの中に含まれ、それを(上の例では)libtoolが
-L/usr/lib64 -lXmu -lXt -lSM -lICE -lXext -lXp -lX11
として渡された部分を
-L/usr/lib64 /usr/lib64/libXmu.so /usr/lib64/libXt.so /usr/lib64/libSM.so /usr/lib64/libICE.so /usr/lib64/libXext.so /usr/lib64/libXp.so /usr/lib64/libX11.so
としてリンカに渡してしまい、エラーを引き起こすような感じになっている。
対処法としては、configureスクリプトの実行後に全てのMakefileに対して
sed -i -e 's/lib64/lib32/g' Makefile
をすればよい(それだけではダメな場合もある)のだが、Makefile生成後、すぐにmakeが実行されてしまう*3ため、タイミングが難しく、ebuildファイルに直接手を加えてからdigestを取り直し、ビルドするのが楽?