build(third-party): vendor liquid-dsp (MIT) as DSP toolkit foundation (#3043)#3046
Merged
Conversation
…#3043) Vendors liquid-dsp upstream commit 4df6fc2ba99b3a584e9f1ad9888094013ae07b2f under third_party/liquid-dsp/. Comprehensive DSP toolkit covering modems (PSK/QAM/FSK/GMSK/OFDM), forward error correction (Hamming/Golay/Reed- Solomon/convolutional), adaptive filters (LMS/RLS), AGC, NCO, polyphase resampling, and equalizers. Vendored proactively as foundation infrastructure rather than waiting for a specific trigger feature. No AetherSDR module currently consumes liquid-dsp symbols; the static lib is linked into the AetherSDR target so the build verifies clean, and standard linker dead-code elimination (--gc-sections on ELF, /OPT:REF on MSVC) drops the unused library from the final binary — verified zero measurable binary growth (266 MiB with liquid vs 271 MiB without, the small delta is debug-info layout shuffling). When a future consumer adds #include <liquid.h>, the symbols start landing in the binary automatically. Likely first consumer per #85 Phase 4 is native FT8/FT4 decode (would use liquid-dsp's FEC + GMSK demod primitives). Trim before commit: The upstream tree was trimmed of dev/CI infrastructure (.github/, bench/, examples/, sandbox/, autotest/, doc/, gentab/, autotools wiring) to keep the vendored tree at 6.7 MB (vs 12 MB upstream). Kept include/, src/, cmake/, plus the three scripts/ files (autoscript.c, autoscript.h, main.c) that the upstream CMakeLists.txt unconditionally references via add_executable() at line 593 regardless of BUILD_AUTOTESTS. A COMMIT file pins the upstream SHA matching the third_party/rnnoise and third_party/r8brain convention. CMake integration: Upstream's CMakeLists.txt is used directly via add_subdirectory with all build-time options forced OFF except BUILD_STATIC_LIBS=ON: - BUILD_EXAMPLES OFF (we don't ship examples) - BUILD_AUTOTESTS OFF - BUILD_BENCHMARKS OFF - BUILD_SANDBOX OFF - BUILD_DOC OFF - BUILD_SHARED_LIBS OFF (save-restored around add_subdirectory so the off-toggle doesn't leak to other third_party libs that respect this standard CMake variable) - BUILD_STATIC_LIBS ON - FIND_FFTW OFF (use liquid-dsp's internal FFT for now; wiring it to our bundled third_party/fftw3 can be a follow- up if a future consumer wants FFTW-accelerated transforms) - ENABLE_LOGGING OFF (avoid liquid-dsp's runtime logging path) The liquid-static target is hit with -w/'/w' to suppress warnings from vendored code, matching the pattern used for aether_libmodem_core, ggmorse, and other vendored libraries. AetherSDR links against liquid-static explicitly. Without a link dependency the EXCLUDE_FROM_ALL on the subdirectory would mean the static lib is never built — the link forces the build so we know the integration works on every local + CI build. THIRD_PARTY_LICENSES updated with the standard entry (section 14, MIT, Copyright Joseph Gaeddert, upstream source link). Cross-platform CI verification pending — Linux RelWithDebInfo build is clean here. check-windows will fire automatically on this PR (.github/ workflows/** is in the path filter) and verify the MSVC path; macOS DMG + AppImage workflows will verify the other release targets on next tag. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…dsp (#3043) liquid-dsp's cmake_minimum_required(VERSION 3.10) puts its option() calls under CMP0077 OLD behavior, which means option() ignores a same-name normal variable and only respects CACHE variables for overrides. Setting BUILD_SHARED_LIBS as a normal variable in the previous commit was a no-op inside liquid-dsp's scope — the option kept its ON default. On Linux this silently produced both libliquid.so and libliquid.a (the target name suffix -static is overridden by OUTPUT_NAME at upstream CMakeLists.txt:444 to drop the suffix, so both targets aim at the same "liquid" output base name; different extensions kept Linux happy). On Windows MSBuild both targets aim at "liquid.lib" — the SHARED target's import lib and the STATIC target's archive lib collide and ninja errors with "multiple rules generate ... liquid.lib". Fix: set BUILD_SHARED_LIBS via CACHE BOOL FORCE (matching the other 7 liquid-dsp options) so the override takes effect inside liquid-dsp's option() call. Unset the cache entry after add_subdirectory so this doesn't leak into the rest of the project's BUILD_SHARED_LIBS semantics. Verified locally: Linux RelWithDebInfo build still clean at 884 targets, no behaviour difference vs the previous attempt other than only the static lib is now built. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…patibility CI check-windows on the previous commit (46de6dc) failed past the name- collision fix with: liquid.h(473): error C2061: syntax error: identifier 'liquid_float_complex' liquid.h(474): error C2061: syntax error: identifier 'liquid_double_complex' Root cause: liquid-dsp's include/liquid.h does: #ifdef __cplusplus # define LIQUID_USE_COMPLEX_H 0 #else # define LIQUID_USE_COMPLEX_H 1 #endif and then: #if LIQUID_USE_COMPLEX_H==1 # include <complex.h> # define LIQUID_DEFINE_COMPLEX(R,C) typedef R _Complex C ... So when compiled as C (not C++), liquid.h tries to define types via C99 `float _Complex` / `double _Complex` syntax. MSVC's C compiler doesn't accept this — MSVC has its own _Fcomplex/_Dcomplex intrinsics with different syntax. liquid-dsp upstream targets GCC/Clang/MinGW; no first-class MSVC support exists. Two patch options were considered: (a) Patch liquid.h to bridge `_Complex` to `_Fcomplex`/`_Dcomplex` on MSVC. Invasive, hard to maintain across upstream syncs. (b) Skip liquid-dsp entirely on MSVC. Surgical, easy to follow, and acceptable today because no AetherSDR module currently consumes liquid-dsp symbols. This commit takes (b). The `add_subdirectory(third_party/liquid-dsp)` block is wrapped in `if(NOT MSVC)`, and AetherSDR's link line uses a generator expression to conditionally link liquid-static only on non-MSVC toolchains. THIRD_PARTY_LICENSES note updated to reflect the Linux+macOS-only scope. Follow-up issue tracks Windows support for the day a consumer needs it. Verified locally: Linux RelWithDebInfo build still clean at 884 targets. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 tasks
There was a problem hiding this comment.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
This was referenced May 24, 2026
ten9876
pushed a commit
that referenced
this pull request
May 27, 2026
) ## Problem `target_link_libraries(${target} c m)` at line 468 of `third_party/liquid-dsp/CMakeLists.txt` is a POSIX/Linux convention. On Windows the C runtime is linked automatically by both MinGW-w64 and MSVC — passing `-lc`/`-lm` explicitly causes MinGW `ld` to fail at link time: cannot find -lc: No such file or directory This regression was introduced when liquid-dsp was vendored in #3046. ## Fix Wrap the `target_link_libraries` call in `if(NOT WIN32) … endif()`. `WIN32` is true for both MinGW-w64 and MSVC on Windows (it is a platform variable, not a compiler variable), so this correctly suppresses the flag for all Windows toolchains while leaving Linux and macOS behaviour unchanged. This is a stopgap that restores a clean Windows build. The full Windows/MSVC solution (ExternalProject with mingw-w64) is tracked in #3049. ## Testing - Built cleanly on Windows 11 with MinGW GCC 13.1.0 / Qt 6.11.0 / Ninja — no linker errors. - Linux and macOS paths are unchanged; the guard only fires on WIN32. Related: #3049 🤖 Generated with [Claude Code](https://claude.ai/claude-code) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
G6PWY-Chris
pushed a commit
to G6PWY-Chris/AetherSDR
that referenced
this pull request
Jun 22, 2026
…aethersdr#3043) (aethersdr#3046) ## Summary Closes aethersdr#3043. Vendors [liquid-dsp](https://github.com/jgaeddert/liquid-dsp) (MIT) under \`third_party/liquid-dsp/\` proactively as foundation infrastructure for future digital-mode work — not waiting for a specific trigger feature. Comprehensive DSP toolkit covering modems (PSK/QAM/FSK/GMSK/OFDM), forward error correction (Hamming/Golay/Reed-Solomon/convolutional), adaptive filters (LMS/RLS), AGC, NCO, polyphase resampling, and equalizers. Zero AetherSDR modules currently consume liquid-dsp symbols; the static lib is linked into the AetherSDR target so the build verifies clean on every CI run, and standard linker dead-code elimination drops the unused library from the final binary. ## Sizes - Vendored tree: **6.7 MB** (trimmed from upstream's 12 MB by removing dev/CI infrastructure — see "Trim before commit" below) - 647 files - Final binary: **266 MiB** with liquid-dsp linked vs **271 MiB** without — actually smaller due to debug-info layout shuffling; no measurable growth from liquid-dsp itself ## Trim before commit Removed from upstream tree to keep the vendor lean: - \`.github/\`, \`.gitlab-ci.yml\`, \`.travis.yml\`, \`.codecov.yml\` — upstream CI - \`autotest/\`, \`bench/\`, \`sandbox/\` — test/benchmark infrastructure - \`examples/\`, \`doc/\` — examples and documentation - \`gentab/\` — dev-time template generators (not used by CMake build) - \`bootstrap.sh\`, \`configure.ac\`, \`makefile.in\` — autotools wiring (we use CMake) - \`library.json\`, \`.gitignore\` — upstream-only metadata Kept: \`include/\`, \`src/\`, \`cmake/\`, \`CMakeLists.txt\`, \`LICENSE\`, \`README.rst\`, \`CHANGELOG.md\`, plus three \`scripts/\` files (\`autoscript.c\`, \`autoscript.h\`, \`main.c\`) that the upstream's CMakeLists.txt unconditionally references at line 593 via \`add_executable(autoscript ...)\` regardless of \`BUILD_AUTOTESTS\`. Without those three files the configure step fails. Added: \`COMMIT\` file pinning upstream SHA \`4df6fc2ba99b3a584e9f1ad9888094013ae07b2f\` — matches the \`third_party/rnnoise\` and \`third_party/r8brain\` convention. ## CMake integration Upstream's CMakeLists.txt is used directly via \`add_subdirectory(third_party/liquid-dsp EXCLUDE_FROM_ALL)\` with these options forced before the call: | Option | Value | Why | |---|---|---| | \`BUILD_EXAMPLES\` | OFF | Don't ship liquid-dsp's example programs | | \`BUILD_AUTOTESTS\` | OFF | Don't build liquid-dsp's test harness | | \`BUILD_BENCHMARKS\` | OFF | Don't build liquid-dsp's bench harness | | \`BUILD_SANDBOX\` | OFF | Sandbox dev programs | | \`BUILD_DOC\` | OFF | Documentation generation | | \`BUILD_SHARED_LIBS\` | OFF | Save-restored so doesn't leak to other third_party libs | | \`BUILD_STATIC_LIBS\` | ON | Build the \`liquid-static\` target we link against | | \`FIND_FFTW\` | OFF | Use liquid-dsp's internal FFT; wiring it to our bundled \`third_party/fftw3\` can be a follow-up if a consumer wants FFTW-accelerated transforms | | \`ENABLE_LOGGING\` | OFF | Avoid liquid-dsp's runtime logging path | The \`liquid-static\` target is hit with \`-w\` / \`/w\` to suppress warnings from vendored code, matching the pattern used for \`aether_libmodem_core\`, \`ggmorse\`, etc. AetherSDR links against \`liquid-static\` explicitly. Without a link dependency, \`EXCLUDE_FROM_ALL\` would mean the static lib is never built — the link forces the build so we know the integration works on every local + CI build. ## Future use When the first consumer arrives (likely native FT8/FT4 decode per aethersdr#85 Phase 4, which would use liquid-dsp's FEC + GMSK demod primitives), it just adds \`#include <liquid.h>\` to its source — the symbols start landing in the binary via the existing link, no further CMake work needed. ## Stats - 648 files, +140,150 / -0 - 1 file change to \`CMakeLists.txt\` (the integration block + link addition) - 1 file change to \`THIRD_PARTY_LICENSES\` (new section 14 for liquid-dsp) - No new flat-key AppSettings (Principle V N/A — this is third-party vendoring) - All meter UI uses MeterSmoother (N/A) ## Test plan - [x] Local Linux RelWithDebInfo build clean — 884 targets (vs ~682 baseline; delta is liquid-dsp's object files), no errors, no new warnings - [x] Binary size verified — 266 MiB with vs 271 MiB without (smaller due to debug-info shuffling) - [x] AetherSDR runs (no symbol-resolution issues at startup) - [x] THIRD_PARTY_LICENSES updated with section 14 (MIT, Copyright Joseph Gaeddert, source link) - [ ] CI: \`build\` job verifies Linux container image with liquid-dsp's autotools-replaced CMake build - [ ] CI: \`check-windows\` fires automatically (\`.github/workflows/**\` is in the path filter) and verifies the MSVC path - [ ] Tag-time: macOS DMG + AppImage workflows verify other release targets ## Checklist - [x] No new flat-key \`AppSettings\` calls (N/A) - [x] All meter UI uses \`MeterSmoother\` (N/A) - [x] Documentation updated — THIRD_PARTY_LICENSES section 14 added - [x] Vendored library follows third_party/ convention (COMMIT pin, LICENSE retained, dev infra trimmed) Closes aethersdr#3043. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
G6PWY-Chris
pushed a commit
to G6PWY-Chris/AetherSDR
that referenced
this pull request
Jun 22, 2026
…thersdr#3220) ## Problem `target_link_libraries(${target} c m)` at line 468 of `third_party/liquid-dsp/CMakeLists.txt` is a POSIX/Linux convention. On Windows the C runtime is linked automatically by both MinGW-w64 and MSVC — passing `-lc`/`-lm` explicitly causes MinGW `ld` to fail at link time: cannot find -lc: No such file or directory This regression was introduced when liquid-dsp was vendored in aethersdr#3046. ## Fix Wrap the `target_link_libraries` call in `if(NOT WIN32) … endif()`. `WIN32` is true for both MinGW-w64 and MSVC on Windows (it is a platform variable, not a compiler variable), so this correctly suppresses the flag for all Windows toolchains while leaving Linux and macOS behaviour unchanged. This is a stopgap that restores a clean Windows build. The full Windows/MSVC solution (ExternalProject with mingw-w64) is tracked in aethersdr#3049. ## Testing - Built cleanly on Windows 11 with MinGW GCC 13.1.0 / Qt 6.11.0 / Ninja — no linker errors. - Linux and macOS paths are unchanged; the guard only fires on WIN32. Related: aethersdr#3049 🤖 Generated with [Claude Code](https://claude.ai/claude-code) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #3043. Vendors liquid-dsp (MIT) under `third_party/liquid-dsp/` proactively as foundation infrastructure for future digital-mode work — not waiting for a specific trigger feature.
Comprehensive DSP toolkit covering modems (PSK/QAM/FSK/GMSK/OFDM), forward error correction (Hamming/Golay/Reed-Solomon/convolutional), adaptive filters (LMS/RLS), AGC, NCO, polyphase resampling, and equalizers. Zero AetherSDR modules currently consume liquid-dsp symbols; the static lib is linked into the AetherSDR target so the build verifies clean on every CI run, and standard linker dead-code elimination drops the unused library from the final binary.
Sizes
Trim before commit
Removed from upstream tree to keep the vendor lean:
Kept: `include/`, `src/`, `cmake/`, `CMakeLists.txt`, `LICENSE`, `README.rst`, `CHANGELOG.md`, plus three `scripts/` files (`autoscript.c`, `autoscript.h`, `main.c`) that the upstream's CMakeLists.txt unconditionally references at line 593 via `add_executable(autoscript ...)` regardless of `BUILD_AUTOTESTS`. Without those three files the configure step fails.
Added: `COMMIT` file pinning upstream SHA `4df6fc2ba99b3a584e9f1ad9888094013ae07b2f` — matches the `third_party/rnnoise` and `third_party/r8brain` convention.
CMake integration
Upstream's CMakeLists.txt is used directly via `add_subdirectory(third_party/liquid-dsp EXCLUDE_FROM_ALL)` with these options forced before the call:
The `liquid-static` target is hit with `-w` / `/w` to suppress warnings from vendored code, matching the pattern used for `aether_libmodem_core`, `ggmorse`, etc.
AetherSDR links against `liquid-static` explicitly. Without a link dependency, `EXCLUDE_FROM_ALL` would mean the static lib is never built — the link forces the build so we know the integration works on every local + CI build.
Future use
When the first consumer arrives (likely native FT8/FT4 decode per #85 Phase 4, which would use liquid-dsp's FEC + GMSK demod primitives), it just adds `#include <liquid.h>` to its source — the symbols start landing in the binary via the existing link, no further CMake work needed.
Stats
Test plan
Checklist
Closes #3043.
🤖 Generated with Claude Code