Banjo API 1.0.0-rc.2
Low-level C99 game development API
Loading...
Searching...
No Matches
Building Banjo

Produce the Banjo library binaries from source, with or without CMake.

Banjo is not distributed as a package: there's no apt install banjo or equivalent. You either build from source (see below) or grab a pre-built release artifact from the Releases page. Either way the runtime side of every optional backend is dlopen'd, so a binary built on one machine can run on another that has the corresponding system shared object installed.

Prerequisites

You need at least a C99-compliant compiler. Beyond that, Banjo's CMake auto-detects platform backends (window system, audio) and enables each one whose development headers are present at build time. To get a working out-of-the-box build, install the headers up-front.

Debian / Ubuntu / Mint:

sudo apt install libx11-dev libwayland-dev libxkbcommon-dev libasound2-dev

Fedora / RHEL:

sudo dnf install libX11-devel wayland-devel libxkbcommon-devel alsa-lib-devel

Arch:

sudo pacman -S libx11 wayland libxkbcommon alsa-lib

macOS: no extra install. Cocoa and CoreAudio ship with Xcode / the Command Line Tools (xcode-select --install).

Windows: no extra install. Win32 and MME ship with the Windows SDK (MSVC) or the MinGW-w64 toolchain.

Emscripten: install the emsdk toolchain (https://emscripten.org/docs/getting_started/downloads.html).

Per-backend / per-distro breakdown

Banjo's optional backends are loaded at runtime with dlopen so the resulting libbanjo has no link-time dependency on them. However, each backend still needs the matching development headers at build time to compile its source. CMake auto-detects these: if the headers are missing, that backend is simply not built (and BANJO_CONFIG_*_BACKEND defaults to OFF).

Backend Debian / Ubuntu / Mint Fedora / RHEL Arch
X11 libx11-dev libX11-devel libx11
Wayland libwayland-dev + libxkbcommon-dev wayland-devel + libxkbcommon-devel wayland + libxkbcommon
ALSA libasound2-dev alsa-lib-devel alsa-lib

At runtime, the dynamic loader must be able to find the shared object matching whatever backend was enabled (libX11.so.6, libwayland-client.so.0, libxkbcommon.so.0, libasound.so.2, etc.). On a desktop Linux distribution these are present whenever the corresponding subsystem is in use, so this typically requires no extra action.

Manual build (no build system)

Banjo is designed to be built without any complex build system. You only need to feed your compiler with the source files and the correct include paths.

Compile all .c files in src/ and src/posix/ (on Unix) or src/win32/ (on Windows). Do not compile files in backend-specific subdirectories (src/x11/, src/cocoa/, etc.) unless you are enabling that specific backend.

Add inc/ and src/ to your include search path.

Output type:

  • Static library: define BANJO_STATIC.
  • Shared library: define BANJO_EXPORTS (do NOT define BANJO_STATIC).

Example (GCC/Clang static library):

gcc -c src/*.c src/posix/*.c -I inc/ -I src/ -D BANJO_STATIC
ar rcs libbanjo.a *.o

See "Build options" below for the per-backend / per-option list of macros and linker flags.

Build with CMake

Banjo provides a CMake configuration that aims to work out-of-the-box: CMake checks your system for libraries (X11, ALSA, …) and your platform (Windows, macOS), and enables matching backends by default.

Every manual option below has a corresponding CMake option. The naming convention is simple: replace the BJ_ prefix with BANJO_. For example the manual macro BJ_CONFIG_X11_BACKEND becomes the CMake option BANJO_CONFIG_X11_BACKEND.

You can force options ON or OFF to override auto-detection:

cmake -B build -DBANJO_CONFIG_X11_BACKEND=OFF
cmake -B build -DBANJO_CONFIG_PEDANTIC=ON -DBANJO_CONFIG_LOG_COLOR=ON

CMake presets

A CMakePresets.json is shipped at the project root with the configurations used by Banjo's CI/CD pipeline. Using a preset is optional (the manual cmake commands above work the same) but presets give you a shortcut to the exact build CI runs, handy for reproducing failures locally.

Preset Description
ci-linux Linux x86_64 release build with examples and tests (used by the PR build job and the linux release artifact)
cmake --preset ci-linux # configure
cmake --build --preset ci-linux # build
ctest --preset ci-linux # run tests

Build artifacts land under build/ci-linux/ to keep preset outputs isolated from any build/ directory you use manually.

Static vs shared library

Banjo can be built and consumed as either a static or a shared library. The build type is set by CMake options and communicated to producing and consuming code through C macro definitions (in inc/banjo/api.h):

  • BANJO_STATIC is set when building and using a static library; it entirely disables the other macros.
  • BANJO_EXPORTS is set when building (but not using) a dynamic library.
  • BANJO_EXPORT and BANJO_NO_EXPORT expand to compiler-specific attributes for exporting/importing symbols through binary compatibility.

When using CMake you don't set these directly; CMake derives them from BUILD_SHARED_LIBS. The default (unset) is a static library.

Build options

You can customize the build by enabling backends or configuration options. To enable an option manually, define the corresponding C macro and compile any required additional sources.

Option Name Description
Win32 backend Enable Win32 window support
X11 backend Enable X11 window support
Wayland backend Enable Wayland window support (Linux)
Cocoa backend Enable Cocoa/macOS support
MME backend Enable Windows Multimedia Extensions audio
ALSA backend Enable ALSA audio support
CoreAudio backend Enable CoreAudio support
Emscripten backend Enable Emscripten/WebAssembly support
Fake backend Always-available no-op fallback (default ON)
Coloured logs Enable ANSI coloured log output
Log Checks Failing checks are logged
Abort on Check Failing checks call abort()
Pedantic Mode Prioritise safety over performance
Fast Math Enable fast-math optimisations

Per-backend / per-option details:

Win32 backend

Additional source files: src/win32/video.c

Compiler Compiler Flags Linker Flags
MSVC /D BJ_CONFIG_WIN32_BACKEND user32.lib gdi32.lib kernel32.lib
GCC/Clang -D BJ_CONFIG_WIN32_BACKEND -luser32 -lgdi32 -lkernel32

Banjo also calls LoadLibrary("dwmapi.dll") at runtime to resolve DwmFlush for vsync-paced event polling, so there is no link-time dependency on dwmapi. dwmapi.dll ships with every Windows Vista or newer install; on stripped SKUs where it is missing, the backend still works but poll runs uncapped.

X11 backend

Additional source files: src/x11/video.c

Compiler Compiler Flags Linker Flags
GCC/Clang -D BJ_CONFIG_X11_BACKEND (none, dlopen'd at runtime)

Banjo loads libX11.so.6 with dlopen, so libbanjo has no link-time dependency on libX11. The X11 development headers are needed at build time only (see Prerequisites), and libX11.so.6 must be discoverable by the dynamic loader on the target machine. On glibc < 2.34, add -ldl when linking the final executable.

Wayland backend

Additional source files: src/wayland/video_wayland.c, src/wayland/wayland-protocol.c, src/wayland/xdg-shell-protocol.c

Compiler Compiler Flags Linker Flags
GCC/Clang -D BJ_CONFIG_WAYLAND_BACKEND (none, dlopen'd at runtime)

Banjo loads libwayland-client.so.0 and libxkbcommon.so.0 with dlopen, so libbanjo has no link-time dependency on either. The Wayland and xkbcommon development headers are needed at build time only (see Prerequisites), and both shared objects must be discoverable by the dynamic loader on the target machine. The Wayland protocol glue (core wayland and xdg-shell) is vendored into the project as pre-generated wayland-scanner output, so neither wayland-scanner nor wayland-protocols is needed at build time. On glibc < 2.34, add -ldl when linking the final executable.

Cocoa backend

Additional source files: src/cocoa/video.m

Compiler Compiler Flags Linker Flags
GCC/Clang -D BJ_CONFIG_COCOA_BACKEND -framework Cocoa -framework CoreVideo

CoreVideo provides CVDisplayLink, which the backend uses for vsync-paced event polling. Both frameworks ship with every macOS install.

CoreAudio backend

Compiler Compiler Flags Linker Flags
GCC/Clang -D BJ_CONFIG_COREAUDIO_BACKEND -framework AudioToolbox

MME backend

Additional source files: src/mme/audio.c

Compiler Compiler Flags Linker Flags
MSVC /D BJ_CONFIG_MME_BACKEND (none, loaded at runtime)
GCC/Clang -D BJ_CONFIG_MME_BACKEND (none, loaded at runtime)

Banjo calls LoadLibrary("winmm.dll") at runtime and resolves waveOut* entry points dynamically, so there is no link-time dependency on winmm. winmm.dll ships with Windows.

ALSA backend

Additional source files: src/alsa/audio.c

Compiler Compiler Flags Linker Flags
GCC/Clang -D BJ_CONFIG_ALSA_BACKEND (none, dlopen'd at runtime)

Banjo loads libasound.so with dlopen, so libbanjo has no link-time dependency on libasound. The ALSA development headers are needed at build time only, and libasound.so.2 must be discoverable by the dynamic loader on the target machine.

Emscripten backend

Additional source files: src/emscripten/video.c and src/emscripten/audio.c

Compiler Compiler Flags Linker Flags
Emscripten -D BJ_CONFIG_EMSCRIPTEN_BACKEND ‘-sEXPORTED_RUNTIME_METHODS=['ccall’,'cwrap','_malloc','_free'] -sEXPORTED_FUNCTIONS=['_bj_emscripten_audio_process'] -sALLOW_MEMORY_GROWTH`

Fake backend

The always-available no-op fallback. Implements the full video and audio vtables with in-memory bitmaps and silence, so initialisation cannot fail even on a headless host with no display server or sound card. Enabled by default; leaving it on is recommended.

Additional source files: src/fake/video_fake.c and src/fake/audio_fake.c

Compiler Compiler Flags Linker Flags
Any -D BJ_CONFIG_FAKE_BACKEND (none)

Logging, checks, and math

Macro Effect
BJ_CONFIG_LOG_COLOR Enable ANSI colour codes in log output
BJ_CONFIG_CHECKS_LOG A failing bj_check logs an error message
BJ_CONFIG_CHECKS_ABORT A failing bj_check calls abort()
BJ_CONFIG_PEDANTIC Enable extra runtime checks (slower, stricter)
BJ_CONFIG_FASTMATH Enable floating-point optimisations that may violate IEEE 754

For fast math, GCC/Clang also need -ffast-math -ffp-contract=fast -fno-math-errno -fno-trapping-math; MSVC needs /fp:fast.

Troubleshooting (build)

CMake says "X11 backend: OFF" on a box that has X11. The runtime library (libx11-6) is installed but the development headers are not. Install libx11-dev (or your distro's equivalent, see Prerequisites).

cmake --build asks for Ninja. You're using a preset that selects Ninja, or you passed -G Ninja. Banjo's presets pin Unix Makefiles. Use the shipped presets or pass -G "Unix Makefiles" explicitly.

clang-tidy fails with cert-err33-c. A return value is being silently discarded. Fold the return into your control flow rather than suppressing with (void): see the Error Management topic for the recipe.

Test binary reports "Potential leaks detected". The test harness's mock_allocators counts every bj_malloc / bj_free and fails the suite if the totals don't match. Look at the most recent TEST_CASE for a missing bj_destroy_* / bj_clear_error / matching bj_free.

See also
Using Banjo