Haskell の SDL binding である HSDL を GHC 6.6.1 でコンパイルするための手順メモです。
1. 必要なものをダウンロードします。
HSDL のソースコード、SDL のランタイムライブラリと開発ライブラリ (ヘッダとか) が必要です。
- http://fxp.hp.infoseek.co.jp/haskell/HSDL/ から HSDL-0.2.0.zip と haSDLis.zip
- http://www.libsdl.org/ から SDL-1.2.12-win32.zip と SDL-devel-1.2.12-mingw32.tar.gz
$ ls HSDL-0.2.0.zip SDL-devel-1.2.12-mingw32.tar.gz SDL-1.2.12-win32.zip haSDLis.zip
2. SDL の開発ライブラリを適当なところに展開します。
$ tar xzf SDL-devel-1.2.12-mingw32.tar.gz $ mv SDL-1.2.12/ /usr/local/
ちなみに僕は cygwin を使ってます。/usr/local は C:\cygwin\usr\local です。好きなところに置けばいいと思います。
3. HSDL を展開します。
$ mkdir HSDL $ cd HSDL $ unzip ../HSDL-0.2.0.zip
4. HSDL.cabal を編集します。
ここがポイントです。
- c-sources を消す。
- include-dirs を C:\cygwin\usr\local\SDL-1.2.12\include\SDL にする。
- ld-options を消す。
- extra-lib-dirs を追加し、C:\cygwin\usr\local\SDL-1.2.12\lib にする。
$ cp HSDL.cabal HSDL.cabal.org $ vi HSDL.cabal $ diff HSDL.cabal.org HSDL.cabal 21,24d20 < c-sources: < Multimedia/SDL/Timer_stub.c, < Multimedia/SDL/Event_stub.c, < Multimedia/SDL/Audio_stub.c 28a25,26 > extra-lib-dirs: > C:\cygwin\usr\local\SDL-1.2.12\lib 30,32c28 < /usr/local/include/SDL < ld-options: < -L/usr/local/lib --- > C:\cygwin\usr\local\SDL-1.2.12\include\SDL
5. ビルドします。
README にある通り。
$ runghc Setup.hs configure $ runghc Setup.hs build $ runghc Setup.hs install
6. テトリスをコンパイルして動作確認します。
$ cd .. $ unzip SDL-1.2.12-win32.zip $ mkdir haSDLis $ cd haSDLis $ unzip ../haSDLis.zip $ ghc --make -o test main.hs $ mv ../SDL.dll . $ ./test.exe
その他
そのままコンパイルした場合、hsc2hs が libSDL.a を見つけられずにエラーになったり*1、
$ runghc Setup.hs build Preprocessing library hsdl-0.2.0... C:\cygwin\usr\local\ghc-6.6.1\gcc-lib\ld.exe: cannot find -lSDL collect2: ld returned 1 exit status linking Multimedia\SDL\Audio_hsc_make.o failed command was: C:\cygwin\usr\local\ghc-6.6.1\bin\ghc.exe -lSDL Multimedia\SDL\Audio_hsc_make.o -o Multimedia\SDL\Audio_hsc_make.exe Setup.hs: got error code while preprocessing: Multimedia.SDL.Audio
リンク時にシンボルの重複でエラーになったりします*2。
$ runghc Setup.hs build Preprocessing library hsdl-0.2.0... Building hsdl-0.2.0... [ 1 of 10] Compiling Multimedia.SDL.Util ( Multimedia/SDL/Util.hs, dist\build/Multimedia/SDL/Util.o ) [ 2 of 10] Compiling Multimedia.SDL.Video ( Multimedia/SDL/Video.hs, dist\build/Multimedia/SDL/Video.o ) [ 3 of 10] Compiling Multimedia.SDL.Window ( Multimedia/SDL/Window.hs, dist\build/Multimedia/SDL/Window.o ) [ 4 of 10] Compiling Multimedia.SDL.Timer ( Multimedia/SDL/Timer.hs, dist\build/Multimedia/SDL/Timer.o ) [ 5 of 10] Compiling Multimedia.SDL.Keysym ( Multimedia/SDL/Keysym.hs, dist\build/Multimedia/SDL/Keysym.o ) [ 6 of 10] Compiling Multimedia.SDL.Joystick ( Multimedia/SDL/Joystick.hs, dist\build/Multimedia/SDL/Joystick.o ) [ 7 of 10] Compiling Multimedia.SDL.Init ( Multimedia/SDL/Init.hs, dist\build/Multimedia/SDL/Init.o ) [ 8 of 10] Compiling Multimedia.SDL.Event ( Multimedia/SDL/Event.hs, dist\build/Multimedia/SDL/Event.o ) [ 9 of 10] Compiling Multimedia.SDL.Audio ( Multimedia/SDL/Audio.hs, dist\build/Multimedia/SDL/Audio.o ) [10 of 10] Compiling Multimedia.SDL ( Multimedia/SDL.hs, dist\build/Multimedia/SDL.o ) C:\cygwin\usr\local\ghc-6.6.1\bin\ar.exe: creating dist\build\libHShsdl-0.2.0.a dist\build\Multimedia\SDL\Audio_stub.o(.text+0x0):Audio_stub.c: multiple definition of `MultimediaziSDLziAudio_dq6y' dist\build\Multimedia\SDL\Audio_stub.o(.text+0x0):Audio_stub.c: first defined here dist\build\Multimedia\SDL\Event_stub.o(.text+0x0):Event_stub.c: multiple definition of `MultimediaziSDLziEvent_dkOD' dist\build\Multimedia\SDL\Event_stub.o(.text+0x0):Event_stub.c: first defined here dist\build\Multimedia\SDL\Timer_stub.o(.text+0x0):Timer_stub.c: multiple definition of `MultimediaziSDLziTimer_ddwA' dist\build\Multimedia\SDL\Timer_stub.o(.text+0x0):Timer_stub.c: first defined here dist\build\Multimedia\SDL\Timer_stub.o(.text+0xb5):Timer_stub.c: multiple definition of `MultimediaziSDLziTimer_ddwd' dist\build\Multimedia\SDL\Timer_stub.o(.text+0xb5):Timer_stub.c: first defined here
あと、Haskell の SDL binding としては http://hackage.haskell.org/cgi-bin/hackage-scripts/package/SDL-0.5.0 もあるようです。こっちの方が公式っぽいですが、どっちの方がいいのかはわかりません。ぱっと見ですが、Audio に関しては HSDL の方が呼べる API が多いです*3。いずれにしても、あんまりメンテナンスされてないような気はしました。