Tutorial 20: Building and Running Your Game
CNA uses CMake as its build system. This tutorial covers release builds for Linux and Windows, the ctest sanity check, WebAssembly via Emscripten, Android APK packaging, and a CMakeLists.txt install target that bundles your game with its assets.
CMake release build (Linux)
## Configure a release build with the EasyGL backend
cmake -S . -B build-release \
-DCMAKE_BUILD_TYPE=Release \
-DCNA_GRAPHICS_BACKEND=EASYGL
## Build only your game target (faster than building everything)
cmake --build build-release --target MyGame --parallel
## Run
./build-release/MyGame
Release mode enables -O3 (GCC/Clang) or /O2 (MSVC) and strips debug symbols. Expect 3–10x faster rendering on CPU-bound scenes compared to Debug.
ctest sanity check
Before shipping, run the CNA test suite to confirm your dependencies and build configuration are sane:
cmake --build build-release --target CnaTests
ctest --test-dir build-release --output-on-failure --parallel 4
All 4,373 unit tests should pass. If any fail, your compiler or CNA version may be incompatible.
Windows executable
:: Configure (PowerShell or cmd.exe)
cmake -S . -B build-win-release ^
-DCMAKE_BUILD_TYPE=Release ^
-DCNA_GRAPHICS_BACKEND=EASYGL
:: Build
cmake --build build-win-release --target MyGame --config Release
:: Run
build-win-release\Release\MyGame.exe
On Windows with MSVC, SDL3.dll is placed alongside the executable automatically by the build system. No additional DLL redistribution steps are required for self-contained distribution.
Linux executable packaging
For distributing to end users on Linux, bundle your executable with its assets:
# In CMakeLists.txt — install target
install(TARGETS MyGame DESTINATION .)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/assets DESTINATION .)
install(FILES ${CMAKE_SOURCE_DIR}/README.txt DESTINATION .)
# Build the install tree
cmake --install build-release --prefix dist/linux-x64
# dist/linux-x64/ now contains:
# MyGame
# assets/
# README.txt
For AppImage packaging, run linuxdeploy on the install prefix. For Flatpak, add a CNA module to your manifest and point to the install prefix.
Emscripten WebAssembly build
CNA supports Emscripten 3.1+ for web deployment. You need the Emscripten SDK installed and activated (source emsdk_env.sh).
## Configure with the Emscripten toolchain
emcmake cmake -S . -B build-web \
-DCMAKE_BUILD_TYPE=Release \
-DCNA_GRAPHICS_BACKEND=EASYGL \
-DCNA_PLATFORM=WEB
## Build
cmake --build build-web --target MyGame
## Output files:
## build-web/MyGame.js
## build-web/MyGame.wasm
## build-web/MyGame.html (auto-generated shell page)
## build-web/MyGame.data (packaged assets)
Assets are packaged into the .data file by Emscripten's --preload-file mechanism. In your CMakeLists.txt:
if(EMSCRIPTEN)
set_target_properties(MyGame PROPERTIES
SUFFIX ".html"
LINK_FLAGS
"-s USE_SDL=3 \
-s USE_SDL_IMAGE=3 \
-s USE_SDL_MIXER=3 \
-s ASYNCIFY \
-s ALLOW_MEMORY_GROWTH=1 \
--preload-file ${CMAKE_SOURCE_DIR}/assets@/assets"
)
endif()
Serve the output directory with any HTTP server — browsers block file:// access to .wasm files:
cd build-web
python3 -m http.server 8080
# Open http://localhost:8080/MyGame.html
Android APK overview
Android support in CNA uses SDL3's Android build infrastructure. The high-level steps are:
- Install Android NDK r25+ and Android SDK with API level 24+.
- Copy the SDL3 Android project template from
third_party/SDL/android-project/. - Configure the Gradle build to reference your CNA library as a native dependency.
- Place assets in
src/main/assets/. - Run
./gradlew assembleReleaseto produce an APK.
## CMake cross-compile for Android ARM64
cmake -S . -B build-android \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=arm64-v8a \
-DANDROID_PLATFORM=android-24 \
-DCNA_GRAPHICS_BACKEND=EASYGL \
-DCNA_PLATFORM=ANDROID \
-DCMAKE_BUILD_TYPE=Release
cmake --build build-android --target MyGame
See the Platforms documentation for a full step-by-step Android setup guide.
Packaging assets with CPack
CPack can produce a ZIP, DEB, or NSIS installer automatically:
## CMakeLists.txt additions for CPack
set(CPACK_PACKAGE_NAME "MyGame")
set(CPACK_PACKAGE_VERSION "1.0.0")
set(CPACK_PACKAGE_VENDOR "My Studio")
set(CPACK_GENERATOR "ZIP;DEB") # or NSIS on Windows
include(CPack)
install(TARGETS MyGame DESTINATION bin)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/assets DESTINATION share/MyGame)
## Generate the package
cmake --build build-release --target package
## Output:
## build-release/MyGame-1.0.0-Linux.zip
## build-release/MyGame-1.0.0-Linux.deb
Full CMakeLists.txt example
cmake_minimum_required(VERSION 3.20)
project(MyGame VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Pull in CNA (assumes sibling directory layout)
add_subdirectory(../cna cna-build)
add_executable(MyGame
src/main.cpp
src/MyGame.cpp
src/states/MainMenuState.cpp
src/states/GameplayState.cpp
)
target_link_libraries(MyGame PRIVATE CNA)
# Copy assets to build dir for development convenience
add_custom_command(TARGET MyGame POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets $<TARGET_FILE_DIR:MyGame>/assets
)
# Install rules
install(TARGETS MyGame DESTINATION .)
install(DIRECTORY assets DESTINATION .)
# CPack
set(CPACK_PACKAGE_NAME "MyGame")
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
set(CPACK_GENERATOR "ZIP")
include(CPack)