Repository navigation
docs: add top-level compile-time build options guide - #6098
Conversation
Document project CMake switches, defaults, dependency requirements and experimental backends in BUILD-OPTIONS.md. Link the guide from the README and build documentation, and replace the partial compiler-definition table in the Developer Guide. Closes #6097.
There was a problem hiding this comment.
Issue fit
Yes. #6097 asked for a root-level BUILD-OPTIONS.md listing the project-defined CMake options with defaults, purpose and platform/dependency prerequisites; DeepFist and RTL-SDR made findable with their extra prerequisites; an explanation of which radio families need no switch; how to set options and inspect an existing cache; packaging/guards/diagnostics/test options grouped separately; and requested-vs-detected-vs-generated distinguished. Every bullet is satisfied, and the three inbound links (README, docs/BUILDING.md, docs/DEVELOPER-GUIDE.md) are in place.
I re-ran the acceptance check independently rather than trusting the test plan. Enumerating option() across every tracked non-vendored CMake file gives exactly 36: 19 in CMakeLists.txt (incl. the three conditional ASR GPU options and ENABLE_DEEPFIST_EXPERIMENT), 6 USE_SYSTEM_*, 5 REQUIRE_*, 2 in cmake/AetherQtPin.cmake, 4 in tests/tests.cmake. The doc lists all 36, invents none, and every documented default matches its option() line — including the computed one (AETHER_EMBED_DFNR_MODEL → ON on WIN32, OFF elsewhere, CMakeLists.txt:220-226). Non-FORCE project cache variables are also exactly the four documented: AETHERSDR_SANITIZER, DEEPFIST_MODEL_BASE_URL, RADE_TAP_DIR (CACHE PATH, only created under RADE_WAV_TAP, which the row says), AETHER_TEST_FFTW_TIMELIMIT.
Scope
| File | What it changes | Claimed? | Verdict |
|---|---|---|---|
BUILD-OPTIONS.md |
New root-level option reference (141 lines) | Yes — the whole ask of #6097 | In scope |
README.md |
+3 lines: link from the source-build section | Yes | In scope |
docs/BUILDING.md |
+3 lines: link above the platform TOC | Yes | In scope |
docs/DEVELOPER-GUIDE.md |
Replaces the HAVE_* table with a link + generated-definition explanation |
Yes | In scope |
Everything in the diff is explained by the issue. No CHANGELOG.md entry (correct). No code, CMake or test sources touched, so the documented defaults cannot have drifted as a side effect of this PR. Socket tests: none added, modified or removed — no test sources are in the diff; the socket-binding opt-in tests the doc describes (hl2_tx_loopback_test, hl2_dsp_readback_sim_test, hl2_signal_stop_test) are pre-existing, and the doc's descriptions of them match tests/tests.cmake:5033-5090.
Blockers
None.
Nits (non-blocking)
- Generated defines are now documented nowhere for ~8 features. The deleted
docs/DEVELOPER-GUIDE.mdtable was the only place mappingENABLE_*→HAVE_*.BUILD-OPTIONS.md:112names four (HAVE_SERIALPORT,HAVE_WEBSOCKETS,HAVE_KEYCHAIN,HAVE_ONNX) anddocs/BUILDING.md:123maps packages→features, not macro names. SoHAVE_RADE,HAVE_SPECBLEACH,HAVE_DFNR,HAVE_MQTT/HAVE_MQTT_TLS,HAVE_NVIDIA_AFX,HAVE_HIDAPI,HAVE_PORTAUDIO,HAVE_SHERPAandHAVE_MIDIlose their home right as the guide tells developers to "use the corresponding#ifdefguards".HAVE_NVIDIA_AFXis the one that actually costs someone time — nobody guesses it fromENABLE_NVIDIA_AFX. A "Generated define" column on the feature tables would close this and directly serve #6097's own "distinguish requested options from … generated compiler definitions" bullet. Inline atBUILD-OPTIONS.md:112.- Worth saying: the removal is a net correction, not just a loss. The old table's
HAVE_BNRrow named a macro that does not exist anywhere in the tree (grep -rn HAVE_BNRreturns nothing; the real define isHAVE_NVIDIA_AFX,CMakeLists.txt:3140), and its "NVIDIA NIM container" package was wrong too — AFX is a runtime-loadeddlopenwrapper.
- Worth saying: the removal is a net correction, not just a loss. The old table's
ENABLE_ASR_VULKAN/ENABLE_ASR_METAL/ENABLE_ASR_METAL_PRECOMPILEare declared inside branches, so off their branch they do not exist and-D…=OFFis a bare unused-variable warning — a hazardCMakeLists.txt:1638-1641calls out by name. Inline atBUILD-OPTIONS.md:69.AETHERSDR_SANITIZERcould note thataddress+threadis refused at configure time (#4360) and that sanitizer builds carry-g3in every config, Release included. Inline atBUILD-OPTIONS.md:131.HAVE_DEEPFISTis an odd exemplar in the Developer Guide (it only exists under an OFF-by-default experiment);HAVE_MIDIorHAVE_NVIDIA_AFXwould teach more.
What I tried to break
- Independent recount of the "36 options" claim, not a spot check:
grep -rn '^\s*option('across the three cited files plussrc/,cmake/,packaging/andhal-plugin/. 36 exactly, with no option in the tree missing from the doc and no documented option absent from the tree. Same for the "four cache settings" claim, filtered forFORCE. - Per-row prerequisite claims against the CMake that implements them: RTL-SDR needs
librtlsdrandfftw3f(2683-2698); SpecBleach isFORCE-set OFF on MSVC withoutclang-cl(658-663); AFX is gated tox86_64|AMD64on Linux/Windows (3138); DeepFist is aFATAL_ERRORwithout ONNX Runtime (2924);AETHER_GPU_SPECTRUMneedsQt6::ShaderTools+ private QtGui headers (577,640-651); the Metal-precompile fallback warns and degrades unlessREQUIRE_ASR_GPU(1776-1791);REQUIRE_ASR_GPU+USE_SYSTEM_LIBWHISPERis the third failure mode the row claims (1771-1775). All fourtests.cmakerows check out, includingSKIP_RETURN_CODE 77on a missinghpsdrsimand the non-Windows + Python 3 registration for signal-stop. - Hunted for a missing prerequisite by analogy to the DFNR row.
ENABLE_RADEis documented with no setup step; I checked whether it needs one. It does not —third_party/radaeis in-tree and the gate isEXISTS ${RADE_DIR}/src/rade_api.h(450-452), with Opus built fromBuildOpus.cmake. Every setup script the doc names exists:setup-deepfilter.{sh,ps1},setup-onnxruntime.*,setup-sherpa-onnx.*. - Tried to falsify the Qt precedence sentence. "An explicit Qt path takes precedence" is not the same claim as the file's "
AETHER_QT_CACHEoverrides all three" (that is cache location). It holds for a different reason: the pin is applied underif(AETHER_USE_PINNED_QT AND NOT _aether_qt_chosen)afterQt6_DIR/Qt6_ROOT/CMAKE_PREFIX_PATHare probed (AetherQtPin.cmake:170-205). - Resolved every link and anchor:
README.md#building-from-source(## Building from Source),#supported-hardware,docs/BUILDING.md#gpu-spectrum-rendering(BUILDING.md:203),docs/deepfist-cw-backend.md,CMakeLists.txt,cmake/AetherQtPin.cmake,tests/tests.cmake— all exist, and the relative paths are right from both root anddocs/.cmake -LAH -N buildis a valid view-only invocation. Nothing in the tree linked to the removed#optional-dependenciesanchor, so the table swap breaks no inbound reference. - Could not check: nothing requiring a build. I did not configure CMake, so option interactions (e.g. what a real configure prints for a given combination) are reasoned from the CMake source rather than observed. CI being green here proves only that docs do not break the build — it exercises none of these claims.
Recommendation
Approve with nits. This is an unusually well-evidenced docs PR: the 36-option inventory is complete and correct, the defaults match source including the computed and FORCE-overridden ones, the prerequisite prose tracks the actual CMake gates, and the Developer Guide swap removes a table that had drifted into naming a macro that does not exist. The nits are additive — most valuably a "Generated define" column so the ENABLE_* → HAVE_* mapping the old table carried is not lost. Next step is a maintainer sanity check on the root-level file placement (#6097 specified it, so that is already a ruling) and either folding in the define column here or filing it as a follow-up. Thanks for checking the inventory against source rather than against the old docs — that is what made this reviewable.
🤖 aethersdr-agent · cost: $5.1534 · model: claude-opus-5
ten9876
left a comment
There was a problem hiding this comment.
Issue fit
Yes, against the PR's merge base 88398a06f. No longer complete against current main. #6097 asked for one root-level reference covering every project-defined CMake option, with defaults, prerequisites and the requested/detected/generated distinction, linked from the README, the build guide and the Developer Guide. At the base, the guide covers all 36 option()s and the four value settings, and every default matches its option() line. Since the base, main has gained two options that the guide does not list (blocker 1).
Scope
| File | Change | Claimed? | Verdict |
|---|---|---|---|
BUILD-OPTIONS.md |
New 141-line option reference | Yes, it is the whole ask of #6097 | In scope |
README.md |
+3: link from "Building from Source" | Yes | In scope |
docs/BUILDING.md |
+3: link above the TOC | Yes | In scope |
docs/DEVELOPER-GUIDE.md |
HAVE_* table replaced with a link and an explanation of generated definitions |
Yes | In scope |
Everything in the diff is explained by the issue. The PR has one commit, authored 2026-10-02. It changes no code, CMake, CI or tests, and adds no CHANGELOG.md entry. The socket preflight is clean: the diff touches no test sources.
Blockers
1. Two options that landed on main after the base are missing
BUILD-OPTIONS.md claims to cover every project option, and its own closing rule (BUILD-OPTIONS.md:138-141) says to update it in the same change as any option change. Two options reached main on 2026-10-03, after this branch's base:
AETHER_SHARED_CORE, atCMakeLists.txt:151onmain(#6136)AETHER_BUILD_SPECTRUM_GESTURE_TEST, attests/tests.cmake:2135onmain(#5924)
The branch still merges cleanly, so the guide would land already incomplete. That is the opposite of what #6097's acceptance check ("check the catalog against CMakeLists.txt, cmake/AetherQtPin.cmake and tests/tests.cmake") is meant to guarantee. Suggested rows for the "Diagnostics and opt-in tests" table:
| `AETHER_SHARED_CORE` | OFF | Build `libaethercore` as a shared library so the sanitizer lane's test binaries fit on a hosted runner. Sanitizer CI only, never for releases; configuring with it ON fails on Windows. |
| `AETHER_BUILD_SPECTRUM_GESTURE_TEST` | OFF | Build/register `spectrum_confirmed_geometry_test`, which compiles the desktop application sources into a test binary to exercise the real `SpectrumWidget` gestures offscreen. |To reproduce the gap:
git grep -nE '^\s*option\s*\(' origin/main -- '*.cmake' '*CMakeLists.txt' ':!third_party'That lists 38 options on current main, against the 36 in this guide.
Nits (non-blocking)
-
The guide's general rule has two exceptions it doesn't mention. The intro (
BUILD-OPTIONS.md:9-10) says a missing dependency "can still disable" anONoption. Two options fail configuration instead:ENABLE_DEEPFIST_EXPERIMENT=ONwithout ONNX Runtime is aFATAL_ERROR(CMakeLists.txton main,if(NOT ORT_FOUND) message(FATAL_ERROR ...)).AETHER_GPU_SPECTRUMrunsfind_package(Qt6 REQUIRED COMPONENTS ShaderTools), so a missing ShaderTools fails configuration. Only missing private QtGui headers fall back to the CPU path.
The rows say "Requires" and "Needs", which is accurate. Saying "configuration fails without it" for those two would save a builder from wondering why the general rule didn't apply.
-
Nothing keeps the guide current. Both options in blocker 1 went in within one day of this branch, and neither PR knew to update a file that didn't exist yet. Without a drift check, the "Keeping this reference current" paragraph will keep failing the same way. A check could work like
gen_bridge_docs --check: diff theoption()inventory against the table names. That would touchtools/and CI, so it's a maintainer call for a separate change, not something to add here. -
I agree with the bot review's define-column nit. The deleted Developer Guide table was the only
ENABLE_*→HAVE_*map, andHAVE_NVIDIA_AFXcan't be guessed fromENABLE_NVIDIA_AFX. A "Generated define" column would keep that map. The old table'sHAVE_BNRrow named a macro that doesn't exist, so removing the table is still a net correction.
What was verified (read-only; docs PR, nothing to build or drive)
- Inventory: I recounted
option()across every tracked, non-vendored CMake file at the PR head: 36, matching the guide exactly. On currentmainit is 38 (blocker 1). The four documented value settings are the only non-FORCEproject cache values:AETHERSDR_SANITIZER,DEEPFIST_MODEL_BASE_URL,RADE_TAP_DIR(created only underRADE_WAV_TAP), andAETHER_TEST_FFTW_TIMELIMIT("empty = unbounded" per its help string). - Per-row claims checked against the CMake that implements them all held:
- RTL needs both
librtlsdrandfftw3f. - SpecBleach is forced OFF on MSVC when
clang-clis absent. - AFX is limited to
x86_64|AMD64on Linux and Windows. - The sanitizer value list and the MSVC/clang-cl refusal match.
- The
AETHER_EMBED_DFNR_MODELdefault is computed per platform. - The MQTT TLS fallback to no OpenSSL matches.
- The signal-stop test registers only on non-Windows hosts with a Python 3 interpreter.
- The Qt pin yields to
Qt6_DIRandCMAKE_PREFIX_PATH.
- RTL needs both
- Links:
README.md#building-from-source(README.md:150),#supported-hardware(:68),docs/BUILDING.md#gpu-spectrum-rendering(:200) anddocs/deepfist-cw-backend.mdall exist onmain. - CI: all checks are green, but the earliest run was created 2026-10-02T19:52Z and
mainhas moved since. For a docs-only diff the green only shows the build is undisturbed, and it does not exercise any of these claims. - Not driven: a documentation change has no runtime surface to drive.
- Automated
/code-reviewpass (medium): no findings at the PR head. It reached the same 36-option result. It checked only the head, notmain, so it could not see blocker 1.
ten9876
left a comment
There was a problem hiding this comment.
Issue fit
Yes at the reviewed head, with minor refresh needed for current main. #6097 requests a discoverable source-build option reference. At b89e36f7, the new guide covers all 36 project Boolean options and four additional settings, explains requested versus detected/generated features, separates experiments/packaging/guards/diagnostics, and supplies the requested configuration/cache examples and three entry-point links. DeepFist's separate model and RTL-SDR's two libraries are explicit. No build behavior changes.
Scope
| File/group | Change | Claimed? | Verdict |
|---|---|---|---|
BUILD-OPTIONS.md |
Option inventory, defaults, prerequisites and examples | Yes | In scope |
README.md, docs/BUILDING.md |
Links to the reference | Yes | In scope |
docs/DEVELOPER-GUIDE.md |
Replace partial definition table with reference and generated-definition explanation | Yes | In scope |
Everything in the diff is explained by the issue. The sole commit's author date is October 2; no unrelated commits, code, defaults, public APIs, UI preferences, or CHANGELOG changes are bundled. Documentation additions do not require an RFC under GOVERNANCE.md. The body's documentation-only and inventory claims hold for its own head; the complete-inventory claim needs refreshing for current main as noted below.
Blockers
None.
Nits — explicitly non-blocking
-
Refresh the inventory against current main —
BUILD-OPTIONS.md:119. Head has 36 Boolean options, but current maincb2d6917has 38.CMakeLists.txt:151on main addsAETHER_SHARED_CORE(OFF, sanitizer CI only, unsupported on Windows), andtests/tests.cmake:2135addsAETHER_BUILD_SPECTRUM_GESTURE_TEST(OFF, real SpectrumWidget gesture regression). Add those rows and update the PR's count when incorporating main. These are intervening changes, not omissions from the author's original snapshot. Suggested rows for the diagnostics table:| `AETHER_SHARED_CORE` | OFF | Build libaethercore as a shared library for sanitizer CI; unsupported on Windows. Not for release builds. | | `AETHER_BUILD_SPECTRUM_GESTURE_TEST` | OFF | Build the real SpectrumWidget gesture regression test. |
-
Qualify the GPU requirement —
BUILD-OPTIONS.md:105. The row promises a configure failure when no ASR GPU backend is built, but all its checks are insideif (ENABLE_ASR)(CMakeLists.txt:1631-1999). I executed that exact extracted block withENABLE_ASR=OFFandREQUIRE_ASR_GPU=ON: exit 0, output-- ASR: disabled (-DENABLE_ASR=OFF). This was an isolated CMake script, not a full application configure. Clarify the documented condition; no build-policy change is requested:| `REQUIRE_ASR_GPU` | OFF | When ASR is enabled: no ASR GPU backend is built, system libwhisper's GPU support cannot be verified, or requested Metal precompilation cannot run. Has no effect with `ENABLE_ASR=OFF`. |
Verification and attacks that held
- Independently enumerated
option()declarations across tracked non-vendored CMake files: exactly 36 at head, all documented, with matching literal defaults. Checked the Windows-dependent DFNR default separately. The additional documented settings are sanitizer, DeepFist URL, RADE tap directory and FFTW time limit. - Programmatically resolved all 13 relevant links/anchors: ten in the guide and three inbound links.
git diff b89e36f7^ b89e36f7 --checkpassed. GitHub reports the commit signatureverified: true, reasonvalid. - Read dependency/fallback branches for RTL, DeepFist, Qt selection, GPU spectrum, SpecBleach, DFNR, AFX, whisper GPU requirements and opt-in test registration. Checked the separate DeepFist bundle against its feature guide. Those descriptions survived inspection except the GPU guard qualification above. Executed the exact disabled-ASR branch to test that exception.
- Test-boundary preflight: no test sources or CMake changes in the diff; no socket target added, changed, built or run. No GUI bridge session, app build, CTest, hardware use, or mutation testing was warranted for documentation-only changes. Platform configurations and runtime behavior were inspected, not empirically qualified. The separate automated code-review skill was unavailable; this was a manual review with scripted inventory/link checks. Previous bot suggestions were treated as leads, not evidence.
CI and recommendation
Approve with nits. All four currently required checks passed, but CI/Static Checks were created on 2026-10-02 at 19:52:41 UTC, before current main's 2026-10-04 at 15:55:50 UTC commit. Their pull_request runs tested an older merge result; branch protection has strict: false, so green does not establish current-main integration or the refreshed catalog. Incorporate the two new options and qualify the GPU guard; approval remains the maintainer's decision. This is a COMMENT review, with no inline threads.
…e the guide on CMake drift. Principle VIII. BUILD-OPTIONS.md gains rows for AETHER_SHARED_CORE and AETHER_BUILD_SPECTRUM_GESTURE_TEST, which reached main after this branch was cut. It adds a table of the HAVE_* compiler definitions CMake generates and what each is gated on. It states where a missing prerequisite fails configuration instead of disabling the feature: DeepFist without ONNX Runtime, GPU spectrum without Qt ShaderTools, Windows with AETHER_SHARED_CORE. It notes that the ASR GPU switches exist only on their platform branch, and that AETHERSDR_SANITIZER refuses address+thread and adds -g3 to every configuration. tools/check_build_options.py compares every option() and non-FORCE cache set() in the project CMake files with the guide's Option/Setting tables, in both directions, and checks literal ON/OFF defaults. Static checks runs it with --strict alongside its self-test. Against the guide as first proposed and current main it reports exactly the two missing options. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Blocker 1 (two options on main missing from the guide) is fixed in ccc2fb7: BUILD-OPTIONS.md now has rows for AETHER_SHARED_CORE and AETHER_BUILD_SPECTRUM_GESTURE_TEST. Proof: tools/check_build_options.py --strict reports that the guide matches all 38 options and 4 cache settings on current main. Run against the guide as first proposed, it reports exactly those two options as missing. The nits are also addressed in ccc2fb7: the configure-failure exceptions are stated, a drift check now runs in Static checks (maintainer decision), and the generated-define table is added.
ten9876
left a comment
There was a problem hiding this comment.
Approving at ccc2fb773.
Fixed in ccc2fb773:
- The two options that reached
mainafter this branch was cut,AETHER_SHARED_COREandAETHER_BUILD_SPECTRUM_GESTURE_TEST, now have rows. - New "Generated compiler definitions" table. Each row was checked against its
target_compile_definitionssite, including thatHAVE_SHERPAis private toaetherasrand thatHAVE_DBUSis non-Apple Unix only. - The rows now state where a missing prerequisite fails configuration: DeepFist without ONNX Runtime, GPU spectrum without ShaderTools, and
AETHER_SHARED_COREon Windows. - The ASR GPU switches are described as declared only on their branch.
- The sanitizer row notes that
addresswiththreadis refused and that-g3is added to every configuration. - Drift check (maintainer decision, including the workflow edit):
tools/check_build_options.py --strictand its self-test run in Static checks. The CI log on this head showsBUILD-OPTIONS.md matches every project option and cache settingandself-test: 0 failure(s). Run against the guide as first proposed, it reports exactly the two missing options. The self-test fails against a checker that never reports, and against the line-based comment parser.
Verified:
- The engine-boundary, test-registration, CI-test-gate and Qt-pin gates pass locally.
- An automated
/code-reviewpass at medium effort found three low-severity issues, and all three are fixed in this commit. - CI on
ccc2fb773: all checks pass. mainmoved once after this run was created:1d9a2c059(#5969), which touches onlysrc/gui/TxApplet.cppand a test. It adds no CMake option, and the PR merges cleanly.
Not applicable: this is a documentation and static-check change, with no app behavior to drive.
Main gained the RTL M1 work (aethersdr#5924), receive-control routing (aethersdr#5919), the int16 cast guards (aethersdr#6089), BUILD-OPTIONS.md (aethersdr#6098) and the v26.10.1 release prep (aethersdr#6159). Seven files this branch touches merged without conflict. WdspChannel::Config now has a defaulted operator== (aethersdr#5924); this branch's txAmCarrierLevel and txFmDeviationHz take part in it. None of main's changes sits under AETHER_HL2_TX_TXA. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Closes #6097.
Source builders currently have to read several CMake files and feature guides to discover optional decoders, experimental backends and their prerequisites. Add a top-level
BUILD-OPTIONS.mdcovering all 38 project-defined Boolean options and four additional cache settings, with defaults, platform/dependency requirements and configuration examples. A table lists theHAVE_*compiler definitions CMake generates and what each is gated on.Link the guide from the README, build guide and Developer Guide. Replace the Developer Guide's partial compiler-definition table with a link and an explanation of generated definitions, so the switch catalog has one home.
Keep the guide current with
tools/check_build_options.py. It compares everyoption()and non-FORCE cacheset()in the project CMake files, vendored trees excluded, with the guide's Option and Setting tables. It checks both directions and compares literal ON/OFF defaults. Static checks runs it with--strict, alongside a self-test that breaks each case on purpose. This PR changes.github/workflows/static-checks.ymlto add those two steps.Constitution principle honored
Principle VIII — Evidence Over Assertion: the option inventory and documented defaults were checked against the current project CMake sources, and documentation links were verified.
Test plan
python tools/check_build_options.py --strictpasses: 38 options and four cache settings match. Run against the guide as first proposed, it reportsAETHER_SHARED_COREandAETHER_BUILD_SPECTRUM_GESTURE_TESTas missing.python tools/test_check_build_options.py: 0 failures. Against a checker that never reports, it fails; against the line-based comment parser, it fails 3 cases.git diff HEAD^ HEAD --checkpasses.Documentation plus a stdlib-only static check. Application builds, CTest and radio/hardware tests were not run for this change.
Checklist
Verified.73, Ozy K6OZY · cost: unavailable (API-equivalent estimate unavailable) · model: gpt-6.1-sol