CVSスナップショットからのビルド(コマンドライン編)

(2007/04/24)

 LinuxSampler の CVS 最新版をそのままビルドして Universal Binary ができるようにしてみた。当然 CVS 最新版は開発途中の版なので、不安定であることは承知しておくこと。

1. 準備

 ディレクトリ構成を決めておく。ここでは、後述の libsndfile のビルドも含めて1つのディレクトリ(以下 $PROJDIR とする。例えば PROJDIR=$HOME/Development/LinuxSampler)の中で全部済ませることにする。

 LinuxSampler の公式サイトから libgig と linuxsampler の最新版をとってくる。

$ cd $PROJDIR
$ cvs -z3 -d:pserver:anonymous@cvs.linuxsampler.org:/var/cvs/linuxsampler co libgig
$ cvs -z3 -d:pserver:anonymous@cvs.linuxsampler.org:/var/cvs/linuxsampler co linuxsampler

 libsndfile もソースをとってきて、同じディレクトリ中で展開しておく。

$ curl -o libsndfile-1.0.17.tar.gz http://www.mega-nerd.com/libsndfile/libsndfile-1.0.17.tar.gz
$ tar xvfz libsndfile-1.0.17.tar.gz

2. Autoconf のやり方

 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 としてインストールされている。このままでは、次のようにつまづいてしまう。

$ cd $PROJDIR/libgig
$ make -f Makefile.cvs
make: libtoolize: Command not found
make: *** [configure] Error 127

 ちょっと強引だが、/usr/bin/glibtoolize へのシンボリックリンクを /usr/local/bin/libtoolize として作成し、パスに /usr/local/bin を入れる。これで一応 make -f Makefile.cvs は通るようになる。

$ PATH=/usr/local/bin:$PATH
$ sudo ln -sf /usr/bin/glibtoolize /usr/local/bin/libtoolize
$ make -f Makefile.cvs
configure.in: installing `./install-sh'
configure.in: installing `./mkinstalldirs'
configure.in: installing `./missing'
src/Makefile.am: installing `./depcomp'

 こういう変更は他の部分に影響を及ぼす可能性があるので要注意である。ただ、libtool は NeXTSTEP 由来の同名のツールが /usr/bin にあるので厄介だが、libtoolize は名前はぶつからないので一応大丈夫みたい。

 ところが、これで作成した configure を走らせると、途中で止まってしまう。

$ ./configure
./configure: line 18460: syntax error near unexpected token `SNDFILE,'
./configure: line 18460: `PKG_CHECK_MODULES(SNDFILE, sndfile >= 1.0.2, ac_cv_sndfile=1, ac_cv_sndfile=0)'

 これは 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 にコピーし、実行許可をつけておく。

$ sudo cp aclocal /usr/local/bin/aclocal
$ sudo chmod +x /usr/local/bin/aclocal

 ちなみに、このファイルの中身は次の2行。同じことで悩んだ人が他にもいたのだろうか。

#!/bin/sh
/usr/bin/aclocal -I /usr/local/share/aclocal $@

 ここまで準備してしまえば、あとは libgig, linuxsampler それぞれのディレクトリで make -f Makefile.cvs とすれば、configure および関連ファイルが作成される。

$ cd $PROJDIR/libgig
$ make -f Makefile.cvs
$ cd $PROJDIR/linuxsampler
$ make -f Makefile.cvs

3. ビルドの方針

 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 installsudo がいちいち必要ないので好都合である。

 具体的には、次のようなディレクトリ構成にする。

$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 でコピーしているが、本当はシンボリックリンクにするべきである。

4. Universal Binary 作成のための注意点

 ADCTN2137: 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行で):

$ env CFLAGS="$CFLAGS -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc" ./configure

 i386 バイナリ(全部1行で):

$ env CFLAGS="$CFLAGS -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch -i386 -msse -msse2" ./configure --host=i386-apple-darwin8

 --host=.... を(configure を走らせているマシンと)違うものに指定すると、クロスコンパイルと見なされ、configure 中に作成したプログラムの実行がスキップされる。また、コンパイラフラグの -msse, -msse2 は、CarbonCore.h をインクルードした時に起きるエラーを回避するためのもの。

 なお、PPC Mac ではクロスコンパイルのために MacOSX10.4u.sdk が必要。これは ADC のサイトからダウンロードすることができる。Intel Mac では、システムのライブラリがすでに UB 化されているため -isysroot ... は必要ないはず(Intel Mac を持っていないので確かめられないが)。

5. PPC 版のビルド

 それではまず PPC 版をビルドしてみる。

5-1. libsndfile

 configure の時に、インストール場所として $PROJDIR/build/ppc/local--prefix オプションで指定しておく。

$ mkdir -p $PROJDIR/build/ppc/local
$ cp -rf $PROJDIR/libsndfile-1.0.17 $PROJDIR/build/ppc/
$ cd $PROJDIR/build/ppc/libsndfile-1.0.17
$ SYSROOT="-isysroot /Developer/SDKs/MacOSX10.4u.sdk" # Intel Mac では不要?
$ export CFLAGS="$SYSROOT -O3 -arch ppc"
$ export CXXFLAGS="$CFLAGS"
$ ./configure --prefix="$PROJDIR/build/ppc/local" --disable-shared
$ make
$ make install

 $PROJDIR/build/ppc/local/liblibsndfile.a, pkgconfig/sndfile.pc ができていれば成功。

