Skip to content

build(third-party): vendor liquid-dsp (MIT) as DSP toolkit foundation (#3043)#3046

Merged
ten9876 merged 3 commits into
mainfrom
auto/vendor-liquid-dsp
May 24, 2026
Merged

build(third-party): vendor liquid-dsp (MIT) as DSP toolkit foundation (#3043)#3046
ten9876 merged 3 commits into
mainfrom
auto/vendor-liquid-dsp

Conversation

@ten9876

@ten9876 ten9876 commented May 24, 2026

Copy link
Copy Markdown
Collaborator

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

  • 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 #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

  • Local Linux RelWithDebInfo build clean — 884 targets (vs ~682 baseline; delta is liquid-dsp's object files), no errors, no new warnings
  • Binary size verified — 266 MiB with vs 271 MiB without (smaller due to debug-info shuffling)
  • AetherSDR runs (no symbol-resolution issues at startup)
  • 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

  • No new flat-key `AppSettings` calls (N/A)
  • All meter UI uses `MeterSmoother` (N/A)
  • Documentation updated — THIRD_PARTY_LICENSES section 14 added
  • Vendored library follows third_party/ convention (COMMIT pin, LICENSE retained, dev infra trimmed)

Closes #3043.

🤖 Generated with Claude Code

…#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>
@ten9876 ten9876 enabled auto-merge (squash) May 24, 2026 06:15
ten9876 and others added 2 commits May 23, 2026 23:28
…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>

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

@ten9876 ten9876 merged commit e620cb9 into main May 24, 2026
4 of 5 checks passed
@ten9876 ten9876 deleted the auto/vendor-liquid-dsp branch May 24, 2026 15:36
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integrate liquid-dsp as comprehensive DSP toolkit (foundation for future modems + FEC + adaptive filters)

2 participants