03 — Build System¶
1. Purpose¶
Specifies the complete build architecture: CMake organization, targets, options, flags, pinned development dependencies, install/packaging, and the amalgamation pipeline. The implementation agent shall never invent build organization.
2. Scope¶
CMakeLists.txt (root and subdirectories), cmake/*, CMakePresets.json, the amalgamation generator's build integration, and packaging groundwork. CI usage of these targets is in 13-ci-architecture.md.
3. Requirements¶
| ID | Requirement |
|---|---|
| REQ-BUILD-001 | The build shall require CMake ≥ 3.28 and a C++23 compiler per the support matrix (§7); cxx_std_23 shall be declared with extensions OFF. |
| REQ-BUILD-002 | The library shall build as a single static library target quiver with alias quiver::quiver. Shared-library builds are out of scope for v1 (see 21-future-work.md); BUILD_SHARED_LIBS shall be ignored with a configure-time warning. |
| REQ-BUILD-003 | The shipped library target shall have zero external link or header dependencies beyond the C++ standard library and OS headers used by MOD-CPU (REQ-REPO-006; Charter T4). |
| REQ-BUILD-004 | Library translation units shall compile with exceptions and RTTI disabled (-fno-exceptions -fno-rtti or MSVC equivalents /EHs-c- /GR-) to enforce the Charter §7.3 execution contract structurally. |
| REQ-BUILD-005 | No shipped translation unit shall be compiled with -march=native or any global ISA flag above the platform baseline. Per-ISA code is enabled by target regions (ADR-003); the sole exception is MSVC, where <family>_avx2.cpp / <family>_avx512.cpp receive per-file /arch:AVX2 / /arch:AVX512 (tier-2, §7). |
| REQ-BUILD-006 | Build options shall be exactly: QUIVER_ENABLE_TESTS (default ON when top-level project, OFF when subproject), QUIVER_ENABLE_BENCH (default OFF), QUIVER_ENABLE_EXAMPLES (default = tests default), QUIVER_ENABLE_ASSERTS (default ON for Debug, OFF otherwise), QUIVER_ENABLE_WERROR (default OFF; ON in CI), QUIVER_SANITIZE (string list: address;undefined;thread;memory), QUIVER_DISABLE_AVX512 (default OFF; escape hatch for broken toolchains), QUIVER_PIN_ISA (string, default unset — compile-time pinning per REQ-DISP-013). New options require a PRD amendment. |
| REQ-BUILD-007 | Development dependencies shall be fetched via FetchContent in cmake/deps.cmake, pinned to an exact release tag and URL SHA-256: GoogleTest (pin recorded as GTEST_PIN, initial v1.15.2) and Google Benchmark (GBENCH_PIN, initial v1.9.1). Dev dependencies shall only be declared when the corresponding option is ON, shall never be installed, and shall never appear in the export set. |
| REQ-BUILD-008 | Warning baseline for library code: GCC/Clang -Wall -Wextra -Wpedantic -Wshadow -Wvla -Wconversion -Wsign-conversion; MSVC /W4. QUIVER_ENABLE_WERROR promotes warnings to errors. Third-party (fetched) code shall be excluded from the warning policy via SYSTEM includes. |
| REQ-BUILD-009 | install() shall export: include/quiver/** headers, the static library, and a CMake package (QuiverConfig.cmake, QuiverConfigVersion.cmake, QuiverTargets.cmake) supporting find_package(Quiver CONFIG). Nothing else shall be installed (REQ-REPO-007). |
| REQ-BUILD-010 | The project shall be consumable in all three Charter §6.5 modes and each shall be CI-verified from M8 onward: (a) installed package + find_package, (b) FetchContent/add_subdirectory, (c) amalgamation drop-in. |
| REQ-BUILD-011 | CMakePresets.json shall define presets: dev (Debug, asserts, tests), release (Release, -O3, tests), bench (Release + bench + examples), asan-ubsan, tsan, msan, ci-gcc, ci-clang, ci-msvc. CI shall invoke presets only, never ad-hoc flag sets. |
| REQ-BUILD-012 | Sanitizer configuration shall live in cmake/sanitizers.cmake; sanitizer flags shall apply to the library, tests, and fuzz targets uniformly; sanitized builds shall define QUIVER_ENABLE_ASSERTS=ON. |
| REQ-BUILD-013 | The amalgamation shall be generated by tools/amalgamate/amalgamate.py (MOD-AMALG) via the build target quiver_amalgamate; a second target quiver_amalgamate_verify shall compile the generated pair and run the unit-test suite against it, requiring byte-identical kernel outputs versus the normal build. |
| REQ-BUILD-014 | Interprocedural optimization (LTO) shall be OFF by default and controllable by the standard CMAKE_INTERPROCEDURAL_OPTIMIZATION; the ledger records whether it was enabled (manifest field, 11). |
| REQ-BUILD-015 | vcpkg and Conan packaging metadata (port/recipe skeletons under cmake/packaging/) shall be prepared at M8; registry submission is a release activity (19), not a build-system feature. |
4. Target inventory¶
| Target | Type | Sources | Options/flags | Visibility |
|---|---|---|---|---|
quiver (quiver::quiver) |
STATIC | all 73 production files (02 §8) | REQ-BUILD-004/005/008 | installed |
quiver_tests_unit, _property, _differential, _invariant, _regression |
test executables | tests/** + testkit |
asserts ON | dev |
quiver_fuzz_<family> ×10 |
fuzz executables | tests/fuzz/** |
-fsanitize=fuzzer,address,undefined |
dev (Clang only) |
quiver_bench_<family> ×10, quiver_bench_dispatch, quiver_bench_pipeline |
bench executables | bench/** |
Release only; PMU on Linux | dev |
quiver_baselines |
OBJECT | bench/baselines/*.cpp |
target regions per ADR-011 | dev (linked into bench) |
quiver_examples_* |
executables | examples/*.cpp |
plain consumer flags (exceptions ON — proves consumability) | dev |
quiver_amalgamate, quiver_amalgamate_verify |
custom | tools/amalgamate | — | dev/release |
5. ADR-002 — Library form: compiled static library + generated amalgamation¶
- Status: Accepted.
- Context: Charter T4 demands three consumption modes including a two-file drop-in; Charter §7.3 demands
-fno-exceptionscompatibility; ADR-003 requires per-ISA compiled code. - Problem: header-only vs compiled vs compiled+amalgamation.
- Alternatives:
- Header-only. + zero build integration. − every consumer TU recompiles all ISA paths; target-region pragmas inside consumer-included headers leak diagnostics and break under MSVC; dispatch table initialization becomes ODR-fragile; compile-time cost contradicts vendorability in practice.
- Compiled static library only. + clean. − no two-file vendoring path; fails Charter §6.5.
- Compiled library + generated amalgamation (selected). + normal builds stay clean; vendoring path is the proven simdjson/fsst pattern (OA §3, §8). − amalgamation generator must be maintained and verified (mitigated by REQ-BUILD-013's identical-output gate).
- Decision: Alternative 3.
- Consequences: MOD-AMALG exists (M8); release assets carry the pair (REQ-REPO-011).
- Reconsideration: if C++ modules become the ecosystem vendoring norm.
- Related: REQ-BUILD-002/010/013, ADR-003, ADR-018, Charter T4/§6.5.
6. ADR-018 — Amalgamation generation strategy¶
- Status: Accepted.
- Context: the pair
quiver.h/quiver.cppmust compile as one TU on GCC/Clang with full ISA coverage, and degrade gracefully on MSVC. - Problem: a single TU cannot receive per-file ISA flags, and naive concatenation breaks include guards and ordering.
- Alternatives: (a) ship per-ISA amalgamated TUs (4 files) — rejected: violates the two-file promise; (b) preprocessor-driven single pair with target regions (selected); (c) unity-build CMake trick — rejected: not a drop-in artifact.
- Decision:
amalgamate.pyshall emit: quiver.h= license banner + version stamp (git describe) + public headers concatenated in dependency order (detail/config.h,core.h,detail/extern_decls.h,dispatch.h, then the nine kernel headers alphabetically), include guards stripped,#include <std…>hoisted, deduplicated, and sorted first.quiver.cpp=#include "quiver.h"+ internal headers + allsrc/**.cppcontents in deterministic order (cpu, dispatch, kernels/common, then families alphabetically, scalar→avx2→neon→avx512 within a family). Because ISA code is enabled by target-region macros (ADR-003), the single TU compiles with no special flags on GCC/Clang. On MSVC, each ISA section is additionally guarded so that only baseline-compatible backends compile unless the consumer sets/arch(QUIVER_AMALG_HAS_AVX2derived from__AVX2__etc.); dispatch then selects among compiled-in backends only. This MSVC narrowing shall be documented in the vendoring guide.- Determinism: two runs on the same tree shall produce byte-identical output (REQ: sorted, no timestamps beyond the version stamp).
- Consequences: source files must keep guard style and internal-include forms uniform (enforced by 17-coding-standards.md REQ-STD-006) so the generator stays trivial.
- Reconsideration: if the file count or macro complexity makes text transformation error-prone, switch to a libclang-based generator (PRD amendment).
- Related: REQ-BUILD-013, REQ-REPO-011, ADR-002/003.
7. Toolchain support matrix¶
| Toolchain | Tier | Minimum | CI |
|---|---|---|---|
| GCC (Linux x86-64, ARM64) | 1 | 13 | 13 and 14 |
| Clang (Linux x86-64, ARM64) | 1 | 17 | 17 and 19 |
| AppleClang (macOS ARM64) | 1 | Xcode 16 | latest stable |
| MSVC (Windows x86-64) | 2 (best-effort) | 19.40 / VS2022 | windows-latest, full suite + amalgamation; blocking in practice |
Tier-1 failures block merges; tier-2 failures open issues (Charter §8.1 Windows posture).
Note (v0.7.1): the MSVC jobs carry no continue-on-error in ci.yml, so they block merges
today despite the best-effort label, and they now run the full suite with no --gtest_filter
exclusions (R-18 closed). The remaining gap to a formal tier-1 listing is the Charter §8.1
"demonstrated demand" gate, not test coverage.
8. Failure modes¶
Configure-time hard errors with actionable messages for: compiler below minimum; missing C++23 support; sanitizer combination invalid (e.g., thread with address); QUIVER_SANITIZE on MSVC (unsupported → error). AVX-512 target-region compile failure on a tier-1 toolchain is a build defect, not a skip — QUIVER_DISABLE_AVX512 exists only for documented broken-toolchain escapes and shall print a warning.
9. Acceptance criteria¶
All REQ-BUILD checks verified by CI jobs (13); a consumer project using each of the three consumption modes builds and runs example 01 (M8 gate); configure options behave per REQ-BUILD-006 defaults under both top-level and subproject inclusion.
10. Traceability¶
Charter T4, §6.5, §7.3/§7.6 → REQ-BUILD-001..015 → ADR-002, ADR-018 → milestones M0 (skeleton), M1 (targets), M8 (amalgamation, packaging). Note: CMakePresets.json is a root file addition to the 02 §3 tree (recorded there).