(2007/04/24)
LinuxSampler の CVS 最新版をそのままビルドして Universal Binary ができるようにしてみた。当然 CVS 最新版は開発途中の版なので、不安定であることは承知しておくこと。
ディレクトリ構成を決めておく。ここでは、後述の libsndfile のビルドも含めて1つのディレクトリ(以下 $PROJDIR
とする。例えば PROJDIR=$HOME/Development/LinuxSampler
)の中で全部済ませることにする。
LinuxSampler の公式サイトから libgig と linuxsampler の最新版をとってくる。
libsndfile もソースをとってきて、同じディレクトリ中で展開しておく。
libgig, linuxsampler の CVS 版は、最初に make -f Makefile.cvs
として configure, Makefile.in
などを作る。ここが最初の難関。
Apple の "Porting UNIX/Linux Applications to Mac OS X" の Dynamic Libraries and Plug-ins の章に書かれている通り、 Mac OS X では GNU libtool, libtoolize はそれぞれ /usr/bin/glibtool, /usr/bin/glibtoolize
としてインストールされている。このままでは、次のようにつまづいてしまう。
ちょっと強引だが、/usr/bin/glibtoolize
へのシンボリックリンクを /usr/local/bin/libtoolize
として作成し、パスに /usr/local/bin
を入れる。これで一応 make -f Makefile.cvs
は通るようになる。
こういう変更は他の部分に影響を及ぼす可能性があるので要注意である。ただ、libtool
は NeXTSTEP 由来の同名のツールが /usr/bin
にあるので厄介だが、libtoolize
は名前はぶつからないので一応大丈夫みたい。
ところが、これで作成した configure
を走らせると、途中で止まってしまう。
これは Mac OS 10.4 に pkg-config が無いため。最新版をダウンロードして、./configure && make && sudo make install
でインストールする。/usr/local
以下にインストールされる。
さらに、このままでは Makefile.cvs
から呼び出される aclocal
が /usr/local/share/aclocal/pkg.m4
を認識してくれない。そこで、libgig のトップレベルディレクトリにある aclocal
を /usr/local/bin
にコピーし、実行許可をつけておく。
ちなみに、このファイルの中身は次の2行。同じことで悩んだ人が他にもいたのだろうか。
ここまで準備してしまえば、あとは libgig, linuxsampler それぞれのディレクトリで make -f Makefile.cvs
とすれば、configure
および関連ファイルが作成される。
libsndfile, libgig はライブラリで、linuxsampler はこれらにリンクする実行ファイルになる。UNIX の流儀なら、ライブラリは /usr/local/lib
あたりにインストールしてもらうことになるのだろうが、Mac OS X の場合はそうはいかない。ユーザーは当然「linuxsampler のバイナリをダウンロードしてきて適当な位置にコピーして、それをダブルクリックすれば linuxsampler が走る」ことを期待している。まあ、JackOSX のインストールぐらいはやってもらってもよいだろうが、それ以上のことをユーザーに要求する訳にはいかない。というわけで、今回はこれらのライブラリはスタティックリンクとする。
また、Universal Binary を作成する時、i386 版と ppc 版は別々に configure && make
することになる。エンディアンやアーキテクチャ依存の最適化が重要なプログラムではこれは必須である。最後に linuxsampler の実行ファイルができてから、lipo
コマンドで結合して Universal Binary を作る。
このため、i386 版と ppc 版のビルドは $PROJDIR
の中にそれぞれ独立したディレクトリを切って、その中で行うことにする。また、libsndfile, libgig はいったん make install
した方がスムーズだが、これも $PROJDIR
の中に一時的なインストールディレクトリを作って、そこにインストールする。こうすれば、make install
に sudo
がいちいち必要ないので好都合である。
具体的には、次のようなディレクトリ構成にする。
$PROJDIR/ libsndfile-1.0.17/ libgig/ linuxsampler/ build/ ppc/ libsndfile-1.0.17/ libgig/ linuxsampler/ local/ # 一時インストール用 i386/ libsndfile-1.0.17/ libgig/ linuxsampler/ local/ # 一時インストール用 UB/ linuxsampler # 実行ファイル(ディレクトリではない)
$PROJDIR/build/i386/libgig
は $PROJDIR/libgig
を(autoconf したあと)ディレクトリツリーごとコピーしたもの。他のディレクトリも同様。下の例ではソースファイルを全部 cp -r
でコピーしているが、本当はシンボリックリンクにするべきである。
ADC の TN2137: Building Universal Binaries from "configure"-based Open Source Projects に "configure" ベースのプロジェクトから Universal Binary を作る方法が記述されている。「単純な」プロジェクトなら、CFLAGS
に "-arch i386 -arch ppc"
を同時に指定することで一気に UB を作れる場合もあるのだが、上にも書いた通り今回は i386 のバイナリと ppc のバイナリを別々に作成する。
上記 Technical Note では、intel マシンと ppc マシンそれぞれでビルドして、あとで結合するように書いてある。しかし、ppc マシンだけしかなくても、次のようにすれば2種類のバイナリを作ることはできるようだ。
ppc バイナリ(全部1行で):
i386 バイナリ(全部1行で):
--host=....
を(configure を走らせているマシンと)違うものに指定すると、クロスコンパイルと見なされ、configure 中に作成したプログラムの実行がスキップされる。また、コンパイラフラグの -msse, -msse2
は、CarbonCore.h をインクルードした時に起きるエラーを回避するためのもの。
なお、PPC Mac ではクロスコンパイルのために MacOSX10.4u.sdk が必要。これは ADC のサイトからダウンロードすることができる。Intel Mac では、システムのライブラリがすでに UB 化されているため -isysroot ...
は必要ないはず(Intel Mac を持っていないので確かめられないが)。
それではまず PPC 版をビルドしてみる。
configure
の時に、インストール場所として $PROJDIR/build/ppc/local
を --prefix
オプションで指定しておく。
$PROJDIR/build/ppc/local/lib
に libsndfile.a, pkgconfig/sndfile.pc
ができていれば成功。
configure
に先と同じ --prefix
オプションに加えて、環境変数として PKG_CONFIG_PATH=$PROJDIR/build/ppc/local/lib/pkgconfig
を指定する。こうしないと、さきほどインストールした libsndfile.a
を見つけられず、失敗する。
$PROJDIR/build/ppc/local/lib
に libgig.a, pkgconfig/gig.pc
ができていれば成功。
configure
に先と同じ --prefix, PKG_CONFIG_PATH=...
指定に加えて、次の指定が必要。
HAVE_UNIX98=1
を指定する。これは、Mutex::Mutex()
中にある pthread_mutexattr_settype()
コールを生かすためのもので、指定しないとデッドロックが起きてしまう。ただしこれは 10.4 での話で、10.3 では実装方法が違うみたい。CFLAGS, CXXFLAGS
に -I$PROJDIR/build/ppc/local/include
が必要。これがないと、giglib のヘッダファイルを見つけてくれない。configure
が生成した Makefile
を見ると GIG_CFLAGS = -I/.../local/include
という1行が確かにあるのだが、これがどこにも使われていない。ちょっと変。
$PROJDIR/build/ppc/local/bin/linuxsampler
ができていれば成功。
ppc 版の時と同様。CFLAGS/CXXFLAGS
に -arch i386 -msse -msse2
を指定することと、configure
に --host=...
を指定するのがポイント。
$PROJDIR/build/i386/local/lib
に libsndfile.a, pkgconfig/sndfile.pc
ができていれば成功。
$PROJDIR/build/i386/local/lib
に libgig.a, pkgconfig/gig.pc
ができていれば成功。
ppc マシン上で i386 版をビルドするときは、--enable-signed-triang-algo=intmathabs --enable-unsigned-triang-algo=intmathabs
というオプションが必要。linuxsampler の configure
では、LFO の処理アルゴリズムを決めるためにベンチマークをやるのだが、ppc マシン上では i386 の実行ファイルを走らせることはできないので、手動でアルゴリズムを決めてやる。ただし、2007/4/11 現在の CVS に含まれる configure.in
はこの点の処理が完全でなく、これらのオプションを与えても config.h
に正しい定義が書き込まれない。従って、configure
が正常に終了した後、config.h
を開いて、CONFIG_SIGNED_TRIANG_ALGO
と CONFIG_UNSIGNED_TRIANG_ALGO
を 5
に #define
するよう手で書き換える。
$PROJDIR/build/i386/local/bin/linuxsampler
ができていれば成功。
2つの linuxsampler バイナリを lipo
で結合する。
Universal Binary になっていることは file
コマンドで確かめることができる。