Skip to content

Added option to use some system libraries#3135

Merged
ten9876 merged 6 commits into
aethersdr:mainfrom
dawkagaming:main
May 25, 2026
Merged

Added option to use some system libraries#3135
ten9876 merged 6 commits into
aethersdr:mainfrom
dawkagaming:main

Conversation

@dawkagaming

Copy link
Copy Markdown
Contributor

Hello,

as I said in the discussions, it would be nice to optionally enable use of some system libraries (this would help is building AetherSDR for Linux distributions packaging)

I tried to do this in this commit, I hope it is worth something.

Thanks,
Dawid SP9SKA

@dawkagaming dawkagaming requested a review from a team as a code owner May 25, 2026 14:42
@dawkagaming dawkagaming force-pushed the main branch 3 times, most recently from 05705fc to f14cb91 Compare May 25, 2026 14:47
@aethersdr-agent

Copy link
Copy Markdown
Contributor

Hi @dawkagaming — thanks for working on system-library support! Distro packaging is a great direction. The CI Configure step is failing on build (Linux), check-windows, and analyze (cpp) — all three are blocked at CMake configure time before compilation starts. Here's what I see in the diff:

1. target_link_libraries(AetherSDR …) is called before the AetherSDR target exists

In the new zlib block (around line 63):

if (USE_SYSTEM_ZLIB)
    cmake_pkg_config(IMPORT zlib REQUIRED NAME zlib)
    target_link_libraries(AetherSDR PRIVATE PkgConfig::zlib)
else()
    add_subdirectory(third_party/zlib EXCLUDE_FROM_ALL)
    target_link_libraries(AetherSDR PRIVATE zlibstatic)
endif()

The AetherSDR executable target isn't created until much later in the file (via qt_add_executable(AetherSDR …) around line 870). CMake errors out with something like:

Cannot specify link libraries for target "AetherSDR" which is not built by this project.

This fires on the default configuration (USE_SYSTEM_ZLIB=OFF), which is why all three platforms fail — not just Linux. The original code worked because add_subdirectory(third_party/zlib EXCLUDE_FROM_ALL) just declares zlibstatic as an available target, and the actual target_link_libraries(AetherSDR PRIVATE … zlibstatic …) happened in the big bundled block at line ~932, after AetherSDR is defined.

Fix: Keep add_subdirectory(...) / find_package(...) early, but defer the target_link_libraries(AetherSDR …) calls until after qt_add_executable(AetherSDR …). The same pattern applies to your new mspack, libmosquitto, and alsa blocks.

2. cmake_pkg_config is not a standard CMake command

You're using cmake_pkg_config(IMPORT zlib REQUIRED NAME zlib) in several places. I don't think this command exists in vanilla CMake — once you fix issue #1 and CMake gets past the target ordering error, this will fail next with:

Unknown CMake command "cmake_pkg_config".

The standard pkg-config pattern in CMake is (docs):

find_package(PkgConfig REQUIRED)
pkg_check_modules(zlib REQUIRED IMPORTED_TARGET zlib)
# then later:
target_link_libraries(AetherSDR PRIVATE PkgConfig::zlib)

There's already precedent for this in the file — see the ENABLE_BNR block around line 277 which does exactly this for grpc++.

The alsa branch on line ~1041 also uses cmake_pkg_config and is unconditional on Linux (no USE_SYSTEM_* guard), which would break the Linux build outright even if the rest were fixed.

3. Minor: inconsistent option names

  • Declared as USE_SYSTEM_LIBMOSQUITTO (line 11) but checked as USE_SYSTEM_MOSQUITTO (line ~1293) — these need to match.
  • USE_SYSTEM_RTMIDI is checked but never declared via option(...).
  • option(USE_SYSTEM_ZLIB OFF) is missing the description string — the signature is option(<var> "<help_text>" [value]), so right now OFF is being parsed as the help text. Not fatal but worth tidying.

Suggested approach: I'd recommend a smaller first PR that adds just USE_SYSTEM_ZLIB end-to-end with the correct CMake idioms — that gives reviewers a clean template, and then mspack/mosquitto/rtmidi can follow the same pattern in a follow-up. Happy to help if you'd like a paired-down version to start from.

Thanks again for tackling this — distro packaging support is genuinely valuable and the option-block consolidation at the top of the file is a nice readability improvement.

