Tutorial 127: Choose Platform, Renderer, and Audio Independently

CNA Tutorials  ·  CNA snapshot c1c316b9

ℹ

Core idea: this snapshot has four different axes — target operating system, host platform implementation, graphics renderer, and audio implementation — plus one switch that decides whether SDL is configured at all (CNA_ENABLE_SDL). “Backend” is too ambiguous to stand in for any of them.

The three CMake selections (and one switch)

VariableImplemented valuesDefault
CNA_PLATFORMSDL3, HEADLESS, TERMINAL — three, and TERMINAL is offered only off WindowsSDL3 on every OS
CNA_GRAPHICS_RENDEREROne of 14 public identitiesOS-dependent: Emscripten WEBGL2, Linux OPENGLES3, everything else SDL_RENDERER
CNA_AUDIO_PLATFORMSDL3, NULL, ALSA (Linux targets only)SDL3 on every OS
CNA_ENABLE_SDL (switch)AUTO, ON, OFF (also TRUE/1 and FALSE/0/NO)AUTO

CNA_PLATFORM owns window, events, input, timing and host services. The renderer produces pixels. CNA_AUDIO_PLATFORM chooses the audio-device integration boundary. CNA_ENABLE_SDL decides whether the vendored SDL3 sub-build runs: with AUTO or ON SDL is configured as it always was; with OFF it is not fetched, built, found or linked, and any selection that genuinely needs it is refused by name. The compiler/toolchain still decides Linux, Windows, macOS, Emscripten, Android or iOS separately. Platform and audio values are case-sensitive; CNA_ENABLE_SDL is normalised.

SDL3 is the one windowing implementation. It reaches Windows, X11, Wayland, macOS, iOS, Android and the browser through SDL’s own video drivers (SDL_VIDEODRIVER picks one explicitly), and a renderer still receives the native HWND, Display*/Window or wl_display*/wl_surface* through the window’s native handle; Windows, X11 and Wayland has the details. HEADLESS and TERMINAL have no graphical window. There is no CNA_PLATFORM environment variable: one implementation is the compiled default, and the always-compiled Headless (and, off Windows, Terminal) can additionally be created by name at run time through PlatformFactory.

⚠

The three audio choices do not offer the same XNA feature set. SOUND_ENABLED is defined for SDL3 and ALSA. SDL3 uses SDL3_mixer; ALSA uses CNA’s own mixer and no SDL audio. NULL provides a real low-level IAudioDevice implementation, but that build omits the high-level mixer engine, so SoundEffect playback, MediaPlayer, XACT audibility and Microphone are not available. Choose NULL for silent CI, servers and device-boundary work, not as a drop-in production playback replacement. The Audio reference has the full matrix.

Combinations CMake refuses

The axes are independent, with hard exclusions. Every refusal is a configure-time FATAL_ERROR that names the reason; nothing silently falls back to SDL3.

SelectionWhy it is refused
CNA_PLATFORM=TERMINAL with any renderer except SOFTWARE, HEADLESS, STUBA terminal has no graphical native window a GPU API could bind to; it presents finished CPU frames.
CNA_ENABLE_SDL=OFF with platform SDL3, audio SDL3, or renderer SDL_RENDERER/SDL_GPU/FNA3D (also inside CNA_GRAPHICS_RENDERERS)“This configuration genuinely requires SDL”; the message lists which selections do. Because the platform and audio defaults are both SDL3, an SDL-free build must set both explicitly.
The window-system names WIN32, X11 and WAYLAND as a platform valueNot platform implementations: the message points to -DCNA_PLATFORM=SDL3, which reaches those window systems through SDL’s video drivers. Never an alias.
TERMINAL on Windows, SDL12, EMSCRIPTENReserved identifiers, “NOT implemented”. (Emscripten as a target OS is real and served by SDL3.)
CNA_AUDIO_PLATFORM=ALSA on a non-Linux target; OPENAL; WASAPIALSA is Linux-only; the other two are reserved names.
Any unknown value, or a wrong case“Not a known platform” / “not a known audio platform”, listing the available and reserved sets.

