Metric Panda Games

One pixel at a time.

Cross compiling for Three Platforms

Rival Fortress Update #11

I’ve moved permanently to Linux as my development platform. I’m in love! Linux is giving me even more freedom from clutter and OS annoyances than what OSX was giving me. How did I ever get by without a tiling window manager!

Fanboyism aside, this week I finally finished the cross compiling setup that I started working on a while back.

Whenever I push commits to the Github repository, an automated build triggers for the three platforms that Rival Fortress will ship on: Windows (32/64bits), Linux (32/64bits) and OSX(64bits).

The build “server” is Mac Mini running a bare bones installation of Arch Linux.

Cross compilation process

The cross compilation process is handled by a simple bash script. The setup step, that is run only once after a clean git clone, initializes Cmake for the 5 “platforms” like so:

# 64 bit builds
if [ ! -d build/linux64 ]; then
  cmake -H. -Bbuild/linux64 -G Ninja -DCMAKE_BUILD_TYPE=Debug

if [ ! -d build/osx ]; then
  cmake -H. -Bbuild/osx -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=cmake/x86_64-osx.cmake

if [ ! -d build/win64 ]; then
  cmake -H. -Bbuild/win64 -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=cmake/x86_64-w64-mingw32.cmake

# 32 bit builds
if [ ! -d build/linux32 ]; then
  CFLAGS=-m32 CXXFLAGS=-m32 cmake -H. -Bbuild/linux32 -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=cmake/i686-linux.cmake

if [ ! -d build/win32 ]; then
  cmake -H. -Bbuild/win32 -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=cmake/i686-w64-mingw32.cmake

Each build, a part from the 64 bit Linux, has a toolchain file associated with it that specifies the compiler to use and the path to libraries and headers.

The 64 bit Linux build doesn’t need a toolchain file since the system is 64 bit and is configured to build by default using Clang 3.8.

The 64 bit Linux also runs first as it is the only build that will run the reflection preprocessor and other build time custom tools that generate code.


I’m using mingw-w64 to build Windows binaries and OSX Cross to build for OSX.

This is the toolchain file I use to compile Windows 64bit binaries:

set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)



Other toolchain files are similar, the only change is x86_64 to i686 and the TOOLCHAIN_PREFIX. You can read more about cross-compiling with Cmake on the docs.

The variable CMAKE_CROSS_COMPILING is used throughout the CMakeLists.txt files to disable running of preprocessing tools I mentioned earlier.


The actual build process is rather simple: the same bash script I mentioned above serially runs Ninja on each folder like so:

  ninja -C build/<platform>

If the build fails the stderr is redirected to a BUILD_ERRORS.txt file that I can later review. Whenever a build breaks for a platform I run the same toolchain on my main development workstation and fix the bugs.

I’m currently building only in debug mode, but when I’ll integrate automated testing for I’ll enable Release mode to. Cross-platform automated testing will be tricky as I’ll probably have to use some form of OS virtualization.

Obviously a successful build doesn’t mean the actual game will run on the target platform, but that will be (hopefully) handled when I implement automated testing.