CMakeでXboxOneのUWPアプリを作る

- GPUデバッガを使っているところ
というわけでXboxOneのUWPアプリをCMakeで作ってみた。SDL2のUWPサポートはCMakeでビルドできないけどその辺は適当に誤魔化した。
ちゃんとGPUデバッガも使用でき、フレームのキャプチャやリプレイもできるようだ。ただし超遅い。黒塗りの矩形を1000個描くだけで30fpsくらいになってしまう。なぜこんなに遅いのかは謎。VSYNCかもしれないけど、手元のマシン(Intel Iris Pro Gen4)でローカル実行するとフレーム時間は2ms(= 500fps)出るので何か間違っている気がする。
現在のCMakeはMS自身の手によってUWPプロジェクトの生成に対応しており、CMake 3.5以降なら

cmake -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0 -G "Visual Studio 14 Win64" \
 c:\cygwin64\home\oku\repos2\grpcore0

のようにCMAKE_SYSTEM_NAMEとCMAKE_SYSTEM_VERSIONを設定してconfigureする( https://cmake.org/cmake/help/v3.5/manual/cmake-toolchains.7.html#cross-compiling-for-windows-10-universal-applications )。どうも-GオプションでWin64を明示的に指定しないとx64のプロジェクトは生成されないようだ。
... とにかくSDL2が動く環境はできたのでやっとゲームの移植に取り掛かれる。。

ハマりポイント

いくつかハマりポイントがあった。

  • プロジェクトのバージョン

最新のWindows SDK previewが必要になるので、Windowsのminimum requirementもInsider用になってしまう。
というわけで、CMakeが生成したソリューションを開いたら、ソリューションを右クリックして"Retarget solution"する。バージョンは10.0.10586.0でOK。

  • resources.pri の生成位置

どうもCMakeの出力するプロジェクトファイルと、XboxのUWPに対応したWindows SDKでは不整合が有るようで、resources.priの出力位置は手修正する必要があった。

    <ProjectPriFullPath>$(ProjectDir)resources.pri</ProjectPriFullPath>

というわけで、ProjectPriFullPathをProjectDirベースに変更する。この値はCMake側にハードコードされているので、プロジェクトが再生成される度に手で修正する必要がある。これをやらないと、Remote machineへのDeployに失敗してしまう。

  • 標準ライブラリのリンク順が変

手でリンカオプションを設定する必要がある。

    # Hey, it's 2016!
    # https://cmake.org/pipermail/cmake-developers/2014-November/023524.html
    set_target_properties(grpcore0
        PROPERTIES
        LINK_FLAGS_RELEASE
        "/nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib"
        )
    set_target_properties(grpcore0
        PROPERTIES
        LINK_FLAGS_RELWITHDEBINFO
        "/nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib"
    )
    set_target_properties(grpcore0
        PROPERTIES
        LINK_FLAGS_DEBUG
        "/nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib"
        )

UWPのクラスを使うには /ZW オプションを渡す必要がある。SDL2の場合は、UWPのプラットフォーム層のうち、C++で書かれているものが該当する。

    # sdl2winrt: Assign /ZW 
    set_source_files_properties(${sdl2winrt}
        COMPILE_FLAGS "/ZW")
  • Deployに失敗したりVSが固まったりする

どうしようもない。Deployの失敗は公式FAQの通りDev mode→Retail mode→Dev modeすれば直ることが多いようだ。
.netアプリではあまり問題が起きていない印象なので、まだまだネイティブ側は開発中というところか。。