SDL2のビルド環境構築

Linux/osx/Windows上のSDL2アプリケーションをビルドする環境の構築手順を記載します。

 

1 Linuxの場合


1.1 ubuntu-14.04

SDL2のパッケージが用意されているのでそれを使います。

sudo apt-get install -y libsdl2-dev libsdl2-image-dev \
libsdl2-mixer-dev libsdl2-net-dev libsdl2-ttf-dev

1.2 ubuntu-12.04

SDL2のパッケージが用意されていないので、自分でビルドしてインストールします。

SDLのビルド環境を利用して、SDL2のビルド環境を整えます。

sudo apt-get build-dep -y libsdl1.2-dev libsdl-image1.2-dev \
libsdl-mixer1.2-dev libsdl-net1.2-dev libsdl-ttf2.0-dev

SDL2のソースコードを取得します。

wget https://www.libsdl.org/release/SDL2-2.0.3.tar.gz
wget https://www.libsdl.org/projects/SDL_image/release/SDL2_image-2.0.0.tar.gz
wget https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.0.tar.gz
wget https://www.libsdl.org/projects/SDL_net/release/SDL2_net-2.0.0.tar.gz
wget https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-2.0.12.tar.gz

SDL2-2.0.3をビルドしてインストールします。

configureで–prefixを指定しない場合、/usr/localディレクトリ配下にインストールされます。

tar zxvf SDL2-2.0.3.tar.gz
cd SDL2-2.0.3
./configure && make && sudo make install

SDL2-2.0.3をインストールすることで、他のパッケージも同様にconfigure、make、sudo make installでインストールできます。


1.3 SDL2がない他のディストリビューション

SDL2がないディストリビューションでも、ubuntu-12.04のように、SDLのビルド環境を利用すれば、SDL2のビルドは容易です。



2 osxの場合

portやhomebrewでインストールします。

sudo port install libsdl2 libsdl2_image libsdl2_mixer \
libsdl2_net libsdl2_ttf

SDL2のサイトからdmgファイルをダウンロードしてインストールすることも可能ですが、sdl2-configが含まれておらず、コンパイル時にインクルードパスとライブラリの設定を追加する必要がある為、portやhomebrewの方をお勧めします。



3 Windowsの場合

MinGWとVisual Studioを用いる方法があります。

ここではMinGWとeclipseを用いた方法を説明します。


3.1 MinGW

MinGWはgcc、g++、make等のツールチェインを提供するものです。

sdl2-configはUnix系シェルスクリプトで記述されている為、別途bash等が必要で、Cygwinをインストールする必要があります。

sdl2-configを使用せず、コンパイル時に自分でインクルードパスとライブラリのパスを設定すればCygwinは必要になりません。

今回はeclipseの設定でインクルードパスとライブラリのパスを設定します。


3.2 MinGWのインストール

MinGWをダウンロードページから入手します。

インストーラを起動します。パスはデフォルトだとC:\MinGWになります。


https://dl-web.dropbox.com/s/5f9vh1b4zedtgfo/0001_MinGW-Install.png



Continueを2回押すと、パッケージの選択画面になります。ここでg++等を選択し、Apply Changesを実行します。実行後、再度Applyボタンを押せばインストールが開始されます。


https://dl-web.dropbox.com/s/zxfuce1kympxqfr/0002_MinGW-Package.png



環境変数PathにC:\MinGW\binを追加しておきます。


https://dl-web.dropbox.com/s/m2039jnosiii23v/0003_MinGW-Path.png



環境変数Pathを反映する為、一度マシンを再起動します。


3.3 JDKのインストール

eclipseはJavaで動作している為、JDKをインストールする必要があります。

JDKのダウンロードページからWindows向けのインストーラを入手します。


https://dl-web.dropbox.com/s/f32c982pqrqf1hr/0004_JDK-Download.png



インストーラのガイドに沿ってインストールを完了させます。


https://dl-web.dropbox.com/s/toe14za326i114m/0005_JDK-Install.png



3.4 SDL2のインストール

