# Compile-time build options
This is the reference for AetherSDR's project-defined CMake options. Start with
the [source-build instructions](README.md#building-from-source) for dependencies
and the [build guide](docs/BUILDING.md) for platform setup.
Defaults below apply to a fresh configuration. An existing build directory
keeps its cached choices, and release workflows can override the defaults.
An option set to `ON` requests a feature; missing dependencies or an unsupported
platform can still disable it. Read CMake's configure messages for availability.
The rows that say configuration fails are the exceptions: there a missing
prerequisite stops the configure instead of disabling the feature.
## Setting and inspecting options
Pass Boolean switches as `-DNAME=ON` or `-DNAME=OFF` when configuring, then
rebuild. For example, request the RTL-SDR backend:
```bash
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_RTL=ON
cmake --build build --parallel
```
Use a separate build directory for an experiment if you want to retain your
normal configuration. Print the cache values and help for an already configured
build without configuring or building it again:
```bash
cmake -LAH -N build
```
That cache also includes standard CMake settings, detected library paths and
vendored-library options. This guide lists AetherSDR's own selectable options
and additional project cache values. Changing them requires a source rebuild;
they are not runtime settings for a downloaded binary.
## Build type and debug info
With no `CMAKE_BUILD_TYPE`, the build is `RelWithDebInfo`. On GCC and Clang,
`RelWithDebInfo` uses `-O2 -g1 -DNDEBUG` rather than CMake's `-g`. That keeps
line tables and function names, so backtraces and core dumps still symbolize,
and keeps each test binary a fraction of the size. When you need local
variables and types in a debugger, build `Debug`, or ask for full debug info
explicitly:
```bash
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo \
"-DCMAKE_C_FLAGS_RELWITHDEBINFO=-O2 -g2 -DNDEBUG" \
"-DCMAKE_CXX_FLAGS_RELWITHDEBINFO=-O2 -g2 -DNDEBUG"
```
Spell it `-g2`. A value identical to CMake's default (`-O2 -g -DNDEBUG`) cannot
be told apart from no choice, so it is lowered too. A debug level already in
`CFLAGS`/`CXXFLAGS` (for example `-g3` for a sanitizer run) leaves the default
alone. MSVC flags and `Release` builds are unaffected.
## Radio backends and decoder experiments
| Option | Default | Purpose and prerequisites |
|---|---|---|
| `ENABLE_RTL` | ON | Build the experimental receive-only RTL-SDR USB backend when both `librtlsdr` and single-precision FFTW (`fftw3f`) are found. Missing either disables the backend unless `REQUIRE_RTL=ON`. |
| `AETHER_HL2_TX_TXA` | ON | Select WDSP's TXA chain as the Hermes-Lite 2 transmit modulator: SSB, AM, DSB and FM. OFF builds the in-tree phasing modulator, which is SSB only; AM, DSB and FM then stay receive-only. This choice has no runtime toggle. |
**Neural CW decoders:** DeepFist and DeepCW build whenever ONNX Runtime is
found at configure time (Apple Silicon macOS, Linux and Windows; the pinned
runtime has no Intel-macOS build), with no separate option. Neither model is
bundled: each downloads on first use from its upstream source at a pinned size
and SHA-256. For developer qualification, the runtime environment variables
`AETHER_DEEPFIST_MODEL_DIR` and `AETHER_DEEPCW_MODEL_DIR` point at a local
copy instead; they are not CMake switches. See
[the DeepFist guide](docs/deepfist-cw-backend.md). ggmorse remains the default
CW receive decoder.
**Other radio families:** Flex, Hermes-Lite 2, Icom, ANAN-G2 and the synthetic
demo backend are included in normal builds without separate enable switches.
Choose the radio or demo mode when connecting. Hermes-Lite 2 and ANAN-G2 are
experimental; Icom support depends on the model. See
[Supported Hardware](README.md#supported-hardware) for the current coverage and
receive/transmit limits. Compiling a backend does not establish hardware support.
## Audio, digital voice, speech and display features
| Option | Default | Purpose and prerequisites |
|---|---|---|
| `ENABLE_RADE` | ON | RADE digital voice using the vendored RADE/Opus sources. |
| `ENABLE_DSTAR` | ON | Local D-STAR waveform helper using vendored smartsdr-dsp/ThumbDV support. |
| `ENABLE_DATA2G` | ON | Vendored Data2G HF data modem core (`third_party/data2g`, RFC #7159) and AetherModem's receive-only **HF Data** tab. OFF builds without the core and hides the tab. |
| `ENABLE_SPECBLEACH` | ON | NR4 spectral noise reduction. MSVC builds also need `clang-cl`; otherwise CMake disables it. |
| `ENABLE_DFNR` | ON | DFNR DeepFilterNet3 noise reduction. Run `scripts/setup/setup-deepfilter.sh` (Windows: `setup-deepfilter.ps1`) before configuring. A missing library disables it. |
| `ENABLE_NVIDIA_AFX` | ON | BNR NVIDIA Maxine AFX GPU denoiser wrapper on x86-64 Linux/Windows. Operation needs a compatible NVIDIA GPU and the runtime/model pack, downloaded on demand. |
| `ENABLE_ASR` | ON | On-device speech recognition through whisper.cpp. Speech model weights are downloaded separately. |
| `ENABLE_ASR_METAL` | ON | ASR Metal acceleration on macOS. Declared only on macOS with ASR enabled; elsewhere the switch does not exist and `-D` produces only an unused-variable warning. |
| `ENABLE_ASR_VULKAN` | ON | ASR Vulkan acceleration when the GPU build dependencies are found. Declared only on non-macOS platforms with ASR enabled; on macOS the switch does not exist. |
| `ENABLE_ASR_METAL_PRECOMPILE` | ON | Precompile Metal kernels on macOS. Declared only for vendored whisper builds (`USE_SYSTEM_LIBWHISPER=OFF`) with ASR enabled. Needs the offline Metal toolchain; a missing compiler warns and falls back to shader source unless `REQUIRE_ASR_GPU` is ON. |
| `AETHER_GPU_SPECTRUM` | ON | QRhi spectrum/waterfall rendering. Needs Qt ShaderTools (configuration fails without it) and private QtGui headers; missing private headers select the CPU build. See [GPU spectrum rendering](docs/BUILDING.md#gpu-spectrum-rendering). |
| `ENABLE_MQTT` | ON | MQTT client support using bundled libmosquitto or the selected system library. |
| `MQTT_TLS` | ON | MQTT TLS support. The bundled library uses OpenSSL when found; OFF omits TLS. |
## Packaging and dependency selection
| Option | Default | Purpose |
|---|---|---|
| `AETHER_USE_PINNED_QT` | ON | Prefer the cached release Qt when present. An explicit Qt path takes precedence. |
| `AETHER_FETCH_QT` | OFF | Run the Qt setup script at configure time if the pinned Qt is missing. This can download the Qt toolchain. |
| `AETHER_EMBED_DFNR_MODEL` | ON on Windows; OFF elsewhere | Embed the DFNR model payload in application resources instead of deploying a loose archive. Relevant when DFNR is built. |
| `ASR_USE_PREBUILT_WHISPER_GPU` | OFF | Windows fallback that consumes the pinned prebuilt whisper GPU pack instead of building the vendored sources. The pack predates local source patches; leave OFF for the normal source build. |
| `LOWER_CASE_BINARY_NAME` | OFF | Use a lowercase executable name on Linux. |
| `USE_SYSTEM_ZLIB` | OFF | Use system zlib instead of the bundled snapshot. |
| `USE_SYSTEM_MSPACK` | OFF | Use system libmspack instead of the bundled snapshot. |
| `USE_SYSTEM_LIBMOSQUITTO` | OFF | Use system libmosquitto when MQTT is enabled. |
| `USE_SYSTEM_RTMIDI` | OFF | Use system RtMidi instead of the bundled snapshot. |
| `USE_SYSTEM_LIBWHISPER` | OFF | Use system libwhisper for ASR. Its GPU support and shader packaging are determined by that library's build. |
| `USE_SYSTEM_SQLITE` | OFF | Use system sqlite3 instead of the bundled snapshot. |
The `USE_SYSTEM_*` choices are primarily for distro packaging. Dependencies
enabled in the build use bundled, pinned snapshots by default. Qt setup and
custom Qt paths are documented in [the build guide](docs/BUILDING.md).
## Required-dependency checks
These switches turn missing optional capabilities into configure errors. They
are useful for release builds that must include those capabilities.
| Option | Default | Fail configuration when… |
|---|---|---|
| `REQUIRE_RTL` | OFF | RTL is disabled, or `librtlsdr` or single-precision FFTW (`fftw3f`) is missing. Official release workflows set this ON together with `ENABLE_RTL=ON`. |
| `REQUIRE_SERIALPORT` | OFF | Qt SerialPort is missing. |
| `REQUIRE_KEYCHAIN` | OFF | QtKeychain is missing. |
| `REQUIRE_ASR_ONNX` | OFF | ONNX Runtime is missing for Silero VAD, speaker labeling and the signal classifier. |
| `REQUIRE_ASR_GPU` | OFF | No ASR GPU backend is built, system libwhisper's GPU support cannot be verified, or requested Metal precompilation cannot run. |
| `REQUIRE_ASR_SHERPA` | OFF | sherpa-onnx is missing for the non-whisper ASR backend. |
Some capabilities are enabled by dependency detection rather than a dedicated
enable switch: Qt SerialPort, Qt WebSockets, QtKeychain, PortAudio, USB HID
support, ONNX Runtime, sherpa-onnx and native Linux PipeWire support. Setup scripts for
ONNX Runtime and sherpa-onnx are under `scripts/setup/`.
### Generated compiler definitions
CMake defines these from the resulting configuration. They are outputs, not
user-facing `-D` switches; code tests them with `#ifdef`. All are public on
`aethercore`, so engine and GUI code see them, except `HAVE_SHERPA`, which only
the ASR library (`aetherasr`) sees.
| Definition | Defined when |
|---|---|
| `HAVE_RADE` | RADE is built (`ENABLE_RADE`). |
| `HAVE_OPUS` | RADE is built, or a system Opus is found. |
| `HAVE_SPECBLEACH` | `ENABLE_SPECBLEACH` is still ON after the MSVC `clang-cl` check. |
| `HAVE_DFNR` | `ENABLE_DFNR` is still ON after the DeepFilterNet library check. |
| `HAVE_NVIDIA_AFX` | `ENABLE_NVIDIA_AFX` on x86-64 Linux or Windows. |
| `HAVE_MQTT` | `ENABLE_MQTT`. |
| `HAVE_MQTT_TLS` | `MQTT_TLS`, and for the bundled library OpenSSL is found. |
| `HAVE_DEEPFIST`, `HAVE_DEEPCW`, `HAVE_CW_RX_BACKENDS` | ONNX Runtime is found. |
| `HAVE_MIDI` | Always; RtMidi is bundled. |
| `HAVE_SERIALPORT`, `HAVE_WEBSOCKETS`, `HAVE_KEYCHAIN` | The Qt SerialPort, Qt WebSockets or QtKeychain package is found. |
| `HAVE_DBUS` | Qt DBus is found on Linux or another non-Apple Unix; it is never looked for on macOS or Windows. |
| `HAVE_ONNX` | ONNX Runtime is found. |
| `HAVE_SHERPA` | sherpa-onnx is found and ASR is built. Private to `aetherasr`. |
| `HAVE_HIDAPI`, `HAVE_PORTAUDIO`, `HAVE_FFTW3` | hidapi, PortAudio or FFTW3 is found. |
| `HAVE_PIPEWIRE`, `HAVE_PIPEWIRE_NATIVE` | Linux; the native variant also needs `libpipewire-0.3` development files. |
## Diagnostics and opt-in tests
These options are for development and qualification.
| Option | Default | Purpose and prerequisites |
|---|---|---|
| `RADE_WAV_TAP` | OFF | Write diagnostic WAV files at RADE transmit tap points when RADE is built. Output directory: `RADE_TAP_DIR`. |
| `AETHER_ENABLE_FLEX_RETRY_SOCKET_TEST` | OFF | Build/register the Flex TCP retry diagnostic. Uses an ephemeral localhost TCP listener to check recovery after source-bound connection refusal; no radio is required. |
| `AETHER_ENABLE_HL2_RECEIVER_CHURN_TEST` | OFF | Build/register the fake-EP6 receiver-churn test used by sanitizer runs. |
| `AETHER_ENABLE_HL2_TX_LOOPBACK_TEST` | OFF | Build/register HL2 transmit-loopback and DSP-readback tests against an external `hpsdrsim` peer. The loopback test keys the simulated transmitter; a missing simulator produces a skip. |
| `AETHER_ENABLE_HL2_SIGNAL_STOP_TEST` | OFF | Build the HL2 signal-stop child process. The loopback-UDP process test is registered on non-Windows hosts with Python 3. |
| `AETHER_ENABLE_RADAR_GL_TEST` | OFF | Build/register the native-GPU weather-radar texture test. Needs a real OpenGL 3.2 context. |
| `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, and `spectrum_pan_pixels_retina_test`, the same binary at a Retina scale factor pinning the Flex pan `xpixels` cap. |
| `AETHER_SHARED_CORE` | OFF | Build `libaethercore` as a shared library so the test binaries fit on a hosted runner. For the sanitizer lanes, the Linux `ci.yml` and `full-suite.yml` builds, and local review builds (`/pr-review` step 7); never for releases; configuration fails on Windows. |
| `AETHER_FIRMWARE_DEV_OVERRIDES` | OFF | Honor the `AETHER_FIRMWARE_CATALOG` (another firmware catalog URL) and `AETHER_FIRMWARE_TRUST_KEYS` (extra Ed25519 firmware-signing keys, hex, comma-separated) environment variables, for testing a firmware publisher's own builds. Each override is logged when used. Never for releases: a release build installs only firmware listed at aethersdr.com and signed by a key built into it. |
| `AETHER_UPDATE_DEV_OVERRIDES` | OFF | Honor four environment variables of the in-app updater, for trying an update end to end before there is a release to update to: `AETHER_UPDATE_MANIFEST_URL` (another signed manifest), `AETHER_UPDATE_TRUST_KEYS` (extra Ed25519 update-signing keys, hex, comma-separated), `AETHER_UPDATE_DOWNLOAD_BASE` (fetch release files from `//`; the URLs the manifest signs are still checked) and `AETHER_UPDATE_PRETEND_VERSION` (run as an older version; never passed on to the self-test or a restart). Each override is logged when used. `windows-installer.yml`'s `dev_overrides` dispatch input builds one, refused on a tag or with the Store flight. Never for releases. |
Additional cache values accept a value rather than ON/OFF:
| Setting | Default | Values and purpose |
|---|---|---|
| `AETHERSDR_SANITIZER` | `none` | `none`, `address`, `undefined`, `address,undefined`, or `thread`. Instruments the main CMake tree with a GNU-driver GCC/Clang build; MSVC and clang-cl are rejected, and so is combining `address` with `thread`. Adds `-g3 -fno-omit-frame-pointer` to every configuration, Release included. ExternalProject children need separate sanitizer flags. |
| `DEEPFIST_MODEL_BASE_URL` | Empty (N9BC's `exp27_bt-champion` release) | Replaces the HTTPS directory holding the exact DeepFist model assets; empty uses the published release. The LICENSE asset carries its own pinned source. See [the DeepFist guide](docs/deepfist-cw-backend.md). |
| `RADE_TAP_DIR` | `/rade_taps` | Directory for RADE WAV diagnostics; available when RADE and its taps are enabled. |
| `AETHER_TEST_FFTW_TIMELIMIT` | `0.001` | Seconds FFTW may spend measuring each plan under test; an empty value allows unbounded measurement. |
| `AETHER_SANITIZER_TIMEOUT_SCALE` | `4` | Positive integer. Multiplier applied to every test `TIMEOUT` when the build is sanitizer-instrumented (`AETHERSDR_SANITIZER` set, or `-fsanitize=` in the global C/C++ flags or in any configuration's `CMAKE__FLAGS_`). An uninstrumented build keeps every limit exactly as written. |
## macOS application identity
| Option | Default | Purpose |
|---|---|---|
| `AETHER_MACOS_ADHOC_SIGN` | OFF | Opt in to ad-hoc signing for local non-Xcode macOS development builds. Signs nested code before the complete app bundle. Leave OFF for production/distribution builds. |
| Setting | Default | Purpose |
|---|---|---|
| `AETHER_MACOS_BUNDLE_IDENTIFIER` | `com.aethersdr.AetherSDR` | macOS only. Set a distinct reverse-DNS identifier, such as `com.aethersdr.AetherSDR.dev`, to give a local development build its own privacy permissions alongside an installed release. |
With `AETHER_MACOS_ADHOC_SIGN=ON`, non-Xcode macOS builds sign nested code,
then sign and verify the complete app bundle after copying resources and helpers.
This is local development signing only: ad-hoc signatures, not an Apple
distribution identity or a persistent self-signed certificate.
The option defaults to OFF; production Apple signing, notarization and release CI
keep their existing workflow and do not enable it. Xcode handles signing itself.
An ad-hoc signature does not guarantee that privacy or Keychain approvals
survive a rebuild; persistent development signing is a separate workflow.
## Keeping this reference current
Option definitions live in [CMakeLists.txt](CMakeLists.txt),
[cmake/AetherQtPin.cmake](cmake/AetherQtPin.cmake),
[cmake/MacOSDevelopmentSigning.cmake](cmake/MacOSDevelopmentSigning.cmake), and
[tests/tests.cmake](tests/tests.cmake). Update this reference in the same change
that adds, removes or changes a project option or its default.
`tools/check_build_options.py --strict` runs in Static checks and fails when an
option or value setting is missing here, is listed here but no longer defined,
or has a different `ON`/`OFF` default.