Skip to content

Build Optimizations

github-actions[bot] edited this page Sep 12, 2026 · 55 revisions

Build and CI Workflow Optimizations

Audience: Programmers

Thread Context: N/A (development/process reference)

Platform/Backend Scope: All platforms (build/CI/git; commands shown for Linux/bash)

Overview

Concrete time and effort savers for build, CI diagnosis, and git workflows. These are faster or more reliable alternatives to the obvious first approach. They apply to any session involving building, testing, CI diagnosis, or git operations in SparkEngine. These are not correctness fixes — the default approaches work — they are efficiency improvements.

Always Use --parallel $(nproc) for CMake Builds

Always pass --parallel $(nproc) to cmake --build to exploit all available CPU cores:

cmake --build build --config Release --parallel $(nproc)

Without this flag, CMake builds single-threaded by default on some configurations, which is dramatically slower on multi-core hosts.

Notes:

  • $(nproc) is Linux/bash-specific. On macOS use $(sysctl -n hw.logicalcpu). On Windows PowerShell, the MSVC generator parallelizes by default with --parallel (no count needed), or use $env:NUMBER_OF_PROCESSORS.
  • All Linux CI jobs already use --parallel $(nproc) (macOS uses $(sysctl -n hw.logicalcpu)) — this makes local builds match CI speed.

Use --log-failed to Jump Straight to CI Failure Output

When a CI run fails, skip reading the full log. Use --log-failed to download only the failed job output:

# Get run ID first
gh run list --branch "$(git branch --show-current)" --limit 3

# Download only failed logs (much smaller, faster to scan)
gh run view <RUN_ID> --log-failed

Notes:

  • Full logs (gh run view <RUN_ID> --log) can be very large — often 10-50 MB for all jobs.
  • --log-failed downloads only the logs from jobs with a failure conclusion.
  • This repo also uploads per-job error-summary artifacts (ci-errors-*) and a report-ci-errors aggregation job — downloading those can be even faster than --log-failed.
  • See GitHub API and PR Checks for the full PR check diagnosis workflow.

Check Branch Delta Before Rebasing

Before running git rebase origin/Working, check how many commits you are behind. This tells you whether to expect conflicts and how many:

git log --oneline HEAD..origin/Working | wc -l
Output Action
0 Branch is up to date — skip rebase entirely
1-3 Straightforward rebase, unlikely to conflict
4-10 Moderate delta — read commit messages before rebasing
10+ Large delta — review commits first with git log --oneline HEAD..origin/Working

Notes:

  • See Git Rebase Conflicts for conflict resolution strategies.
  • Checking first prevents surprises mid-rebase on large divergences.

gh pr checks Snapshot Over --watch Loop

For a quick status snapshot without risk of hanging, use plain gh pr checks (no flags) rather than --watch:

# Quick snapshot — does not hang
gh pr checks

# Then use run list + view for details on failures
gh run list --branch "$(git branch --show-current)" --limit 3
gh run view <RUN_ID>

gh pr checks --watch is designed for interactive terminals and can hang indefinitely in non-TTY environments.

Notes:

  • See GitHub API and PR Checks for the full polling workflow.
  • Ignore exit code 1 from gh pr checks if checks are still running — the non-zero exit is not meaningful while checks are in progress.

CMake Dry-Run to Verify Preset Flags

Use the -N flag to do a CMake dry-run that prints all resolved options without actually configuring:

cmake --preset linux-gcc-release -N

Useful for verifying which CMake toggles (ENABLE_NETWORKING, ENABLE_DXR, etc.) are set by a preset before committing to a full configure.

Notes:

  • Much faster than a full configure when you just need to check a flag.
  • Many toggles are OFF by default (e.g. ENABLE_VULKAN, ENABLE_OPENGL, ENABLE_METAL, ENABLE_DXR, SPARK_DOUBLE_PRECISION_PHYSICS); ENABLE_NETWORKING, ENABLE_EDITOR, ENABLE_GRAPHICS, and BUILD_GAME_MODULES are ON. See CLAUDE.md "Build" for the authoritative toggle list.

