Skip to content

build: finish the LTO and CI-parallelism change - #20

Merged
ResurrectedTrader merged 1 commit into
mainfrom
lto-build
Sep 15, 2026
Merged

ResurrectedTrader merged 1 commit into
mainfrom
lto-build

Conversation

@ResurrectedTrader

Copy link
Copy Markdown
Owner

706469f ("perf: Speed up CI + proper LTO") landed one file of that change, src/contract/game/GameLock.cpp, and nothing else. What is on main today is a tracked source file that no project compiles and that could not compile if one did, because the header still defines both thread-locals inline, plus a commit message describing link-time optimisation that is not actually enabled. This is the rest of it.

LTO

The ClangCL toolset ignores WholeProgramOptimization (no /GL equivalent reaches clang-cl), so Directory.Build.props turns the projects' Release setting into -flto. Objects become bitcode, llvm-lib archives them as-is, and lld-link runs the whole-program optimisation at link time. That is what lets the one-pointer game:: wrapper types inline across the static libs, which the architecture leans on.

That is also what GameLock.cpp was for. A COMDAT thread_local with a non-trivial destructor breaks lld's LTO (Associative COMDAT symbol ... does not exist), so GameReadLock::lock_ and GameWriteLock::manual_ are now declared in the header and defined in that file, and contract and js_tests compile it.

Parallelism

MultiProcessorCompilation lets each project compile its own sources across cores, MSBuild -m lets independent projects build at the same time, and EnforceProcessCountAcrossBuilds makes the two share one core-count budget instead of each spawning a full set of compilers.

CI

The release workflow ran tests in a second job that rebuilt the whole dependency tree just to run an executable the first job had already produced. Tests now run in build. The job that was serialised behind it becomes api, which reads only headers and so runs alongside build rather than after it.

Verification

Local, on this branch:

Check Result
build.ps1 Release succeeded, 0 warnings
build.ps1 test 127 passed
build.ps1 check-format clean
build.ps1 lint 113 passed, 0 failed

lint is the one worth noting: it fails on main today, because it analyses GameLock.cpp and hits the redefinition described above. This is the change that makes it pass.

706469f landed one file of this change, `src/contract/game/GameLock.cpp`,
and nothing else. The result is a tracked source file that no project
compiles and that could not compile if one did, because the header still
defines both thread-locals inline, plus a commit message describing link-time
optimisation that is not actually enabled. This is the rest of it.

LTO. The ClangCL toolset ignores `WholeProgramOptimization` - no `/GL`
equivalent reaches clang-cl - so `Directory.Build.props` turns the projects'
Release setting into `-flto`. Objects become bitcode, llvm-lib archives them
as-is, and lld-link optimises the whole program at link time, which is what
lets the one-pointer `game::` wrappers inline across the static libs.

That is what `GameLock.cpp` was for: a COMDAT `thread_local` with a
non-trivial destructor breaks lld's LTO ("Associative COMDAT symbol does not
exist"), so `GameReadLock::lock_` and `GameWriteLock::manual_` are declared
in the header and defined in that file, and `contract` and `js_tests` now
compile it.

Parallelism. `MultiProcessorCompilation` lets each project compile its own
sources across cores, MSBuild `-m` lets independent projects build at the
same time, and `EnforceProcessCountAcrossBuilds` makes the two share one
core-count budget rather than each spawning a full set of compilers.

CI. The release workflow ran tests in a second job that rebuilt the whole
dependency tree to run an executable the first job had already produced.
Tests now run in `build`, and the job that was serialised behind it becomes
`api`, which needs only headers and so runs alongside `build` instead of
after it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ResurrectedTrader
ResurrectedTrader merged commit a1cff11 into main Sep 15, 2026
1 check passed
@ResurrectedTrader
ResurrectedTrader deleted the lto-build branch September 15, 2026 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant