fix(liquid-dsp): guard -lc/-lm link flags against WIN32 platforms#3220
Merged
Conversation
`target_link_libraries(${target} c m)` is a POSIX/Linux convention.
On Windows, the C runtime is linked automatically by both MinGW-w64 ld
and MSVC — passing `-lc`/`-lm` explicitly causes MinGW ld to error
with "cannot find -lc: No such file or directory" because there is no
standalone libc.a in the MinGW sysroot.
Wrap the call in `if(NOT WIN32)` so MinGW and MSVC builds skip the
redundant link flags while Linux/macOS behaviour is unchanged.
Fixes build on Windows with MinGW GCC 13.1.0 introduced when
liquid-dsp was vendored in PR aethersdr#3046. Tracks upstream issue aethersdr#3049.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
10 tasks
Contributor
There was a problem hiding this comment.
Thanks for the fix, @NF0T — clean, surgical, and the rationale in the inline comment + PR body is exactly what a future reader needs.
A couple of confirming notes:
WIN32is the right gate. It's set by CMake based on the target platform regardless of the toolchain, so both MinGW-w64 and MSVC are covered. No need to also testMSVC/MINGW.- The line
target_link_libraries(${target} c m)atthird_party/liquid-dsp/CMakeLists.txt:468is upstream liquid-dsp's POSIX assumption — leaving Linux/macOS untouched preserves upstream behavior, and the guard is the standard idiomatic fix used by other CMake-based ports of liquid-dsp. - Scope is appropriately tight: a single vendored-CMakeLists patch. Cleanly labelled as a stopgap until the proper Windows path lands via #3049.
One minor optional suggestion (non-blocking — feel free to ignore): since the if (fftw3f_FOUND) target_link_libraries(${target} fftw3f) block immediately below is unaffected on Windows, the current placement is fine. If you ever wanted to fold the guard, target_link_libraries(${target} $<$<NOT:$<BOOL:${WIN32}>>:c> $<$<NOT:$<BOOL:${WIN32}>>:m>) would work but is strictly less readable than what you have. The explicit if(NOT WIN32) block is the better choice here.
LGTM.
🤖 aethersdr-agent · cost: $3.9241 · model: claude-opus-4-7
ten9876
pushed a commit
that referenced
this pull request
May 27, 2026
…ign encoding (#3221) ## Summary Implements a unified RADE TX pipeline that correctly transmits End-of-Over (EOO) frames with an LDPC-encoded operator callsign, matching the behaviour of FreeDV-GUI through the same DAX TX path. Five root-cause fixes were required; EOO+callsign transmission is now OTA-confirmed against a FreeDV-GUI station (see Test plan). ## Constitution principle honored **Principle VIII — Evidence Over Assertion**: the EOO fix claim is backed by measured `Dtmax12_eoo` values (previously stuck at ~0.21, now reliably crossing the ~0.45 detection threshold), `rade_demod_wav -v 2` output reporting frame-level EOO detection, and OTA callsign decode ("NF0T") at the far end. The behavior change is demonstrated independently of the implementing agent's description. **Principle XI — Fixes Are Demonstrated**: the fix was demonstrated OTA against a FreeDV-GUI station before this PR was opened; the test criteria listed below were all met and are reproducible. **Principle X — Claims Are Atomic And Mortal**: branch rebased against current `main` (including the 109-commit upstream batch from 2026-05-27) before this PR was opened; no stale-snapshot overwrites. ## Changes ### Core pipeline (`src/core/`) - `RADEEngine`: three-layer PTT intercept — `PttOffHook` holds TX open while `setEooRequested(true)` → `rade_tx_eoo()` + callsign encoding → FIR flush → 60 ms silence tail → `eooFinished` signal → 254 ms transport timer → `set_mox=0` - `RADEEngine::setTxCallsign()` pre-encodes callsign via `rade_text_generate_tx_string()` / `rade_tx_set_eoo_bits()` - Named timing constants on the class: `kEooFrameMs` (144) + `kEooSilenceTailMs` (60) + `kEooTransportMarginMs` (50) = 254 ms total - `Resampler`: removed dead `flush()` stub; added `prewarm()` to stabilise FIR state before first audio block ### GUI (`src/gui/`) - `MainWindow`: three-layer PTT intercept wired up; `PttOffHook` intercepts MOX button, serial/MIDI, and CAT PTT paths; `kEooPlaybackMs` composed from named constants; DAX stream registration uses `qCDebug(lcRade)`; VFO signals explicitly disconnected on `deactivateRADE()` ### Diagnostics (`#ifdef RADE_WAV_TAP`, off by default) - Six TAP points (A–F) write per-PTT WAV files for offline analysis - `rade_demod_wav` build target (wrapped in `EXISTS` guard) for verifying EOO frame detectability with `rade_demod_wav -v 2` ### Docs - `docs/architecture/audio-pipeline.md`: EOO transmission and three-layer PTT intercept documented; TX flowchart and path table updated > **Architecture note:** the three-layer PTT intercept touches > `MainWindow.cpp` (maintainer-only CODEOWNERS tier). This is an > architectural change — flagging for maintainer review per CONTRIBUTING.md. ## Test plan - [x] Local build passes (`cmake --build build`) — MinGW/Windows clean - [x] `Dtmax12_eoo` crosses detection threshold (~0.45; was stuck at ~0.21) - [x] `rade_demod_wav -v 2` reports "End-of-over at modem frame N" - [x] OTA: far-end FreeDV-GUI station decodes "EOO callsign: NF0T" - [x] No regression in voice RX/TX quality - [ ] CI (Linux build — will run on PR open) > **Note:** FreeDV-GUI only decodes the EOO callsign when Reporting is > enabled (Tools → Options). `textPtr_` is null when reporting is off; > the EOO pilot is still detected but the callsign is silently skipped. > RC4 (output burst cadence) deferred — RC1–RC3/RC5 proved sufficient OTA. ## Checklist - [x] Commits are signed (`docs/COMMIT-SIGNING.md`) - [x] No new flat-key `AppSettings` calls — EOO timing constants are `static constexpr` on `RADEEngine` (Principle V) - [x] No new meter UI — `MeterSmoother` not applicable (Principle II) - [x] `docs/architecture/audio-pipeline.md` updated ## Related - Upstream issue #3049 (liquid-dsp Windows build) — stopgap in progress via PR #3220; that fix is not included here 🤖 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.
Problem
target_link_libraries(${target} c m)at line 468 ofthird_party/liquid-dsp/CMakeLists.txtis a POSIX/Linux convention.On Windows the C runtime is linked automatically by both MinGW-w64 and
MSVC — passing
-lc/-lmexplicitly causes MinGWldto fail atlink time:
This regression was introduced when liquid-dsp was vendored in #3046.
Fix
Wrap the
target_link_librariescall inif(NOT WIN32) … endif().WIN32is true for both MinGW-w64 and MSVC on Windows (it is aplatform 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
Ninja — no linker errors.
Related: #3049
🤖 Generated with Claude Code