glcaml を cygwin で

glcaml という OpenGLocaml binding があったので、cygwin (というか mingw) で遊んでみようと思ったら結構大変でした。メモ。

1. ocamlmingw 用にビルドする

MinGW-based native Win32 port が公開されていますが、そのインストーラだと ...\Objective Caml というスペースの入ったパスにしかインストールできないっぽいです (嫌がらせだろうか) 。昔これではまったことがあるので、自分でビルドしました *1
mingw 用のビルドの仕方は INSTALL には書いてなくて、README.win32 にあります (嫌がらせだろうか) 。ざっと言うと

  • config/ の中のファイルをコピーする
  • config/Makefile の PREFIX を編集してインストール先を指定する
  • config/Makefile の TK_ROOT を編集して tk をインストールしている位置を指定する
  • make -f Makefile.nt ... する

です。詳細は README.win32 を参照のこと。ぼくは labltk は要らなかったので、config/Makefile の OTHERLIBRARIES から labltk を消してみたところ、tk をインストールしないでビルドできました (正しくビルドできてるかは知らない) 。

2. 環境変数を設定する

こんな感じ。/usr/local/ocaml-3.10.2/bin はインストールしたパスにあわせて適当に。

export PATH=/usr/local/ocaml-3.10.2/bin:$PATH
export OCAMLLIB="`cygpath -w /usr/local/ocaml-3.10.2/lib`

3. SDL をインストールする

http://www.libsdl.org/ から SDL-devel-1.2.13-mingw32.tar.gz を落としてきて、展開して移動するだけ。

$ tar xzf SDL-devel-1.2.13-mingw32.tar.gz
$ cd SDL-1.2.13 /usr/local

4. glcaml をビルドする

install.txt に書いてあるように、makefile を編集して「MAKE=make WIN32=true」の行のコメントをはずします。
以下のように CFLAGS と LDFLAGS を指定して make します。

$ make CFLAGS="-I/usr/local/SDL-1.2.13/include -mno-cygwin" \
  LDFLAGS="-L/usr/local/SDL-1.2.13/lib"

ビルドできたら bin 以下に移動して、SDL.dll をコピーします。なんなら C:\WINDOWS\system32 とかにコピーしといてもいいと思います。

$ cd bin
$ cp /usr/local/SDL-1.2.13/bin/SDL.dll .

サンプルを起動して、窓が出れば OK 。

$ ./lesson09.exe

5. ネイティブコードを出力する

デフォルトだとバイトコードが生成されています。この状態だと、音を鳴らすサンプルを起動すると異常終了すると思います。

$ ./audiosample.exe data/sample.wav
(異常終了の窓)

mixer のコールバック関数がマルチスレッドで呼ばれるのですが、どうもバイトコード実行との相性がよくないようでした。ぼくの環境ではネイティブコードにしたらちゃんと動きました。
ネイティブコードを生成するためには、makefile.inc をいじって all: nc という行を書き足します。

--- makefile.inc
+++ makefile.inc
@@ -18,4 +18,5 @@
 CC=gcc
 SOURCES=$(WIN_SOURCE) $(SDL_SOURCE) $(GL_SOURCE) $(EXAMPLE)
 RESULT=$(BINDIR)/$(MLFILE)
+all: nc
 -include OCamlMakefile

include OCamlMakefile の前に書かないとダメ。書き足したら前と同様に make 。

$ make CFLAGS="-I/usr/local/SDL-1.2.13/include -mno-cygwin" LDFLAGS="-L/usr/local/SDL-1.2.13/lib"

今度は音が鳴りました。

$ ./audiosample.exe data/sample.wav

その他

生成されたコードは -mno-cygwin でビルドしているので、cygwin1.dll がない環境でも動くはず。たぶん。

$ objdump -p audiosample.exe | grep dll
        DLL Name: msvcrt.dll
        DLL Name: msvcrt.dll
        DLL Name: KERNEL32.dll
        DLL Name: SDL.dll

こういうのって何か作ろうと思って環境を整えるんだけど、環境が整ったら満足してしまって何も作らないんですよね。だめだめ。何か作ってから公開しようと思ってたけどやっぱり何も作らなそうなので公開。

*1:あとこのインストーラが勝手に環境変数 OCAMLLIB を設定するので、cygwinocaml が動かなくなってはまったことがあるのはぼくだけではあるまい。