A renderer name outside the 14 public identities is refused by the same kind of configure error; see Renderers for the list, and Platform Support for which renderers each target OS offers.

Useful configurations

Default desktop host and audio, explicit renderer

cmake -S ../cna -B build-desktop \
  -DCNA_PLATFORM=SDL3 \
  -DCNA_GRAPHICS_RENDERER=OPENGLES3 \
  -DCNA_AUDIO_PLATFORM=SDL3

No display and no high-level sound engine

cmake -S ../cna -B build-headless \
  -DCNA_PLATFORM=HEADLESS \
  -DCNA_GRAPHICS_RENDERER=HEADLESS \
  -DCNA_AUDIO_PLATFORM=NULL

This is useful for game-logic CI and servers. A headless platform does not secretly force null audio: choose SDL3 (or ALSA) audio if the process should still play sound.

POSIX terminal presentation

cmake -S ../cna -B build-terminal \
  -DCNA_PLATFORM=TERMINAL \
  -DCNA_GRAPHICS_RENDERER=SOFTWARE \
  -DCNA_AUDIO_PLATFORM=NULL

TERMINAL is POSIX-only and accepts exactly three CPU/no-output renderers: SOFTWARE, HEADLESS and STUB. It is not an implemented Windows-console mode. See Tutorial 139.

No SDL at all: a windowless build

cmake -S ../cna -B build-nosdl \
  -DCNA_ENABLE_SDL=OFF \
  -DCNA_PLATFORM=HEADLESS \
  -DCNA_AUDIO_PLATFORM=ALSA \
  -DCNA_GRAPHICS_RENDERER=HEADLESS

This is the configuration CNA’s SDL-free CI job builds; it then proves that the test executables and a demo link no SDL and load libasound at run time rather than linking it. An SDL-free build has no window: use HEADLESS, or TERMINAL with SOFTWARE, as the platform. Use -DCNA_AUDIO_PLATFORM=NULL instead if the machine has no ALSA headers. Tutorial 138 walks through it; the audio half is Tutorial 137.

A specific window system through SDL3

SDL_VIDEODRIVER=wayland ./build-desktop/my_game   # or x11, or windows on Windows

The window system is chosen at run time, not at configure time: SDL picks one for the session, and SDL_VIDEODRIVER forces it. CNA’s platform CI runs the SDL3 platform suite on a private Xvfb and on a private headless Weston. See Tutorial 135, Tutorial 136 and Windows, X11 and Wayland.

SDL3 window, native audio

cmake -S ../cna -B build-alsa \
  -DCNA_PLATFORM=SDL3 \
  -DCNA_AUDIO_PLATFORM=ALSA

Legal: the window stays SDL3 while sound goes through ALSA and CNA’s own mixer. Configure needs the ALSA headers (libasound2-dev). This exact pairing is not exercised by CI.

Where there is no SDL-free audio

On Windows and macOS the only audio choices are SDL3 and NULL, and CNA_ENABLE_SDL=OFF refuses the first. An SDL-free Windows build is windowless (HEADLESS) and has silent NULL audio; OPENAL and WASAPI are reserved names, not implementations.

Reserved names are not support claims

SDL12 and EMSCRIPTEN are reserved platform identifiers (and TERMINAL is reserved on Windows); OPENAL and WASAPI are reserved audio identifiers. This snapshot rejects all of them at configure time. Emscripten as a target OS/toolchain is real, but it is not a CNA_PLATFORM=EMSCRIPTEN implementation.

Verify the configured axes

cmake -LA -N build-headless | grep -E 'CNA_(PLATFORM|GRAPHICS_RENDERER|AUDIO_PLATFORM|ENABLE_SDL)'
ctest --test-dir build-headless -N

The generated test inventory changes with all of these selections and with feature options. Report the values beside test results; a number without its configuration is not reproducible. The configure log also prints CNA: Using <NAME> platform implementation and CNA: Using <NAME> audio platform implementation.

Next steps