Compiler Caching in CI (ccache / sccache)

CI uses compiler caches to speed up incremental builds: ccache on the Linux jobs and sccache on the two Windows MSVC lanes (build-windows-vs2022, build-windows-vs2026), passed via -DCMAKE_C_COMPILER_LAUNCHER=sccache / -DCMAKE_CXX_COMPILER_LAUNCHER=sccache. If you reproduce a CI job locally and have ccache/sccache installed, adding the same launcher flags makes repeat builds far faster; otherwise omit them.

The Windows contract (since 2026-09-06):

  • Generator: -G "Ninja Multi-Config" inside the Visual Studio developer environment (Enter-VsDevShell -VsInstallPath <vs> -SkipAutomaticLocation -DevCmdArguments "-arch=x64 -host_arch=x64", which also puts cl, rc, ninja and the Windows SDK fxc on PATH) (fxc discovery and the foliage shader validations are expected from find_program(FXC_EXECUTABLE ...); no CI run at this tree has confirmed them yet). Visual Studio generators ignore CMAKE_<LANG>_COMPILER_LAUNCHER, which is why the earlier sccache step on the VS-generator lane was inert. build-windows-shipping still configures through its windows-shipping preset (Visual Studio 17 2022 generator) and uses no compiler cache.
  • Tool: sccache v0.17.0 downloaded from the GitHub release and verified against a SHA-256 literal in the workflow; a hash mismatch or failed download fails the job before any compile. mozilla-actions/sccache-action is no longer used.
  • Cache: SCCACHE_DIR under runner.temp, restored and saved with split actions/cache/restore / actions/cache/save steps keyed sccache-windows-<lane>-<config>-<hashFiles of CMakeLists.txt and *.cmake>-<sha> (the same shape as the Linux ccache keys). The save step runs under !cancelled(), so a job that went red (compile error, test gate) still saves the objects it produced. build/ is never restored on these lanes any more.
  • Flags: -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON (sccache cannot cache /Yc / /Fp), -DCMAKE_CXX_SCAN_FOR_MODULES=OFF (no module units exist), -DGENERATE_DEBUG_SYMBOLS=OFF (removes Jolt's /Zi, which would otherwise make sccache demand a PDB that cl never writes under the engine's /Z7), plus -DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded as a guard for the pin the top-level CMakeLists.txt already sets before project().
  • Evidence: the Print sccache stats step (the server is kept alive with SCCACHE_IDLE_TIMEOUT=0 until --stop-server) writes the stats to the job summary and emits ::warning:: annotations for 0 compile requests, non-zero cache error counters, or a cold restore; it never fails the job.

Source & Freshness

  • Original entry: Build and CI Workflow Optimizations, last updated 2026-03-14.
  • Verified against codebase 2026-06-08.
  • Updated / found stale:
    • Added a Windows/PowerShell note for --parallel (the $(nproc) form is bash-only).
    • Added the ci-errors-* artifacts / report-ci-errors job as a faster-than---log-failed option (new since source).
    • Added a ccache/sccache section documenting the compiler-cache launcher flags CI now uses.
    • Rewrote the Windows part of that section (2026-09-06): the vs2022/vs2026 lanes now use Ninja Multi-Config + hash-pinned sccache with split restore/save on SCCACHE_DIR; the earlier claim that the Visual Studio-generator lanes passed launcher flags was false (the sccache step there was inert).
    • Refreshed the default-OFF/ON toggle list against current CLAUDE.md (source pointed at a codebase-observations.md file not migrated here).
    • Retargeted cross-references to the migrated wiki pages.

Related Pages

SparkEngine Wiki

Website Entry Points

Getting Started

Engine Subsystems

Gameplay & Tools

Platform Support

Graphics

Advanced

Development & Process

Research & Analysis

Engineering Notes & Audits

Specifications

Reference

Clone this wiki locally