5-2. libgig

 configure に先と同じ --prefix オプションに加えて、環境変数として PKG_CONFIG_PATH=$PROJDIR/build/ppc/local/lib/pkgconfig を指定する。こうしないと、さきほどインストールした libsndfile.a を見つけられず、失敗する。

$ cp -rf $PROJDIR/libgig $PROJDIR/build/ppc/
$ cd $PROJDIR/build/ppc/libgig
$ export CFLAGS="$SYSROOT -O3 -arch ppc"
$ export CXXFLAGS="$CFLAGS"
$ ./configure --prefix="$PROJDIR/build/ppc/local" --disable-shared PKG_CONFIG_PATH=$PROJDIR/build/ppc/local/lib/pkgconfig
$ make
$ make install

 $PROJDIR/build/ppc/local/liblibgig.a, pkgconfig/gig.pc ができていれば成功。

5-3. linuxsampler

 configure に先と同じ --prefix, PKG_CONFIG_PATH=... 指定に加えて、次の指定が必要。

$ cp -rf $PROJDIR/linuxsampler $PROJDIR/build/ppc/
$ cd $PROJDIR/build/ppc/linuxsampler
$ export CFLAGS="$SYSROOT -O3 -arch ppc -I$PROJDIR/build/ppc/local/include"
$ export CXXFLAGS="$CFLAGS"
$ ./configure --prefix=$PROJDIR/build/ppc/local --disable-shared PKG_CONFIG_PATH=$PROJDIR/build/ppc/local/lib/pkgconfig HAVE_UNIX98=1
$ make
$ make install

 $PROJDIR/build/ppc/local/bin/linuxsampler ができていれば成功。

6. i386 版のビルド

6-1. libsndfile

 ppc 版の時と同様。CFLAGS/CXXFLAGS-arch i386 -msse -msse2 を指定することと、configure--host=... を指定するのがポイント。

$ mkdir -p $PROJDIR/build/i386/local
$ cp -rf $PROJDIR/libsndfile-1.0.17 $PROJDIR/build/i386/
$ cd $PROJDIR/build/i386/libsndfile-1.0.17
$ SYSROOT="-isysroot /Developer/SDKs/MacOSX10.4u.sdk" # Intel Mac では不要?
$ export CFLAGS="$SYSROOT -O3 -arch i386 -msse -msse2"
$ export CXXFLAGS="$CFLAGS"
$ ./configure --prefix="$PROJDIR/build/i386/local" --disable-shared --host=i386-apple-darwin8
$ make
$ make install

 $PROJDIR/build/i386/local/liblibsndfile.a, pkgconfig/sndfile.pc ができていれば成功。

6-2. libgig

$ cp -rf $PROJDIR/libgig $PROJDIR/build/i386/
$ cd $PROJDIR/build/i386/libgig
$ export CFLAGS="$SYSROOT -O3 -arch i386 -msse -msse2"
$ export CXXFLAGS="$CFLAGS"
$ ./configure --prefix="$PROJDIR/build/i386/local" --disable-shared --host=i386-apple-darwin8 PKG_CONFIG_PATH=$PROJDIR/build/i386/local/lib/pkgconfig
$ make
$ make install

 $PROJDIR/build/i386/local/liblibgig.a, pkgconfig/gig.pc ができていれば成功。

6-3. linuxsampler

 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_ALGOCONFIG_UNSIGNED_TRIANG_ALGO5#define するよう手で書き換える。

$ cp -rf $PROJDIR/linuxsampler $PROJDIR/build/i386/
$ cd $PROJDIR/build/i386/linuxsampler
$ export CFLAGS="$SYSROOT -O3 -arch i386 -msse -msse2 -I$PROJDIR/build/i386/local/include"
$ export CXXFLAGS="$CFLAGS"
$ ./configure --prefix=$PROJDIR/build/i386/local --disable-shared --enable-signed-triang-algo=intmathabs --enable-unsigned-triang-algo=intmathabs --host=i386-apple-darwin8 PKG_CONFIG_PATH=$PROJDIR/build/i386/local/lib/pkgconfig HAVE_UNIX98=1
# ここで config.h を書き換える
$ make

 $PROJDIR/build/i386/local/bin/linuxsampler ができていれば成功。

7. Universal Binary の作成

 2つの linuxsampler バイナリを lipo で結合する。

$ mkdir -p $PROJDIR/build/UB
$ cd $PROJDIR/build
$ lipo -create ppc/local/bin/linuxsampler i386/local/bin/linuxsampler -output UB/linuxsampler

 Universal Binary になっていることは file コマンドで確かめることができる。

$ file UB/linuxsampler
UB/linuxsampler: Mach-O fat file with 2 architectures
UB/linuxsampler (for architecture ppc): Mach-O executable ppc
UB/linuxsampler (for architecture i386): Mach-O executable i386