OSX LionでSDLを使いたい、そんな気分 (解決済)

お詫びと注意

この記事のサンプルプログラムにはミスがあります
http://d.hatena.ne.jp/yano-htn/20120219/1329621619
に再まとめがあるのでそっち参照

SDLってなに?

公式サイト
http://www.libsdl.org/index.php

Simple DirectMedia Layerのこと。
マルチプラットフォームで動作し、オーディオやキーボード、マウス、ジョイスティック、3D描画 via OpenGL、2D描画とかを提供するライブラリ。
基本的にC言語で書かれてるけど、PythonとかRubyとかいろいろな言語に移植されてる。
参考:
http://ja.wikipedia.org/wiki/SDL

SDLセットアップ

SDLをインストールする。brew、port、apt、yumとかでもライブラリあると思うけど、
バージョンを最新に揃えたいのでソースから入れる。

入れるのは

  • SDL-1.2.15 : SDL本体
  • SDL_image-1.2.12 : SDLで色々な画像形式を扱うためのライブラリ
  • SDL_sound-1.0.3 : SDLで色々なサウンド形式を扱うためのライブラリ
  • SDL_mixer-1.2.12 : SDLでオーディオを扱うためのライブラリ
  • SDL_ttf-2.0.11 : SDLTrueTypeフォントを扱うためのライブラリ
  • SDL_gtx-2.0.22 : SDLで拡大・縮小・回転といった画像操作を行うためのライブラリ

それぞれ公式サイトのライブラリから探す
# ネットワークが絡むものを作るならSDL_netも入れるといいかも

入れ方はそれぞれをソースを拾ってきて

$ ./configure
$ make
# make install

でおk
...と思ったらSDL_gfxだけうまくインストールできないorz

aclocal-1.10: couldn't open directory `m4': No such file or directory

とか言われる。調べたらm4ディレクトリを手動で作成すればいいみたいなので作成
http://code.google.com/p/ffmpegthumbnailer/issues/detail?id=37

$ mkdir m4

でビルドしたら次は

configure.in:120: error: possibly undefined macro: AM_PATH_SDL

とか出た。
調べたらaclocalでm4ファイルのパス取得に失敗してるっぽいので、
以下のサイトを参考に以下を実行
http://www.geocities.jp/fut_nis/html/automake-ja/Macro-search-path.html

# cd /usr/share/aclocal
# echo "/usr/local/share/aclocal" >> dirlist

公式サイトよく読んだらconfigureの前にautogen.shをやれって書いてあったので、

$ ./autogen.sh
$ ./configure

を実行

...うーん、これでもうまくいかない
仕方が無いのでautogen.shで直接パスを指定するように編集

$ diff autogen.sh autogen.sh.org
6c6< aclocal --force -I /usr/local/share/aclocal

    • -

> aclocal --force
12c12< aclocal -I /usr/local/share/aclocal

    • -

> aclocal
$ ./autogen.sh
$ ./configure
$ make
# make install

今度はうまくいった

動作テスト

試しにソースを書いて動作テストしてみる。

http://ro119.com/archive/tokyo.cool.ne.jp/sdl/
のサイトを参考にウィンドウを出すだけのプログラムを書いてみる。
# 以下のプログラムは返り値判定とか関数名とかいろいろミスってますので動きません

#include <SDL/SDL.h>

#include <iostream>
#include <string>

SDL_Surface* screen;
static const std::string SCREEN_CAPTION = "SDL window test";
static const int SCREEN_WIDTH = 640;
static const int SCREEN_HEIGHT = 640;
static const int SCREEN_BPP = 32;

bool init();
bool finalize();
bool pollingEvent();

int main() {
  // initialize
  if (init()) {
    std::cerr << "ERROR: failed to initialize SDL" << std::endl;
    exit(1);
  }

  // main loop
  while (true) {
    if (pollingEvent()) break;
  }

  // finalize
  finalize();
  
  return 0;
}


bool init() {
  // initialize SDL
  if( SDL_Init(SDL_INIT_VIDEO) < 0 ) return false;

  // set caption of window
  SDL_WM_SetCaption( SCREEN_CAPTION.c_str(), NULL );

  // initialize window
  screen = SDL_SetVideoMode(
                            SCREEN_WIDTH,
                            SCREEN_HEIGHT,
                            SCREEN_BPP,
                            SDL_SWSURFACE // | SDL_FULLSCREEN
                            );

  // vanish mouce cursor
  // SDL_ShowCursor(SDL_DISABLE);

  return true;
}

bool end() {
  // finalize SDL
  SDL_Quit();
}


// polling event and execute actions
bool pollingEvent()
{
  SDL_Event ev;
  SDLKey *key;
  while ( SDL_PollEvent(&ev) )
    {
      switch(ev.type){
      case SDL_QUIT:
        // raise when exit event is occur
        return false;
        break;
      case SDL_KEYDOWN:
        // raise when key down
        {
          key=&(ev.key.keysym.sym);
          // ESC
          if(*key==27){
            return false;
          }
        }
        break;
      }
    }
  return true;
}

コンパイル

g++ `sdl-config --cflags` show_window.cpp `sdl-config --libs`

...コンパイルできない/(^o^)\

$ g++ `sdl-config --cflags` show_window.cpp `sdl-config --libs`
Undefined symbols for architecture x86_64:
"finalize()", referenced from:
SDL_main() in ccBPYxMw.o
"_SDL_main", referenced from:
-[SDLMain applicationDidFinishLaunching:] in libSDLmain.a(SDLMain.o)
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

うーん、ライブラリのビルドの仕方が違うとか?
もうちょっと調べてみる。