ADR-018 — Amalgamation generation strategy¶
- Identifier: ADR-018
- Title: Amalgamation generation strategy
- Status: Accepted
- Source: extracted verbatim from the Engineering PRD, docs/prd/03-build-system.md (REQ-DOC-004). From M0 onward this file is the canonical, living ADR record; status changes happen here and in the index, with the PRD text remaining the historical record.
- 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.
-
Amendment (M8, 2026-07-05) — MSVC narrowing is unnecessary for the default-
/archbuild. The decision above prescribed per-ISA#ifnarrowing (QUIVER_AMALG_HAS_AVX2from__AVX2__) so only baseline-compatible backends compile on MSVC. An empiricalwindows-latestprobe (Visual Studio 2022) showed this is not needed: with the default/arch(SSE2 baseline) MSVC compiles the AVX2 and AVX-512 intrinsics — self-contained at their call sites — while leaving the scalar and dispatch code at baseline, so the single-TU amalgamation compiles all backends and the unit suite passes with runtime dispatch intact (baseline-safe by construction). The supported MSVC configuration is therefore "build the amalgamation with default/arch", verified by themsvc-amalgamationCI leg; the narrowing guards are not implemented. A narrowing scheme for consumers who deliberately set/arch:AVX2+ (which would raise the whole-TU baseline and could leak higher-ISA codegen into the baseline path) is a tier-2 deferral, tracked as risk R-17.