73 — AetherClaude 🤖


🤖 aethersdr-agent · cost: $9.8532 · model: claude-opus-4-7

@dawkagaming

Copy link
Copy Markdown
Contributor Author

Actually the docs (https://cmake.org/cmake/help/latest/module/FindPkgConfig.html) mention that, quote:

The cmake_pkg_config() command for a modern and more advanced way to work with pkg-config in CMake without requiring pkg-config executable to be installed.

Here is the documentation for it: https://cmake.org/cmake/help/latest/command/cmake_pkg_config.html

@dawkagaming dawkagaming force-pushed the main branch 2 times, most recently from 4b5dd99 to a2c53d2 Compare May 25, 2026 16:00
Signed-off-by: dawkagaming <147207983+dawkagaming@users.noreply.github.com>
dawkagaming and others added 2 commits May 25, 2026 21:46
…TT placement

Conflict resolutions in CMakeLists.txt:

* Option block conflict (top of file) — combined Dawid's centralised
  USE_SYSTEM_* + build-feature option block with main's
  LOWER_CASE_BINARY_NAME option (PR aethersdr#3138).
* Link-libraries block conflict (~line 875) — kept both the new
  USE_SYSTEM_* target_link_libraries calls and main's new
  LOWER_CASE_BINARY_NAME OUTPUT_NAME logic.  Independent additions,
  both retained.

Additional fixes on top:

* Dropped cmake_minimum_required from 3.25 back to 3.20.  After the
  switch from cmake_pkg_config to pkg_check_modules(IMPORTED_TARGET ...)
  nothing in the new code needs 3.25.  Restoring the original 3.20 keeps
  Debian 12 (cmake 3.25) friendly and matches what the rest of the file
  was written against.

* HAVE_MQTT / HAVE_MQTT_TLS placement — the previous form nested
  `target_compile_definitions(... HAVE_MQTT)` inside
  `if (NOT USE_SYSTEM_LIBMOSQUITTO)`, so USE_SYSTEM_LIBMOSQUITTO=ON would
  link against the system package but leave HAVE_MQTT undefined, meaning
  every `#ifdef HAVE_MQTT` block in the rest of the codebase compiled out.
  Moved HAVE_MQTT to the outer ENABLE_MQTT scope, and route HAVE_MQTT_TLS
  on the system-mosquitto branch through the existing MQTT_TLS option
  (distro mosquitto packages are conventionally TLS-enabled).

Local build clean against the bundled defaults (USE_SYSTEM_* all OFF).

Co-Authored-By: dawkagaming <147207983+dawkagaming@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876

ten9876 commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Claude here — really nice work on this, Dawid! Distro packaging is exactly the kind of thing AetherSDR needs more attention to, and the USE_SYSTEM_* flag pattern you picked is the right shape for it. Saw your follow-up commit moving from cmake_pkg_configpkg_check_modules(... IMPORTED_TARGET) — that's a great instinct; that command pair has been the durable cross-version CMake idiom for over a decade and works on every distro that matters.

Pushed a follow-up commit on top of your branch (with your permission via "allow maintainers to edit" — thanks for leaving that on). Three things in the merge:

1. Resolved the conflicts with current main. Two collisions, both clean to merge:

  • Your centralised option block at the top of the file met the new LOWER_CASE_BINARY_NAME option (your other PR, Add option to make the binary's name lower case #3138 — already merged!) — combined them into the same block so all options stay in one place.
  • Your new USE_SYSTEM_* target_link_libraries block met that PR's LOWER_CASE_BINARY_NAME OUTPUT_NAME logic just below — independent additions, kept both.

2. Dropped cmake_minimum_required from 3.25 back to 3.20. After your switch to pkg_check_modules(IMPORTED_TARGET ...) (which has been around since CMake 3.6), nothing in the new code actually needs 3.25 anymore. Restoring the original 3.20 keeps Debian 12 (which ships CMake 3.25) and older LTS distros buildable — the exact packagers this PR is meant to help.

3. Fixed an #ifdef HAVE_MQTT placement bug. This one was subtle: the previous form nested target_compile_definitions(... HAVE_MQTT) inside the if (NOT USE_SYSTEM_LIBMOSQUITTO) branch. So a packager building with -DUSE_SYSTEM_LIBMOSQUITTO=ON would link against the system mosquitto package — but HAVE_MQTT would never get defined, and every #ifdef HAVE_MQTT block in the rest of the project (MqttApplet, the radio model's MQTT plumbing, etc.) would compile out. Net result: a quietly broken MQTT build despite all the linkage being correct. Moved HAVE_MQTT to the outer ENABLE_MQTT scope so it gates the codebase regardless of bundled/system choice. Same fix for HAVE_MQTT_TLS — assumed on for system mosquitto unless -DMQTT_TLS=OFF (distro packages essentially always ship with TLS support).

Locally verified the default-bundled path (USE_SYSTEM_* all OFF) still builds clean. CI is re-running now.

This is a really useful contribution and I'm glad to land it — would love to see follow-ups for any other vendored dependencies you spot, and packaging recipes (AUR PKGBUILD, .deb control, etc.) if you end up writing any for your distro of choice.

Welcome to the project, and 73 from across the pond!

73, Jeremy KK7GWY & Claude (AI dev partner)

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks Dawid (SP9SKA) — the overall shape is good. Defaults-OFF keeps the bundled, version-pinned third_party/ snapshots as the default for CI, releases, and contributor builds, while letting distro packagers swap to system copies. That's the right tradeoff. A few specific things worth tightening before merge:

Scope: two unrelated changes mixed in

The PR description scopes this to "optional system libraries," but the diff also includes two behavior changes that aren't gated by any USE_SYSTEM_* option:

  1. cmake_minimum_required(VERSION 3.25)3.20 (line 1). This is an unrelated relaxation. If the motivation is to support a specific packaging target (e.g. Ubuntu 22.04 ships CMake 3.22), please call that out in the PR description and the commit message. Otherwise, recommend leaving 3.25 in place — lowering the floor risks silently masking 3.25-feature regressions that only surface on newer hosts. I grep'd for the common 3.25 features (block(), add_subdirectory(... SYSTEM), cmake_path, file(COPY_FILE), etc.) and don't see any actively used, so the lowering is probably safe, but the change needs explicit justification.

  2. ALSA: target_link_libraries(... asound)pkg_check_modules(alsa REQUIRED IMPORTED_TARGET alsa) (around line 1085). This is a hard change for all Linux builds, not gated by a USE_SYSTEM_* flag, and now requires pkg-config on every Linux build host. Most distros have it, but it's still a new hard requirement. Either gate this behind a flag or split it into its own PR/commit with a short justification.

Splitting these out (or at minimum acknowledging them in the description) makes the PR easier to land and easier to revert in pieces if something surfaces.

Dead guard after REQUIRED

This pattern repeats four times:

find_package(PkgConfig REQUIRED)
if(PkgConfig_FOUND)
    pkg_check_modules(...)
endif()

find_package(PkgConfig REQUIRED) already fails the configure if pkg-config isn't found, so the if(PkgConfig_FOUND) branch can never be false. Either drop the guard, or drop REQUIRED and keep the guard (with a friendlier error message). The current form is just noise.

No version constraints on the system packages

pkg_check_modules(zlib REQUIRED IMPORTED_TARGET zlib) accepts any installed zlib. The bundled snapshots have specific pins (e.g. the comment at line 996 says "bundled third_party/zlib 1.3.1"). A too-old distro lib could compile but lack APIs the project relies on, with confusing failure modes.

Suggest adding minimum versions matching what the vendored snapshots assume, e.g.:

pkg_check_modules(zlib         REQUIRED IMPORTED_TARGET zlib>=1.2.13)
pkg_check_modules(libmosquitto REQUIRED IMPORTED_TARGET libmosquitto>=2.0)
pkg_check_modules(rtmidi       REQUIRED IMPORTED_TARGET rtmidi>=5.0)
pkg_check_modules(libmspack    REQUIRED IMPORTED_TARGET libmspack>=0.10)

(Pick versions that match what the bundled copies actually provide — the maintainer can confirm.)

Status-message regression

The bundled-vs-system distinction got lost here:

message(STATUS "MIDI controller support enabled (RtMidi)")

Previously it said (bundled RtMidi). Worth restoring the distinction on both the MIDI and the mosquitto paths so build logs show which copy was actually picked:

if (USE_SYSTEM_RTMIDI)
    message(STATUS "MIDI controller support enabled (system RtMidi)")
else()
    message(STATUS "MIDI controller support enabled (bundled RtMidi)")
endif()

HAVE_MQTT_TLS assumption with system libmosquitto

if (USE_SYSTEM_LIBMOSQUITTO)
    if(MQTT_TLS)
        target_compile_definitions(AetherSDR PRIVATE HAVE_MQTT_TLS)
    endif()

The comment notes "System libmosquitto is conventionally built with TLS support" — true on Debian/Ubuntu/Fedora, but if a packager's mosquitto was built without TLS, HAVE_MQTT_TLS will be defined and AetherSDR code that calls mosquitto_tls_set() etc. will fail at link. Not a runtime safety issue, but the failure mode is confusing.

Consider probing for the symbol (check_symbol_exists(mosquitto_tls_set mosquitto.h ...)) or at least emitting a STATUS line warning packagers to verify their mosquitto has TLS when both flags are set.

Nits (low priority)

  • Indentation change inside the if(NOT MSVC) liquid-dsp block — fine, but unrelated to the system-libs work; flag in the commit message so reviewers don't have to diff-stare.
  • set(ENABLE_SPECBLEACH OFF CACHE BOOL "..." FORCE) on MSVC-no-clang-cl: this works, but you could also just leave the option() at the top and add if(MSVC AND NOT CLANG_CL) set(ENABLE_SPECBLEACH OFF ...) endif() for symmetry with the other option() declarations you hoisted.

None of these block the intent of the PR, which is well-motivated. The defaults-OFF + per-lib opt-in design is exactly right for distro packaging without disrupting the canonical build. Happy to look again once the CMake-minimum and ALSA pieces are either split out or justified.

73 and thanks for the contribution — Linux-distro-friendly builds matter for a project with this scope.


🤖 aethersdr-agent · cost: $5.6297 · model: claude-opus-4-7

dawkagaming and others added 3 commits May 25, 2026 22:31
PkgConfig::libmosquitto is only created when ENABLE_MQTT is on (the
pkg_check_modules() call lives inside that block).  Without an
ENABLE_MQTT guard on the top-level link line, the combination
`-DENABLE_MQTT=OFF -DUSE_SYSTEM_LIBMOSQUITTO=ON` configures cleanly
and then fails at link time with a missing-target error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876 ten9876 merged commit 10bc544 into aethersdr:main May 25, 2026
4 checks passed
@ten9876

ten9876 commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Claude here.

Merged at 10bc544. AetherSDR now supports opt-in USE_SYSTEM_ZLIB, USE_SYSTEM_MSPACK, USE_SYSTEM_LIBMOSQUITTO, and USE_SYSTEM_RTMIDI — exactly what distro packagers need for dynamic-linking-policy compliance. As a bonus, ALSA on Linux now goes through proper pkg-config discovery instead of the raw target_link_libraries(asound).

This is your fourth merged packaging-readiness PR (#3074, #3138, #3143, #3135), and reading them together they tell a coherent story: AetherSDR is meaningfully more packageable on Debian, Arch, NixOS, etc. than it was a week ago. Thank you for the persistent attention to that surface — distro-friendly software is rare and valuable, and you've moved a real measurable distance in that direction with minimal disturbance to existing bundled-build users.

Small follow-up on the same theme: I noticed that you closed #3139 (BUILD_TIMESTAMPS) in favour of the standard SOURCE_DATE_EPOCH approach we discussed. I just opened #3165 with that — a one-line CMake addition surfacing SOURCE_DATE_EPOCH honor at configure time, no source-tree changes. Credit to you in the PR body for surfacing the reproducibility concern in the first place.

73, Jeremy KK7GWY & Claude (AI dev partner)

G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
Hello,

as I said in the discussions, it would be nice to optionally enable use
of some system libraries (this would help is building AetherSDR for
Linux distributions packaging)

I tried to do this in this commit, I hope it is worth something.

Thanks,
Dawid SP9SKA

---------

Signed-off-by: dawkagaming <147207983+dawkagaming@users.noreply.github.com>
Co-authored-by: Jeremy Fielder <kk7gwy@aethersdr.com>
Co-authored-by: Claude Opus 4.7 (1M context) <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.

2 participants