エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

narioをMac OS Xで動かした

試行錯誤の結果を紹介。

準備

おとといのエントリを参考に、GHCSDL、HSDL、narioを準備してください。

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のエラーが出るので、上に書いたように変更して、再ビルド。

これで実行ファイルができるはずです。