試行錯誤の結果を紹介。
SDLMain.m/.hの編集
SDLのエントリになるSDLMain.mとSDLMain.hをSDLのsrc/main/macosx/からコピーします。
エントリポイントをHaskellのプログラムから呼び出せるようにSDLMain.mを編集します。
/* BEFORE */ int main (int argc, char **argv) { /* 中略 */ }
/* AFTER */ int sdlMain_ (int argc, char **argv) { /* 中略 */ } void sdlMain(void) /* この関数をHaskellのプログラムから呼び出します */ { char *argv[] = { "" }; sdlMain_(0, argv); }
SDLMain.hにプロトタイプを書きます。
void sdlMain(void);
Haskellの関数を呼び出す関数をSDLMain.mに追加します。
int SDL_main(int argc, char **argv) /* この関数はSDLのメインループから呼び出されます */ { narioMain(); /* この関数はHaskellのプログラムで定義します */ return 0; }
上の関数の宣言されたヘッダファイルの読み込みをSDLMain.mに追加します。このファイルは関数をexportするMain.hsをコンパイルした時に生成されます。
#import "Main_stub.h"
Main.hsの編集
SDLのエントリポイントの呼び出しと、呼び出される関数を定義します。
-- BEFORE main :: IO () main = do -- 以下略
-- AFTER foreign import ccall "SDLMain.h sdlMain" sdlMain :: IO () foreign export ccall narioMain :: IO () main :: IO () main = sdlMain narioMain :: IO () -- mainの名前を変更(SDLのメインループから呼び出される) narioMain = do -- 以下略
Makefileの編集
ghc -o $(PROJECT) --make -O $(SRCS)
SDLMain.mをビルド対象に追加、import/exportできるようにオプションを追加、Cocoaフレームワークをリンクを指定。
ghc -o $(PROJECT) --make -O $(SRCS) SDLMain.m -fglasgow-exts -framework Cocoa
微調整
いろいろ環境を突っ込んでいるせいなのか、パスが通ってないところが2カ所ほどあった。これを修正。
ひとつめ。Main_stub.hがHsFFI.hを読み込めなくなっていた。これのパスを指定。
ふたつめ。SDLMain.mがSDL.hを読み込めなくなっていた。これのパスを指定。
ビルド
これらの編集を経てmakeを実行。
一回目はMain_stub.hのエラーが出るので、上に書いたように変更して、再ビルド。
これで実行ファイルができるはずです。