Repository navigation
Build System and CMake Modules
SparkEngine uses CMake 3.25+ as its build system with documented options, cross-platform presets, and CI/CD integration.
Source: CMakeLists.txt, cmake/, CMakePresets.json, Tools/buildmatrix/
Release boundary: Presets and compiler paths document configuration coverage, not certification. Only Windows 11 x64 with MSVC v143 is declared in
stable-v1, and that profile remains blocked and uncertified. Linux, macOS, MinGW/Wine, other compiler lines, and non-D3D11 graphics paths stay outside it.
- CMake 3.25+
- C++23 standard (enforced via
cxx_std_23, no extensions) - CMP0091 policy for consistent MSVC runtime library selection
Native compiler metadata is build-directory state. Keep a build directory tied
to one CMake executable, generator, compiler, and toolset; never configure it
concurrently or switch CMake installations in place. If any of those inputs
change, use a new directory or cmake --fresh so compiler ABI and feature
detection run again. The supported Windows preset selects Visual Studio 17
2022, x64, and v143, but does not pin CMake/MSVC/Windows SDK patch versions.
# Windows (Visual Studio 2022)
.\generate.bat -g "Visual Studio 17 2022" release
# Linux (Ninja)
./generate.sh release -g Ninja
# Direct CMake
cmake -B build -G "Visual Studio 17 2022" -A x64 -T v143
# Using presets (recommended)
cmake --fresh --preset windows-release
cmake --build --preset windows-releasecmake -B build [options]
│
├── Check CMake version (>= 3.25)
├── Set C++23 standard (no extensions)
├── Apply CMP0091 policy (MSVC runtime)
│
├── Evaluate declared CMake options
│ ├── consumed options alter definitions, dependencies, or selected targets
│ └── inert cache variables do not remove a subsystem (tracked by HEAD-220)
│
├── Detect platform and compiler
│ ├── MSVC → /W4, MSVC runtime selection
│ ├── GCC → -Wall -Wextra
│ └── Clang → -Wall -Wextra
│
├── Configure targets (SparkEngineLib, SparkEngine, SparkGame, ...)
├── Include component libraries (cmake/SparkComponentLibraries.cmake)
├── Configure tests (if BUILD_TESTS=ON)
└── Generate build files
Only options declared and consumed by the current root CMakeLists.txt have a
proven build effect. The table below intentionally avoids undocumented pseudo-options.
Undeclared options fail configure (CI-120). The last command of the root
CMakeLists.txt is spark_reject_undeclared_options() from
cmake/SparkOptionGuard.cmake. Any ENABLE_*, SPARK_* or BUILD_* cache entry
that is still UNINITIALIZED after the whole tree has configured -- i.e. it was
passed as an untyped -DNAME=VALUE (or a preset string value) and nothing ran
option()/set(... CACHE ...) for it -- stops configure with a FATAL_ERROR
listing each name and the cmake -U NAME <build-dir> command to drop it. A typo
such as -DENABLE_EDTIOR=OFF, or an option that only exists on another platform,
can therefore no longer configure "successfully" with the default feature set.
Explicitly typed entries (-DNAME:BOOL=ON, or a preset boolean/typed value) are
checked too: spark_capture_cli_options(), the first command after
cmake_minimum_required(), returns every guarded entry that still carries CMake's
command-line helpstring to UNINITIALIZED, so option() adopts it like an untyped
entry and an undeclared one reaches the final check. Options that are declared but
never read (no if(), ${}, generator expression, forwarded -D or
configure_file template consumes them) are reported by
Tools/buildmatrix/check_parity.py as the blocking declared-option-unread
finding (the inert ENABLE_GRAPHICS was deleted on that basis). Options that
must be accepted on every platform are declared
unconditionally: SPARK_REQUIRE_WINDOWS_INSTALLERS (SparkBuild passes it
everywhere; ON off Windows is itself fatal) and the explicit
SPARK_MODULE_CXX_LANGUAGE_ABI override (declared by cmake/SparkGameModule.cmake).
Tests/Tools/test_build_option_guard.py (CTest BuildOptions_UnknownOptionRejected)
configures a fixture project through the real module (typed and untyped -D
entries, and a typed preset) and audits every cache variable in CMakePresets.json
against the tree's declarations.
| Option | Root default | Source-backed effect when disabled |
|---|---|---|
ENABLE_VULKAN |
ON | Disables Vulkan discovery and omits SPARK_VULKAN_SUPPORT; root source glob remains |
ENABLE_OPENGL |
ON | Disables OpenGL discovery/enablement; verify host context separately |
ENABLE_METAL |
ON on Apple, OFF elsewhere | Omits Metal enablement on Apple development builds |
ENABLE_DXR |
ON | Skips DXR shader compilation and hardware-RT definition setup |
ENABLE_HYBRID_RT |
ON | Omits SPARK_HYBRID_RT and its hardware-RT definition setup |
ENABLE_NETWORKING |
ON | Omits networking definition/libraries from SparkEngineLib; service targets use ENABLE_SERVER_PROCESSES
|
SPARK_HEADLESS_SUPPORT |
ON | Omits the compile definition; host entry sources are still listed |
ENABLE_EDITOR |
ON | Omits the SparkEditor target |
BUILD_TESTS |
ON | Omits test targets |
BUILD_GAME_MODULES |
ON | Omits in-tree game-module targets |
The minimal preset disables networking, DXR, and the optional tool and module
targets. Every preset cache variable is a declared root option (the option guard
rejects anything else), but disabling them does not remove the graphics/RHI
sources, so this is not a core-only build contract. Disable declared targets such as the editor explicitly
when needed; HEAD-220 tracks a true stripped/headless configuration.
cmake --preset minimal
cmake -B build -DENABLE_EDITOR=OFFBuild with OpenGL enabled for CPU-based software rendering via Mesa llvmpipe:
# Install dependencies
sudo apt-get install -y libgl-dev libx11-dev
# Configure with OpenGL backend
cmake -B build -DENABLE_OPENGL=ON -DBUILD_TESTS=ON
# Build
cmake --build build --config Release
# Run with software rendering (no GPU required)
Xvfb :99 -screen 0 1024x768x24 &
DISPLAY=:99 LIBGL_ALWAYS_SOFTWARE=1 ./build/bin/SparkEngineThe GLAD OpenGL loader is bundled in ThirdParty/glad/. A bare
RHIFactory::CreateDevice call does not retry a failed backend, but runtime
RHIBridge::Initialize retries its available GPU candidates after device or
swap-chain setup fails and creates NullRHIDevice only after all candidates
fail. That no-render resilience path is in stable-v1 only on Windows 11 x64;
other hosts are uncertified.
SparkEngine now tracks third-party dependency metadata in ThirdParty/dependencies.lock (single source of truth).
Each manifest row declares:
- dependency name + upstream source URL/repo,
- exact pinned version/tag/commit,
- license,
- local path,
- fallback/shim behavior (
SPARK_HAS_*macro + stub/fallback path).
cmake/SparkThirdPartyAudit.cmake is invoked from root CMakeLists.txt early in configure and:
- validates required files exist for each declared dependency,
- prints source/version/license summary during configure,
- warns on manifest mismatches; with
-DSPARK_STRICT_DEPS=ONevery locked entry is required and any missing dependency or pin mismatch fails configure (see ThirdParty Dependencies Audit).
CI enforces manifest hygiene via tools/check-thirdparty-manifest-sync.sh: dependency path/URL/version wiring changes must include a matching ThirdParty/dependencies.lock update.
cmake -G "Visual Studio 17 2022" -A x64 -T v143 ... # VS 2022
cmake -G "Visual Studio 18 2026" -A x64 ... # VS 2026 (v145 default)Toolset and platform are generator inputs; select them with -T/-A or the preset toolset/architecture fields, not project cache variables.
CMakePresets.json provides ready-made configurations:
Preset availability is configuration coverage, not release certification. The
Windows 11 x64/v143 line is the only toolchain family in stable-v1, which remains
blocked; Linux and MinGW/Wine rows are development paths outside the profile.
| Preset | Generator | Compiler | Config | Notes |
|---|---|---|---|---|
windows-debug |
VS 2022 | MSVC | Debug | Full features |
windows-release |
VS 2022 | MSVC | Release | Full features |
linux-gcc-debug |
Ninja | GCC | Debug | Full features |
linux-gcc-release |
Ninja | GCC | Release | Full features |
linux-clang-debug |
Ninja | Clang | Debug | Full features |
linux-clang-release |
Ninja | Clang | Release | Full features |
ci-linux-asan |
Ninja | GCC | Debug | AddressSanitizer + UBSan |
ci-linux-tsan |
Ninja | GCC | Debug | ThreadSanitizer |
linux-mingw-release |
Makefiles | MinGW-w64 | Release | Cross-compile the Windows D3D11 path; D3D12/DXR are excluded; run under Wine |
linux-mingw-debug |
Makefiles | MinGW-w64 | Debug | Cross-compile the Windows D3D11 path; D3D12/DXR are excluded; run under Wine |
minimal |
Default | Default | Release | Core runtime with optional tools, modules, scripting, networking, and experimental rendering breadth disabled |
# List available presets
cmake --list-presets
# Configure and build with a preset
cmake --preset windows-release
cmake --build --preset windows-releaseEvery preset writes build/<preset>, and the Visual Studio presets are
multi-config, so a tree built or tested without --config/-C produces Debug.
tools/site-data/documented_commands.py (run by tools/site-data/validate.py
and the BuildOptions_DocumentedCommandsMatchPresets CTest) resolves every
cmake/ctest/cpack command in the shell code blocks and inline code spans
of every root-level Markdown page (README.md, CLAUDE.md, TROUBLESHOOTING.md,
CONTRIBUTING.md, AGENTS.md, ...), wiki/, docs/, .github/prompts/, the
Copilot instructions, the .claude/skills/ and .codex/skills/ runbooks, and the
Markdown under SparkBuild/, SparkSDK/, FuzzerTests/, GameModules/ and
Templates/ against CMakePresets.json. A cd is followed: cd MyGame then
cmake -B build configures MyGame/build, not the root build, and cd into
the directory a documented git clone created is the repository root. It fails
when:
-
--presetnames no visible preset of that family; - a build, install, test or package tree (
cmake --build/--install,ctest,cpack --config <tree>/CPackConfig.cmake, or the directory acdentered) is neither a presetbinaryDirnor configured earlier in the document with-Bor a repository configure script (generate.sh,generate.bat,build.shandbuild.ps1all configurebuild); - a block that configured presets then uses any other tree, including another
preset's (the classic
cmake --preset <name>thencmake --build build); - an ad-hoc
-Bconfigure writes into a preset's tree; - a multi-config preset tree omits its preset's configuration (a preset with no
generator counts as multi-config unless its condition pins a non-Windows host,
because Visual Studio is the Windows default), or any stated
configuration differs from it.
cmake --installandcpackdefault a multi-config tree to Release, so they may omit it only for a Release preset;--buildandctestdefault to Debug; - an ad-hoc configure with a generator the presets use omits the
-A/-Tvalues those presets pin (-A x64 -T v143for VS 2022;-T v143,host=x64states the same toolset). A generator no preset uses has no pin to compare.
Placeholders (<preset>, $VAR, ~) and absolute paths are skipped. Generated
pages (docs/api/, wiki/reference/, the readiness handoff), dated plans
under docs/superpowers/ and the CHANGELOG.md history are out of scope.
The build-matrix tooling uses CMake File API replies to prove which targets a concrete build profile actually configured. The capture command creates a unique stateful File API query, invokes the canonical configure itself, and records only the matching reply transaction before inventory generation:
python3 Tools/buildmatrix/capture_provenance.py \
--profile windows-shipping \
--build-dir build/windows-shipping
python3 Tools/buildmatrix/inventory.py \
--codemodel windows-shipping=build/windows-shipping \
--output docs/readiness/build-matrix-inventory.json
python3 Tools/buildmatrix/check_parity.py \
--inventory docs/readiness/build-matrix-inventory.json \
--baseline docs/readiness/build-matrix-parity-findings.jsonThe capture step requires an exactly clean repository, derives the commit itself, creates the query before configuring, and binds the profile, source/build directories, CMake executable and version, generator, cache values, and exact index/codemodel/cache/target reply digests. Inventory rejects missing, malformed, oversized, linked, out-of-directory, changed, unbound, or post-hoc reply data. Caller-supplied commit text is not provenance, and missing material fields or expected cache values remain blocking findings.
The local record detects reply substitution but cannot authorize itself. The Windows Shipping build matrix job records that evidence and succeeds; it never attests anything. The Build Matrix Verifier workflow (.github/workflows/build-matrix-verifier.yml) runs afterwards from the exact current Working default-branch checkout, binds one successful source run/job/artifact through the Actions API, downloads by immutable artifact ID with digest mismatch failure, reparses the File API replies as bounded data, rehashes every declared product, reconstructs the inventory and parity report with trusted code, attests only the resulting verified receipt, and posts the Build Matrix Verifier / Exact Source commit status. Work item CI-120 stays open until a verifier run on Working proves this path end to end.
The repository can cross-compile Windows D3D11 code paths on a Linux host using MinGW-w64 for development evaluation. The resulting .exe files run under Wine, with DXVK translating D3D11 calls to Vulkan (or WineD3D as fallback). Combined with Mesa Lavapipe, this exercises D3D11 paths without a GPU; it does not certify D3D11 or a Linux host for stable-v1.
Full guide: See Cross-Compilation: Wine Testing for complete setup, troubleshooting, and the automated test suite.
# 1. Install prerequisites
sudo apt-get install mingw-w64 wine64 mesa-vulkan-drivers
# 2. Install DirectXMath headers (MinGW doesn't ship them)
# See the full guide for download instructions
sudo cp DirectX*.h DirectX*.inl /usr/x86_64-w64-mingw32/include/
# 3. Build
cmake --preset linux-mingw-release
cmake --build build/linux-mingw-release --parallel $(nproc)
# 4. Run tests under Wine
tools/wine-run.sh build/linux-mingw-release/bin/SparkTests.exe
# 5. Run automated test suite (7 phases)
python3 tools/test-windows-wine.py --build-dir build/linux-mingw-release5 Windows executables + game module DLLs: SparkEngine.exe, SparkEditor.exe, SparkTests.exe, SparkConsole.exe, SparkShaderCompiler.exe
- D3D12 excluded (MinGW headers too old for ID3D12Device5/DXR)
-
D3D11 paths exercised under Wine + DXVK; this is outside
stable-v1and not certification - DirectXMath must be installed manually to the MinGW sysroot
-
-municoderequired forwWinMainUnicode entry point
| File | Purpose |
|---|---|
cmake/toolchains/mingw-w64-x86_64.cmake |
CMake toolchain for MinGW cross-compilation |
tools/wine-run.sh |
Wine runner with DXVK/VKD3D-Proton auto-setup |
tools/test-windows-wine.py |
Automated 7-phase Wine test suite |
CMakePresets.json |
linux-mingw-release / linux-mingw-debug presets |
The routes below are configuration/development paths, not universal host
certification. RHIBridge::Initialize tries the available GPU candidates in
order after device or swap-chain failure, then creates NullRHIDevice if none
succeeds; the bare RHIFactory::CreateDevice operation has no retry loop. The
bridge does not probe every conceptual backend row regardless of what was
compiled or made available.
| Backend | Platform | Software Fallback |
|---|---|---|
| D3D11 | Windows | WARP route where explicitly selected by the backend |
| D3D12 | Windows | WARP adapter route where explicitly selected by the backend |
| Vulkan | Host/runtime dependent | A CPU ICD such as Lavapipe, only when installed and selected |
| OpenGL | Linux development | Mesa llvmpipe with the required EGL/GLX/display setup |
| Metal | macOS | No software fallback declared |
| None | Host-independent implementation | Explicit NullRHIDevice; no pixels are rendered |
RHIDeviceCapabilities contains an isSoftwareDevice field, but that field is
not evidence of automatic fallback or uniform runtime probing.
| Target | Type | Description |
|---|---|---|
SparkEngineLib |
Static library | Core engine systems (all subsystems linked here) |
SparkEngine |
Executable | Runtime host (loads game modules) |
SparkGame |
Shared library | Default game module DLL |
| SparkEditor | Executable | ImGui visual editor with Windows and experimental non-Windows build paths |
| SparkConsole | Executable | Debug console with named-pipe transport on Windows and bidirectional inherited stdio transport elsewhere |
SparkShaderCompiler |
Executable | Offline HLSL/GLSL shader compilation tool |
SparkTests |
Executable | Unit test runner (when BUILD_TESTS=ON) |
uninstall |
Custom target | Manifest-driven removal of the last full cmake --install (see below) |
cmake --install <build> records every file it writes in
<build>/install_manifest.txt (install_manifest_<component>.txt for a
--component install). cmake/SparkUninstall.cmake removes exactly those files:
cmake --build <build> --target uninstall # full install into CMAKE_INSTALL_PREFIX
cmake -DPREFIX=<prefix> -DMANIFEST=<build>/install_manifest_runtime.txt \
-P cmake/SparkUninstall.cmake # --prefix or --component installsEvery manifest entry is validated before anything is deleted. The helper refuses
the whole manifest if any entry is relative, not normalized, outside the prefix,
a link, a directory, or under a parent that resolves outside the prefix. It also
refuses a manifest containing a semicolon or an entry with unbalanced square
brackets (CMake list handling would merge it with its neighbors), and a
filesystem-root prefix. Entries that are already gone are skipped, so a second
uninstall succeeds. Directories are pruned only when they are left empty, so data
written under the prefix after install (saves, settings, caches) survives. The
emptiness check escapes glob metacharacters, so a prefix such as
C:/Games [Beta] is listed literally rather than read as a pattern. DESTDIR is
applied as cmake --install applies it: the manifest holds unstaged paths, and a
leading drive letter is dropped before DESTDIR is prepended. The DESTDIR stage is
tested on Linux; the drive-letter mapping has not yet run on a Windows host. The vendored SDL2 uninstall target is disabled
(SDL2_DISABLE_UNINSTALL) because it deletes manifest paths without these checks.
SparkTrackedInstall.Contract covers the contract. It runs two install,
reinstall and uninstall cycles, asserts that reinstall is byte-identical and that
only declared user data remains, and checks the adversarial manifests, a
DESTDIR stage, and a prefix containing glob metacharacters with user data inside
an installed directory. This is local CMake-tree evidence only. Windows CPack/NSIS
uninstall and SparkInstaller are separate and not yet qualified (ASSET-220,
INST-130).
build/
├── bin/ # Executables and DLLs
│ ├── SparkEngine.exe
│ ├── SparkGame.dll
│ ├── SparkEditor.exe
│ ├── SparkConsole.exe
│ └── SparkTests.exe
├── lib/ # Static libraries (.lib / .a)
│ └── SparkEngineLib.lib
├── Shaders/ # Compiled shader bytecode
└── Assets/ # Game assets (copied from source tree)
SparkBuild is an in-tree C++17 terminal-UI wrapper around CMake. The source lives at SparkBuild/ (vendored from the now-archived Krilliac/SparkBuild; see SparkBuild/UPSTREAM.md for the pinned commit). It is built as part of the normal engine build under the ENABLE_SPARKBUILD option (ON by default).
Output: build/<preset>/bin/SparkBuild (or build/<preset>/bin/<Config>/SparkBuild.exe on Windows).
cmake --preset linux-gcc-release
cmake --build build/linux-gcc-release --target SparkBuild
./build/linux-gcc-release/bin/SparkBuildBecause SparkBuild only shells out to cmake, it has no dependency on any SparkEngine header or library — so in-tree hosting introduces no circular build dependency. To skip it:
cmake -B build -DENABLE_SPARKBUILD=OFF ...Source: cmake/SparkGameModule.cmake
Provides spark_add_game_module() for creating game module DLLs:
include(cmake/SparkGameModule.cmake)
spark_add_game_module(MyGame ${GAME_SOURCES})| Step | Action |
|---|---|
| 1 | Creates a SHARED library from provided sources |
| 2 | Defines SPARK_MODULE_DLL and SPARK_GAME_DLL compile definitions |
| 3 | Links against Spark::SparkEngineLib (private) |
| 4 | Sets SDK include directories (SPARK_ENGINE_INCLUDE_DIR, Spark/, SparkEngine/) |
| 5 | Enforces C++23 via target_compile_features(cxx_std_23)
|
| 6 | On MSVC: sets runtime library to MultiThreaded$<$<CONFIG:Debug>:Debug>DLL
|
See Creating a Game Module for a complete usage guide.
Source: cmake/SparkEnginePreflight.cmake
Validates that a SparkEngine SDK installation is complete before find_package runs. Include it in standalone projects to get clear error messages when required files are missing.
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../cmake")
include(SparkEnginePreflight)
find_package(SparkEngine REQUIRED)The spark_preflight_check() function searches candidate directories and verifies:
| Required File | Purpose |
|---|---|
SparkEngineConfig.cmake |
CMake package configuration |
SparkEngineTargets.cmake |
Imported target definitions for Spark::SparkEngineLib
|
SparkGameModule.cmake |
Game module helper function |
If any file is missing, it emits a FATAL_ERROR with the exact missing path and remediation steps (re-run cmake --install).
Source: cmake/SparkComponentLibraries.cmake
Defines per-subsystem OBJECT library targets that partition the monolithic SparkEngineLib into fine-grained component libraries.
include(cmake/SparkComponentLibraries.cmake)
spark_define_component_libraries()| Target | Sources | Dependencies | Description |
|---|---|---|---|
SparkCore |
Core/*.cpp/.h |
-- | Platform, EngineContext, Assert, Logger |
SparkUtils |
Utils/*.cpp/.h |
SparkCore | Console, Profiler, JobSystem, Octree |
SparkECS |
Engine/ECS/**/*.cpp/.h |
SparkCore | Components, Systems, World, ReactiveSystem |
SparkGraphics |
Graphics/**/*.cpp/.h |
SparkCore, SparkUtils | GraphicsEngine, RHI, Shaders, PostProcessing |
SparkPhysics |
Engine/Physics/**/*.cpp/.h |
SparkCore, SparkECS | PhysicsSystem, Jolt Physics integration |
SparkAudio |
Engine/Audio/**/*.cpp/.h |
SparkCore, SparkECS | AudioEngine, XAudio2 |
SparkAI |
Engine/AI/**/*.cpp/.h |
SparkCore, SparkECS, SparkUtils | AISystem, BehaviorTree, NavMesh |
SparkAnimation |
Engine/Animation/**/*.cpp/.h |
SparkCore, SparkECS | Skeleton, Clips, Blending, IK |
SparkNetworking |
Engine/Networking/**/*.cpp/.h |
SparkCore | NetworkManager, Transport |
# Before (monolithic)
target_link_libraries(MyTarget PRIVATE SparkEngineLib)
# After (component-based — link only what you need)
target_link_libraries(MyTarget PRIVATE SparkECS SparkGraphics SparkPhysics)SparkEngineLib remains as an umbrella target that links all components for backward compatibility.
On non-Windows producers, this helper detects libc++ or libstdc++ from the
selected standard-library headers for each configuration. It rejects ambiguous
or mixed-family configurations. The selected family is exported as C++ compile
and link requirements on SparkEngineLib and SparkEngineInterface, so installed
consumers retain the producer's standard-library choice. Windows keeps its
existing CRT/toolset contract.
SDKCxxRuntime_ExportContract checks the configure/export/import wiring without
enabling a compiler. It does not establish native ABI compatibility; the installed
SDK consumer build and module-load checks remain necessary.
Source: cmake/SparkUIFonts.cmake
Stages the shared Spark UI fonts (IBM Plex Sans, JetBrains Mono, Font Awesome and their
LICENSES/, all from SparkEditor/Fonts) next to an executable, in
<exe dir>/EditorAssets/Fonts, which is the first place Spark::Ui::FindFontDirectory looks.
The root CMakeLists.txt includes it before the SparkEngine executable block.
include(cmake/SparkUIFonts.cmake)
spark_stage_ui_fonts(SparkEngine) # POST_BUILD copy into $<TARGET_FILE_DIR:SparkEngine>/EditorAssets/FontsThe POST_BUILD step runs the same file in script mode
(cmake -DSPARK_UI_FONTS_SOURCE=<dir> -DSPARK_UI_FONTS_DEST=<dir> -P cmake/SparkUIFonts.cmake).
Several executables share one output directory, so the copy takes a file lock on the destination
and copies only files whose contents differ; concurrent and repeated builds are safe. It fails the
build when the source directory holds no fonts. Install rules stay with each consumer.
Enables find_package(SparkEngine) for standalone game projects. Defines the Spark::SparkEngineLib imported target.
| Script | Platform | Description |
|---|---|---|
generate.bat |
Windows | CMake configuration wrapper (accepts generator and config) |
generate.sh |
Linux/macOS | CMake configuration wrapper |
build.ps1 |
Windows | PowerShell build script |
build.sh |
Linux/macOS | Bash build script |
# Generate API docs from headers (no Doxygen required)
docs/generate-api-docs.sh generate # Full generation
docs/generate-api-docs.sh check # Only if headers changed (checksum-based)
docs/generate-api-docs.sh status # Show generation status
# Sync wiki pages with codebase inventory
docs/sync-wiki.sh sync # Update auto-generated sections
docs/sync-wiki.sh check # Dry-run: report what's stale
# Legacy Doxygen (optional, requires doxygen + graphviz)
cd docs && ./generate-docs.shSee the Documentation Index and the Doc Tooling page for full documentation tooling details.
Runs on pushes to main, develop, Working, and release/**; pull requests targeting main, develop, or Working; and manual dispatch. Topic branches (claude/**, codex/**, feature/**) are covered by the pull-request trigger only, so a push to one of them no longer queues the matrix a second time.
| Job | Runner | Compiler | Configs | Key Flags |
|---|---|---|---|---|
check-format |
ubuntu-24.04 | clang-format | -- | --dry-run --Werror |
validate-prompts |
ubuntu-24.04 | -- | -- | --ci |
build-linux-gcc |
ubuntu-24.04 | GCC | Debug, Release | -DBUILD_TESTS=ON |
build-linux-clang |
ubuntu-24.04 | Clang | Debug, Release | -DBUILD_TESTS=ON |
build-linux-asan |
ubuntu-24.04 | GCC | Debug | ASan + UBSan |
build-windows-vs2022 |
windows-2022 | MSVC v143 | Debug, Release | Ninja Multi-Config + sccache (hash-pinned, SCCACHE_DIR restore/save; PCH, module scan, Jolt /Zi off), -DBUILD_TESTS=ON -DBUILD_GAME_MODULES=ON
|
build-windows-vs2026 |
windows-2025-vs2026 | MSVC v145 | Debug, Release | Ninja Multi-Config + sccache inside the VS 2026 dev shell; advisory until runner availability is guaranteed |
coverage |
ubuntu-24.04 | GCC | Debug |
--coverage + lcov |
clang-tidy |
ubuntu-24.04 | Clang | Debug | continue-on-error |
todo-count |
ubuntu-24.04 | -- | -- | threshold: 20 |
Linux GCC:
cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON \
-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++
cmake --build build --parallel $(nproc)
cd build && ctest --output-on-failure --no-tests=error && ./bin/SparkTests && cd ..Linux Clang:
cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON \
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
cmake --build build --parallel $(nproc)
cd build && ctest --output-on-failure --no-tests=error && ./bin/SparkTests && cd ..AddressSanitizer (ASan + UBSan):
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON \
-DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer" \
-DCMAKE_C_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined" \
-DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address,undefined"
cmake --build build --parallel $(nproc)
cd build && ctest --output-on-failure --no-tests=error && ./bin/SparkTests && cd ..Windows MSVC (VS 2022, as build-windows-vs2022 runs it — from an "x64 Native Tools" shell):
cmake --fresh -B build -G "Ninja Multi-Config" \
-DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl \
-DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache \
-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded \
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -DCMAKE_CXX_SCAN_FOR_MODULES=OFF \
-DGENERATE_DEBUG_SYMBOLS=OFF \
-DBUILD_TESTS=ON -DBUILD_GAME_MODULES=ON
cmake --build build --config Release --parallel
ctest --test-dir build -C Release --output-on-failure --no-tests=errorOmit the two _LAUNCHER flags without sccache; with sccache keep -DGENERATE_DEBUG_SYMBOLS=OFF (Jolt's /Zi otherwise breaks every Jolt TU under sccache). The Visual Studio generator (-G "Visual Studio 17 2022" -A x64 -T v143) still works for local IDE builds but ignores compiler launchers; in CI only build-windows-shipping uses it, through its preset, uncached.
Runs for release/** pushes, v* tags, the nightly schedule, and manual dispatch:
- Can publish rolling
nightlyassets withmake_latest: falsefor development evaluation; these are not versioned releases and do not supplystable-v1signing, install, or attestation certification - Builds Windows, Linux, and macOS Debug/Release packages plus configured Windows installer artifacts
- Formats include
.zip(Windows) and.tar.gz(Linux/macOS) - Includes exact commit hash and timestamp
| Compiler | Version | Platform | Status |
|---|---|---|---|
| MSVC | v143 (VS 2022) | Windows | Declared stable-v1 toolset line; profile blocked and uncertified |
| MSVC | v145 (VS 2026) | Windows | Experimental (continue-on-error) |
| GCC | 13+ | Linux | Development build floor; outside stable-v1
|
| Clang | 17+ | Linux | Development build floor; outside stable-v1
|
| Apple Clang | C++23 capable | macOS | Experimental |
| Compiler | Warning Flags | Additional |
|---|---|---|
| MSVC | /W4 |
Zero warnings enforced |
| GCC | -Wall -Wextra |
Zero warnings enforced |
| Clang | -Wall -Wextra |
Zero warnings enforced |
SparkEngine enforces consistent code style via .clang-format (Microsoft-based, Allman braces, 120-col, 4-space indent).
# Check formatting (dry run)
find SparkEngine/Source GameModules SparkEditor/Source SparkConsole/src SparkShaderCompiler/src \
SparkBuild/src SparkInstaller/src SparkDaemon/src SparkServer/src SparkGateway/src \
SparkCooker/src SparkWorker/src SparkAutomation/src SparkLauncher/src SparkUI Tests FuzzerTests \
-not -path '*/Metal/*' \( -name '*.h' -o -name '*.hpp' -o -name '*.cpp' \) \
| xargs clang-format --dry-run --Werror 2>&1
# Fix formatting automatically
find SparkEngine/Source GameModules SparkEditor/Source SparkConsole/src SparkShaderCompiler/src \
SparkBuild/src SparkInstaller/src SparkDaemon/src SparkServer/src SparkGateway/src \
SparkCooker/src SparkWorker/src SparkAutomation/src SparkLauncher/src SparkUI Tests FuzzerTests \
-not -path '*/Metal/*' \( -name '*.h' -o -name '*.hpp' -o -name '*.cpp' \) \
| xargs clang-format -iCI rejects PRs with formatting violations.
- Getting Started -- Build quickstart
- Testing -- Running unit tests
- Architecture Overview -- Engine design and subsystems
- Contributing -- Contribution workflow and code style
- Creating a Game Module -- Building game modules
The installed EmptyProject consumer check now launches the installed engine
with the exact generated module and -require-game, from the generated project.
Its 120-second headless run must pass the existing production NullRHI lifecycle
parser (one initialized module, update/fixed/unload callbacks and zero faults).
The module image hash must remain unchanged. This is a same-build runtime ABI
check; it does not establish N-1 compatibility, hot reload or rendered behavior.
Source checks alone do not qualify this runtime gate.
Published from 614bca17b41e. Edit the canonical source in wiki/.
- Documentation
- Docs route
- Wiki index
- Guides
- Tutorials
- Samples
- Examples
- API Reference
- API route
- Reference
- Build Guide
- Dependencies
- FAQ
- Changelog
- Roadmap
- Contributing
- Code of Conduct
- Home
- FAQ
- Getting Started
- Quick-Start Tutorial
- Making Your First Game
- Making Your First Multiplayer Game
- Artist Workflow Guide
- Editor Walkthrough
- Migration Guide
- How SparkEngine Works
- Architecture Overview
- Engine Architecture Flowchart
- Creating a Game Module
- Game Modules (catalog)
- Entity Component System
- Rendering and Graphics
- Physics
- Cloth Simulation
- Audio
- Input System
- Camera System
- Scripting with AngelScript
- Visual Scripting
- AI and Navigation
- Animation
- 2D Systems
- Networking
- Dedicated Server
- Multiplayer Quick Start
- Area Server Architecture
- Scene Management
- Large World Support
- Collaborative Editing
- Coroutine System
- Event System
- Event Response System
- Job System
- UI System
- UI Layout Extensions
- Localization
- Dialogue System
- Destruction System
- Replay System
- Achievement System
- Loading System
- Mod System
- Content Delivery
- Tween System
- Memory Integrity
- Gameplay Systems
- Terrain and Procedural Generation
- Save System
- Persistence System
- Day Night Cycle and Weather
- Cinematic Sequencer
- Runtime Prefabs
- SparkEditor
- Editor Tutorials
- SparkConsole
- SparkDaemon
- Shader Pipeline
- Asset Pipeline
- Asset Validation
- Asset Migration
- Game Packaging
- Online Services
- DataTable System
- Loot and Crafting System
- CSG System
- Font System
- Timer Manager
- Movie Render Pipeline
- HLOD and World Partition
- Remote Debug System
- Selection Manager
- Asset Dependency Graph
- Editor Automation
- File Watcher
- Project Templates
- System Requirements
- VR Support
- Mobile Platform
- Accessibility
- Platform Input
- Platform Certification
- Cross-Compilation: Wine Testing
- RHI Abstraction Layer
- D3D11 Backend
- D3D12 Backend
- Vulkan Backend
- OpenGL Backend
- Metal Backend
- DXR Raytracing
- Hybrid Ray Tracing
- Upscaling (DLSS/FSR)
- Render Graph
- Shader Graph
- GPU Particles
- GPU-Driven Rendering
- Volumetric Fog
- Volumetric Clouds
- Global Illumination
- Virtual Texturing
- Water Rendering
- Clustered Lighting
- Material System
- Post-Processing
- Shadow System
- Particle System
- Decal System
- Sky and Atmosphere
- Foliage System
- Mesh Shaders
- Neural Rendering
- Configuration Reference
- Performance Tips
- Benchmark Framework
- Threading Model
- Fuzz Policy and Parser Security
- Memory Safety
- Memory Management Patterns
- Build System and CMake Modules
- Profiler and Debugging
- Performance Profiling Guide
- Telemetry System
- Crash Reporting
- Golden Image Testing
- Utilities
- Testing
- Fuzz Policy and Parser Security
- Codebase Statistics
- Codebase Health
- Error Handling Patterns
- Hot Reload Overview
- Troubleshooting
- Contributing
- Workflow Patterns
- Build Optimizations
- CI Reproducible Builds
- CI Controlled-Failure Rehearsal
- Release Publication Stages
- Session Handoff 2026-09-27
- GitHub API and PR Checks
- Git Rebase Conflicts
- Clang-Format
- Code Quality Violations
- AI Bloat Pattern
- MinGW + Wine Cross-Compilation
- Live Editor Testing
- Engine & Renderer Landscape
- DuetOS Portability Catalog
- Five-Engine Analysis
- Eleven-Engine Analysis
- ThorVG / Unity Graphics Analysis
- Advanced Techniques Catalog
- Third-Party Library Evaluation
- Engine Viability Evaluation
- Engine Feature Recommendations
- Project Recommendations
- Mac Compatibility Analysis
- Codebase Observations
- Codebase Bloat Audit
- Test Suite Audit
- Documentation Coverage Audit
- ThirdParty Dependencies Audit
- Load Test Baseline
- Gameplay Systems Status
- SparkGame Module Status
- Stub and Abandoned Features
- Memory Integrity System
- Memory Safety Evaluation
- Hardware Acceleration Systems
- Jolt Physics Integration
- GPU/CPU Separation Plan
- Daemon Services Architecture
- Online Service Boundary
- Server Operations Runbook
- Reflection & Polymorphism Refactoring Plan
- SparkBuild In-Tree
- Wine No-JobSystem Breakthrough
- Wine Role and Fallback Tiers