Tutorial 127: Choose Platform, Renderer, and Audio Independently

CNA Tutorials  ·  CNA snapshot b0e97bb1

ℹ

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, X11, WAYLAND, WIN32, HEADLESS, TERMINAL — six, but WIN32 is offered only for Windows targets, TERMINAL only off Windows, and X11/WAYLAND only when their development packages are foundSDL3 on every OS
CNA_GRAPHICS_RENDEREROne of 18 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.

Three of the six platforms are native backends that contain no SDL at all — X11 (Xlib, XKB, XInput2, XRandR, GLX), WAYLAND (a direct Wayland client) and WIN32 (user32, gdi32, WGL). They are described in Native Platforms (X11, Wayland, Win32). 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. 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.
CNA_PLATFORM=X11 or WAYLAND when the development packages are missingThe message names the packages to install and explicitly refuses to fall back to SDL3.
CNA_PLATFORM=WIN32 off Windows, 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 18 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: native X11

cmake -S ../cna -B build-x11 \
  -DCNA_ENABLE_SDL=OFF \
  -DCNA_PLATFORM=X11 \
  -DCNA_AUDIO_PLATFORM=NULL \
  -DCNA_GRAPHICS_RENDERER=HEADLESS

This is the configuration the x11-sdl-free CI job builds and tests under Xvfb, and CI then proves that the test executables link no SDL. Swap in -DCNA_AUDIO_PLATFORM=ALSA and a real renderer such as OPENGL33 for sound and pixels (CI’s x11-sdl-free-gpu job also compiles VULKAN, SOFTWARE and HEADLESS in for run-time selection). The X11 backend needs libx11-dev, libxext-dev and X11/XKBlib.h; the rest of the X libraries are optional and each gates one capability. Tutorial 135 walks through it; the audio half is Tutorial 137.

Native Wayland (no CI)

cmake -S ../cna -B build-wayland \
  -DCNA_ENABLE_SDL=OFF \
  -DCNA_PLATFORM=WAYLAND \
  -DCNA_AUDIO_PLATFORM=NULL \
  -DCNA_GRAPHICS_RENDERER=HEADLESS

Needs wayland-client 1.18 or newer, xkbcommon 0.5 or newer, wayland-protocols with stable/xdg-shell, and wayland-scanner. No GitHub workflow builds CNA_PLATFORM=WAYLAND; its tests exist and are run locally. See Tutorial 136 and Native Platforms.

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 native Windows build (CNA_PLATFORM=WIN32) therefore 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 WIN32 is reserved off Windows, TERMINAL 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. Notice what changed since alpha.1: WIN32 and ALSA used to be reserved and are now implemented.

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