SDL2SDL2_imageSDL2_mixerSDL2_netSDL2_ttfのページからMinGW開発用のアーカイブをダウンロードします。

各アーカイブを展開すると、i686-w64-mingw32とx86_64-w64-mingw32というフォルダが生成されています。

BUGS.txt     INSTALL.txt     README.txt        include
x86_64-w64-mingw32
COPYING.txt  Makefile        WhatsNew.txt      lib
CREDITS.txt  README-SDL.txt  i686-w64-mingw32  test

私の環境ではi686-w64-mingw32を使用しました。

i686が32bit用、x86_64が64bit用だと思うのですが、上記のMinGWインストーラでインストールされるコンパイラが32bitのものであるようで、i686でないとリンクエラーになってしまいました。


i686-w64-mingw32フォルダの中身を一つのフォルダにまとめます(それぞれのフォルダに対して、インクルードパスとライブラリのパスを個別に設定するならば、別々でも構いません)。

まとめると以下のようになります(i686-w64-mingw32をSDLという名前に変更してます)。

eclipseにて、このフォルダのincludeにインクルードパスを、libにライブラリのパスを設定します。また、binは実行時に必要なdllが格納されています。

SDL
├── bin
│   ├── LICENSE.FLAC.txt
│   ├── LICENSE.freetype.txt
│   ├── LICENSE.jpeg.txt
│   ├── LICENSE.mikmod.txt
│   ├── LICENSE.modplug.txt
│   ├── LICENSE.ogg-vorbis.txt
│   ├── LICENSE.png.txt
│   ├── LICENSE.smpeg.txt
│   ├── LICENSE.tiff.txt
│   ├── LICENSE.webp.txt
│   ├── LICENSE.zlib.txt
│   ├── SDL2.dll
│   ├── SDL2_image.dll
│   ├── SDL2_mixer.dll
│   ├── SDL2_net.dll
│   ├── SDL2_ttf.dll
│   ├── libFLAC-8.dll
│   ├── libfreetype-6.dll
│   ├── libjpeg-9.dll
│   ├── libmikmod-2.dll
│   ├── libmodplug-1.dll
│   ├── libogg-0.dll
│   ├── libpng16-16.dll
│   ├── libtiff-5.dll
│   ├── libvorbis-0.dll
│   ├── libvorbisfile-3.dll
│   ├── libwebp-4.dll
│   ├── sdl2-config
│   ├── smpeg2.dll
│   └── zlib1.dll
├── include
│   └── SDL2
│       ├── SDL.h
│ <snip>
│       └── close_code.h
├── lib
│   ├── libSDL2.a
│   ├── libSDL2.dll.a
│   ├── libSDL2.la
│   ├── libSDL2_image.a
│   ├── libSDL2_image.dll.a
│   ├── libSDL2_image.la
│   ├── libSDL2_mixer.a
│   ├── libSDL2_mixer.dll.a
│   ├── libSDL2_mixer.la
│   ├── libSDL2_net.a
│   ├── libSDL2_net.dll.a
│   ├── libSDL2_net.la
│   ├── libSDL2_test.a
│   ├── libSDL2_ttf.a
│   ├── libSDL2_ttf.dll.a
│   ├── libSDL2_ttf.la
│   ├── libSDL2main.a
│   └── pkgconfig
│       ├── SDL2_image.pc
│       ├── SDL2_mixer.pc
│       ├── SDL2_net.pc
│       ├── SDL2_ttf.pc
│       └── sdl2.pc
└── share
    └── aclocal
        └── sdl2.m4

私の環境ではこのSDLというフォルダをC:\Users\hiroom2\Documentsに格納しています。


3.5 SDL_platform.hの修正

SDL2-2.0.3ではMinGW使用時にSDL_platform.hでコンパイルエラーが出る為、以下の修正を加えます。

本修正はリポジトリにある最新のSDL2では反映済みです。

