Building CNA

CMake-based build system  ·  C++23 required

Step 1 - Clone and initialise submodules

git clone https://github.com/openeggbert/cna.git
cd cna
git submodule update --init --recursive

This populates third_party/SDL, third_party/SDL_image, and third_party/SDL_mixer. After this step, SDL is built from source by the CMake build - no system SDL packages are required.

Step 2 - Select a backend and build

CNA requires exactly one rendering backend to be selected at configuration time via -DCNA_GRAPHICS_BACKEND=<BACKEND>. Available backends: SDL_RENDERER, EASYGL, BGFX, VULKAN.

Linux - EasyGL (OpenGL) backend

cmake -S . -B build -DCNA_GRAPHICS_BACKEND=EASYGL
cmake --build build --target CNA CnaTests

Requires ../easy-gl to be present alongside the CNA repository.

Linux - SDL_Renderer backend

cmake -S . -B build-sdlrenderer -DCNA_GRAPHICS_BACKEND=SDL_RENDERER
cmake --build build-sdlrenderer --target CNA CnaTests

Windows - SDL_Renderer backend (MSVC)

On Windows with MSVC 2022 opened from a Developer Command Prompt:

git submodule update --init --recursive
cmake -S . -B build-win -DCNA_GRAPHICS_BACKEND=SDL_RENDERER
cmake --build build-win --target CNA CnaTests

Linux → Windows cross-compilation (MinGW-w64)

# Install the cross toolchain (Debian/Ubuntu)
sudo apt install mingw-w64

git submodule update --init --recursive
cmake -S . -B build-windows \
      -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/mingw-w64.cmake \
      -DCNA_GRAPHICS_BACKEND=SDL_RENDERER
cmake --build build-windows --target CNA CnaTests

bgfx backend

cmake -S . -B build-bgfx -DCNA_GRAPHICS_BACKEND=BGFX
cmake --build build-bgfx --target CNA

bgfx is fetched via CMake FetchContent - no separate clone needed. Implementation is ongoing; not all features are complete.

Vulkan backend

cmake -S . -B build-vulkan -DCNA_GRAPHICS_BACKEND=VULKAN
cmake --build build-vulkan --target CNA

The Vulkan backend is CNA's second-most mature backend: full 2D and 3D pipeline, all five stock effects (pixel-tested), instancing, MRT, MSAA 4×, FillMode::WireFrame, and Texture3D/TextureCube. Open gaps: BlendState Requires a Vulkan-capable GPU and driver. Vulkan SDK headers must be present (usually via your distribution's vulkan-headers / libvulkan-dev package).

Emscripten / WebAssembly (EasyGL + WebGL 2)

# 1. Install and activate the Emscripten SDK
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
cd ..

# 2. Configure and build
cmake -S cna -B build-wasm \
      -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
      -DCNA_GRAPHICS_BACKEND=EASYGL
cmake --build build-wasm --target CNA

Output files are .html, .js, and .wasm. Serve them from a local web server — browsers block direct file:// access due to CORS. FFmpeg video (VideoPlayer) is excluded on this target. Assets must be preloaded via Emscripten's --preload-file linker flag.

Android (SDL_Renderer backend, Android NDK)

cmake -S . -B build-android \
      -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
      -DANDROID_ABI=arm64-v8a \
      -DANDROID_PLATFORM=android-21 \
      -DCNA_GRAPHICS_BACKEND=SDL_RENDERER
cmake --build build-android --target CNA

SDL3's native Android JNI/Activity layer is used. Set ANDROID_NDK to your NDK path. The build has been validated on Android hardware with the SDL_RENDERER backend. Sensor (Accelerometer) and touch input need runtime validation on an Android device.

Optional: use system-installed SDL

By default CNA builds SDL3 from the vendored submodules. If you prefer to link against system SDL3 packages, pass -DCNA_USE_SYSTEM_SDL=ON:

cmake -S . -B build -DCNA_USE_SYSTEM_SDL=ON -DCNA_GRAPHICS_BACKEND=SDL_RENDERER
cmake --build build --target CNA CnaTests

This calls find_package for SDL3, SDL3_image, and SDL3_mixer. The packages must be installed (e.g. via your distribution's package manager).

Running the tests

ctest --test-dir build --output-on-failure

Running the demos

# Hello-triangle verification target (EasyGL / SDL_RENDERER)
cmake --build build --target hello-triangle-sdl

# House 3D demo (EasyGL backend)
cmake --build build --target cna_house3d_demo
./build/cna_house3d_demo

# 2D demo
cmake --build build --target cna_demo_2d
./build/cna_demo_2d

Tested compiler matrix

PlatformCompilerBackendStatus
Linux x86_64GCC 12+EASYGL, SDL_RENDERERTested
Linux x86_64Clang 15+EASYGL, SDL_RENDERERTested
Windows x86_64MSVC 2022SDL_RENDERERPlanned
Windows x86_64MinGW-w64SDL_RENDERERPlanned
Linux → WindowsMinGW-w64 (cross)SDL_RENDERERVerified (Wine)

CMake options reference

OptionValuesDefaultDescription
CNA_GRAPHICS_BACKENDSDL_RENDERER, EASYGL, BGFX, VULKANSDL_RENDERERSelects the rendering backend for this build.
CNA_USE_SYSTEM_SDLON, OFFOFFLink against system SDL3 packages instead of vendored submodules.
CNA_BGFX_BUILD_SHADERCON, OFFOFFBuild bgfx's shaderc shader compiler tool (only relevant for BGFX backend; needed to recompile bgfx shaders from GLSL source).

Troubleshooting

sharp-runtime not found

CNA requires sharp-runtime to be present as a sibling directory:

parent/
├── cna/
└── sharp-runtime/

Clone sharp-runtime next to CNA and re-run CMake configuration.

easy-gl not found (EASYGL backend)

The EASYGL backend requires easy-gl as a sibling directory. Clone it alongside CNA or switch to SDL_RENDERER if you do not need OpenGL.

Submodule directories empty

Run git submodule update --init --recursive from the repository root. If this fails, check your network and that the submodule URLs in .gitmodules are accessible.

Vulkan: no Vulkan device found

The Vulkan backend requires a Vulkan-capable GPU and driver. On Linux, install libvulkan-dev and ensure your GPU driver provides a Vulkan ICD (check with vulkaninfo). On virtual machines without GPU passthrough, Vulkan is generally not available.

EASYGL: OpenGL context creation failed

The EasyGL backend requires OpenGL ES 3.0 (or OpenGL 3.0+ desktop with ES emulation). On Linux, ensure your GPU driver is installed and your display server is running. On headless CI servers, use a software renderer such as LIBGL_ALWAYS_SOFTWARE=1 or Mesa's llvmpipe.

bgfx: FetchContent download fails

The BGFX backend fetches bgfx.cmake via CMake's FetchContent during configuration. This requires an internet connection. If you are behind a proxy, set the https_proxy environment variable before running CMake.