Skip to content

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-exceptions compatibility; 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.cpp must 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.py shall 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 + all src/**.cpp contents 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_AVX2 derived 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).