diff -uprN SDL2-2.0.3.org/x86_64-w64-mingw32/include/SDL2/SDL_platform.h SDL2-2.0.3/x86_64-w64-mingw32/include/SDL2/SDL_platform.h
--- SDL2-2.0.3.org/x86_64-w64-mingw32/include/SDL2/SDL_platform.h 2014-03-16 11:34:41.000000000 +0900
+++ SDL2-2.0.3/x86_64-w64-mingw32/include/SDL2/SDL_platform.h 2015-05-07 16:18:44.000000000 +0900
@@ -114,10 +114,10 @@
 #define __SOLARIS__ 1
 #endif
 
-#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
+#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
 /* Try to find out if we're compiling for WinRT or non-WinRT */
 /* If _USING_V110_SDK71_ is defined it means we are using the v110_xp or v120_xp toolset. */
-#if defined(__MINGW32__) || (defined(_MSC_VER) && (_MSC_VER >= 1700) && !_USING_V110_SDK71_) /* _MSC_VER==1700 for MSVC 2012 */
+#if (defined(_MSC_VER) && (_MSC_VER >= 1700) && !_USING_V110_SDK71_) /* _MSC_VER==1700 for MSVC 2012 */
 #include <winapifamily.h>
 #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
 #undef __WINDOWS__

3.6 eclipseのインストール

eclipseのページからEclipse IDE for C/C++ Developersをダウンロードします。

アーカイブを解凍し、eclipseを起動します。

c++のプロジェクトを作成し、MinGWをコンパイラとして選択します。


https://dl-web.dropbox.com/s/l8a9apxsun5rny2/0006_Eclipse-Project.png



プロジェクトのプロパティにて、インクルードパスを追加します。


https://dl-web.dropbox.com/s/6q1q7iobkrtpt69/0007_Eclipse-IncludePath.png



ライブラリのパスを追加します。


https://dl-web.dropbox.com/s/n5e05az8j86lgm4/0008_Eclipse-LibraryPath.png



ライブラリを追加します。

mingw32、SDL2main、SDL2の前後関係に注意してください。

SDL_imageはlibjpeg等を前にして、SDL_imageを後にすれば良いでしょう。

他のSDL2プロジェクトも同様だと思います。


https://dl-web.dropbox.com/s/9po8b7rmw607gsc/0009_Eclipse-Library.png



Run Configurationsにて、実行時に参照するdllのパスを設定します。


https://dl-web.dropbox.com/s/db2w32askow1u70/0010_RunConfigurations.png



4 ビルドの確認

Linuxとosxの場合はMakefileを利用します。

sdl2-configを用いてインクルードパスとライブラリのパスを設定します。

PROG := $(patsubst %.cc,%,$(wildcard *.cc))
CXXFLAGS += -I. -std=c++0x $(EXTRA_CXXFLAGS)
CXXFLAGS += $(shell sdl2-config --cflags)
LDFLAGS += $(shell sdl2-config --libs)
LDLIBS += -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer -lpthread -ldl

all: $(PROG)

clean:
$(RM) -rf $(PROG) *.dSYM

以下のソースコードをビルドできるか確認します。

#include <iostream>
#include <SDL.h>

int main(int argc, char *argv[])
{
  if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
    std::cerr << "SDL_Init: " << SDL_GetError() << std::endl;
    return 1;
  }

  SDL_Quit();
  return 0;
}

4.1 main関数とlibSDL2main.aについて

ios、android、windowsの場合、プリプロセッサによってmain関数をSDL_main関数に置き換えられる為、main関数は以下の書式である必要があります。

int main(int argc, char *argv[])
#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE)
#define main    SDL_main
#endif

/**
 *  The prototype for the application's main() function
 */
extern C_LINKAGE int SDL_main(int argc, char *argv[]);

これはプログラム開始用の関数がmain関数でない処理系の為のものです。

プログラム開始用の関数はlibSDL2main.aで実装されています。

libSDL2main.aで定義されたプログラム開始用の関数からSDL_main関数が呼び出されます。

main関数からプログラムが開始する処理系の場合はlibSDL2main.aを必要としません。