覺書: using SDL2 on MSYS2

前置き

MSYS2SDL2を利用するときのあれこれを覺え書きしておく。

導入

pacmanでSDL2のパッケージを導入する。

以下のパッケージも必要に應じて導入する。

R5.3.2追記

UCRT64を使ふ場合は以下に替へる。net、gfx、smpeg2はいまのところ利用してゐないので……。

CMakeを用ゐてのビルドの例

參考とすべく、SDL2日本語リファレンスマニュアルSDL_RenderClearの項に揭載されてゐるサンプルを(微妙に手直しして)CMakeを使つてビルドしてみた。

以下がC++のソースコード(sample.cpp)。

#include <SDL2/SDL.h>

int main(int argc, char* argv[])
{
  /* SDLを初期化する */
  if (SDL_Init(SDL_INIT_VIDEO) < 0)
    return 1;

  /* 描画するウィンドウを生成する */
  SDL_Window* window
    = SDL_CreateWindow(
        "SDL_RenderClear",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        512, 512,
        0);

  /* ウィンドウへの描画で使うSDL_CreateRendererを生成する */
  SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);

  /* 描画の色を選択する. ここでは赤を設定する */
  SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);

  /* 選択した色で画面を消去する */
  SDL_RenderClear(renderer);

  /* 上の描画は全て裏側で行われている
     これで新たに表示され, ウィンドウが赤くなる */
  SDL_RenderPresent(renderer);

  /* ウィンドウを見せるために5秒待つ */
  SDL_Delay(5000);

  /* 全て終了する */
  SDL_Quit();
  return 0;
}

以下がCMakeLists.txt。

cmake_minimum_required(VERSION 3.10)
set(CMAKE_VERBOSE_MAKEFILE 1)
project(sdl2sample CXX)

enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)

add_executable(sdl2_sample WIN32
  sample.cpp
)

target_compile_options(sdl2_sample PRIVATE
  -Wall -O3 ${SDL2_STATIC_CFLAGS}
)

target_link_options(sdl2_sample PRIVATE
  -static
)

target_link_libraries(sdl2_sample ${SDL2_STATIC_LIBRARIES})

PkgConfigとpkg_check_modulesを用ゐてリンクすべきライブラリを自動的に取得するあたりが今回の膽。必要ならsdl2の後にSDL2_mixerとかSDL2_ttfとかを加へればいい筈。

DLL周りの面倒を避けるために靜的リンクをすることを意圖して書いたが、動的DLLリンクをするつもりなら、target_link_optionsから-staticを除去して、${SDL2_STATIC_CFLAGS}を替へて${SDL2_CFLAGS}に、${SDL2_STATIC_LIBRARIES}を替へて${SDL2_LIBRARIES}にすればいい筈。

sample.cppとCMakeLists.txtを同じディレクトリに置いて、以下を實行。

sdl2_sample.exeが出來て、うまく動けば成功。

SDL2_ttfを靜的リンクしようとしたときの羂

SDL2_ttfを用ゐて文字を表示するプログラムを書いたまでは良かつたが、DLL周りの面倒を廻避すべく靜的リンクをしようとした途端、色々出た。

單にfind_package(Freetype REQUIRED)とやつてtarget_link_librariesにFreetypeを追加しただけだと、Freetypeについては動的リンクになる、といふあたりが面倒事の發端。

仕方ないのでFreetypeについてもpkg_check_modulesで參照することにしたが、今度は-lbrotlicommonが無い、-lbrotlidecが無いと叱られる始末。確かめてみると、/mingw64/lib/にはlibbrotlicommon-static.aやlibbrotlidec-static.aは存在するが、-staticの附いてゐないファイルは無い。これが怪しいと踏んだのでシンボリックリンクを作つたが上手くいかない。あれこれ回り道をして到達したのは、シンボリックリンクでは何故か上手くいかないので、コピーを作らねばならない、といふ結論だつた。

回り道の最後の最後に遭遇した事象も記しておかう。SDL2もFreetypeもpkg_check_modulesを使ふのだから、と、pkg_check_modules(SDL2 REQUIRED freetype2 sdl2 SDL2_mixer SDL2_ttf)と纏めて書いたら、何故かシンボル未定義エラーでリンクが通らなかつた。ターミナル畫面を見れば、しつかりと-lfreetypeの字が見えるのだから、わけが分からない。ライブラリの指定順序によつてをかしなことが起こることもあるので、駄目元でpkg_check_modules(SDL2 REQUIRED sdl2 SDL2_mixer SDL2_ttf freetype2)としたらすんなり通つたから、良かつたといへば良かつたのだが、いまいちすつきりしない。

R3.11.24追記

その後の更新により、libbrotli絡みの姑息な手段を用ゐる必要は無くなつた。

SDL2_imageの靜的リンク

pkg_check_modules(SDL2 REQUIRED sdl2 SDL2_image libpng libjpeg libtiff-4)とした。僅かに問題となつたのはlibtiff-4の "-4" くらゐで、後は割とすんなりと行つた氣がする。

R3.11.24追記

その後の更新により、libtiffの參照するlibLercで靜的リンク用の*.aが提供されないために上手くいかないといふ情況になり、結局SDL2_imageを自分でビルドする羽目になつた。

R5.3.2追記

その後の更新により、libLercの靜的リンク用の*.aが復活したやうで、pacmanで取り込んだパッケージでいけるやうになつたと思しい。ただ自前ビルドでインストールしたあれこれを完全に消した狀況で確認できてゐないので何か拔けてゐる可能性はある。