Kakasi を Universal Binary でビルドする

以前できたと思っていたのだけどどうもうまくないような気がするのでもう一度見直してみる。Technical Note TN2137: Building Universal Binaries from "configure"-based Open Source Projects を参考にした。
上記ページには 2 つのやり方が書かれていて、片方は ppc 用、i386 用を一度に作成してしまう方法、もう片方は別々に作成しておいて最後に lipo で結合する方法だ。どちらでもいけそうな気がするが、とりあえず両方試してみる。

  • 一度に作成する場合

% env CFLAGS="-O -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc" env LDFLAGS="-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk" ./configure --disable-dependency-tracking --disable-shared

で一度に configure を実行(--disable-shared をつけておかないと make 時にエラーが出る)。あとは、make、make install するだけ。インストールされたファイルが Universal Binary になっているかどうかは、file コマンドで確認できる。

% file /usr/local/bin/kakasi
/usr/local/bin/kakasi: Mach-O fat file with 2 architectures
/usr/local/bin/kakasi (for architecture i386): Mach-O executable i386
/usr/local/bin/kakasi (for architecture ppc): Mach-O executable ppc

% file /usr/local/lib/libkakasi.a
/usr/local/lib/libkakasi.a: Mach-O fat file with 2 architectures
/usr/local/lib/libkakasi.a (for architecture i386): current ar archive random library
/usr/local/lib/libkakasi.a (for architecture ppc): current ar archive

なんともあっさり。

  • 別々に作成して最後に結合する場合

i386 フォルダ、ppc フォルダを作成してそれぞれのフォルダ内でビルドし、最後にそれらを結合する。まずは、i386 から。

% mkdir i386
% cd i386
% env CFLAGS="-O -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386" env LDFLAGS="-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk" ../configure --disable-dependency-tracking --disable-shared
% cp ../src/kakasi.h src/
% make
% cd ..

同じように ppc も作成。

% mkdir ppc
% cd ppc
% env CFLAGS="-O -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc" env LDFLAGS="-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk" ../configure --disable-dependency-tracking --disable-shared
% cp ../src/kakasi.h src/
% make
% cd ..

最後に lipo で結合(とりあえず kakasi と libkakasi.a のみ)。

% mkdir ub
% lipo -create ../i386/src/kakasi ../ppc/src/kakasi -output kakasi
% lipo -create ../i386/lib/.libs/libkakasi.a ../ppc/lib/.libs/libkakasi.a -output libkakasi.a

これで同じように Universal Binary の実行ファイル、ライブラリが完成だ。ちょっと手間がかかるが、こちらの方が汎用性は高いみたい。

できあがったファイルを比べてみると、やはりサイズも内容も違う。Universal Binary のファイルがどういう構造になっているのかわからないが、作り方によって微妙に異なる形式があるということなんだろうか。あるいはそうではなく、ファイル内の格納順序が微妙に異なることによってオフセットなどの値が違っているということなんだろうか。内容を見た限りでは、少なくとも、ビルドされた場所の情報が異なる(ビルド時のオプション次第では関係なくなるのかもしれないが)ということは事実のようだけど。

とりあえず前者の方法でビルドしたものをもとに Text-Kakasi もビルドしたものを POPFileユニバーサルバイナリ版に含めてみた。これで問題が解決するとよいのだけど。