From 6c6fc51ae9f628cedb3da5fa5e412f5c54b94615 Mon Sep 17 00:00:00 2001 From: Francesco Zanini Date: Fri, 17 Oct 2025 08:57:23 +0200 Subject: [PATCH 1/3] soapysdr-with-plugins: split linux-only plugins Allow clean-build of soapysdr-with-plugins on Darwin. --- pkgs/top-level/all-packages.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index f38323f85cb8..ffd5aad353fd 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -8593,8 +8593,10 @@ with pkgs; soapyplutosdr soapyremote soapyrtlsdr + ] + ++ (lib.optionals stdenv.hostPlatform.isLinux [ soapyuhd - ]; + ]); }; spandsp = callPackage ../development/libraries/spandsp { }; From 4e9fd819e20e59b4daf99ff21a87d4ce6e16590b Mon Sep 17 00:00:00 2001 From: Francesco Zanini Date: Tue, 11 Nov 2025 22:11:16 +0100 Subject: [PATCH 2/3] libbladeRF: fix build on darwin --- pkgs/by-name/li/libbladeRF/package.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/by-name/li/libbladeRF/package.nix b/pkgs/by-name/li/libbladeRF/package.nix index 4ae2c179ad30..c1c6af08ebb3 100644 --- a/pkgs/by-name/li/libbladeRF/package.nix +++ b/pkgs/by-name/li/libbladeRF/package.nix @@ -62,7 +62,7 @@ stdenv.mkDerivation rec { ]; env = lib.optionalAttrs stdenv.cc.isClang { - NIX_CFLAGS_COMPILE = "-Wno-error=unused-but-set-variable"; + NIX_CFLAGS_COMPILE = "-Wno-error=unused-but-set-variable -Wno-error=tautological-overlap-compare"; }; hardeningDisable = [ "fortify" ]; From fc62fcb838e4b9d49367096a0ad19ad06b60c3a2 Mon Sep 17 00:00:00 2001 From: Francesco Zanini Date: Fri, 17 Oct 2025 08:57:23 +0200 Subject: [PATCH 3/3] sdrpp: fix server mode, add options, simplify - rework patch to apply more cleanly and cover all entrypoints in one place. - add `audio_source` parameter, useful for making "server only" builds (avoid dependency on rtaudio in these builds) - fix build on Darwin by disabling soapyplutosdr, which in turns depends on libiio (Linux only) --- ...ement-of-resources-and-modules-paths.patch | 113 ++++++++++++++++++ pkgs/by-name/sd/sdrpp/package.nix | 79 +++++++----- pkgs/by-name/sd/sdrpp/runtime-prefix.patch | 60 ---------- 3 files changed, 163 insertions(+), 89 deletions(-) create mode 100644 pkgs/by-name/sd/sdrpp/0001-Allow-management-of-resources-and-modules-paths.patch delete mode 100644 pkgs/by-name/sd/sdrpp/runtime-prefix.patch diff --git a/pkgs/by-name/sd/sdrpp/0001-Allow-management-of-resources-and-modules-paths.patch b/pkgs/by-name/sd/sdrpp/0001-Allow-management-of-resources-and-modules-paths.patch new file mode 100644 index 000000000000..43a6b45442b8 --- /dev/null +++ b/pkgs/by-name/sd/sdrpp/0001-Allow-management-of-resources-and-modules-paths.patch @@ -0,0 +1,113 @@ +From 89189428a6857bc5607d8e28b9090c0d8bd0f8e3 Mon Sep 17 00:00:00 2001 +From: Francesco Zanini +Date: Mon, 6 Oct 2025 16:19:55 +0200 +Subject: [PATCH] Allow management of resources and modules paths + +SDR++ uses the config file to determine the location of modules and +resources to load. While this is mostly static in other distributions, +in Nix it changes very often. + +This commit adds some functionality to the config manager to replace +`@prefix@` in the values of the keys `modulesDirectory` and +`resourcesDirectory` to a dynamic path. On save, the change is reverted. + +The prefix path used is either the installation directory, or the +content of the `SDRPP_PREFIX` environment variable, if present. +--- + core/src/config.cpp | 31 ++++++++++++++++++++++++++++++- + core/src/config.h | 4 +++- + core/src/core.cpp | 15 ++------------- + 3 files changed, 35 insertions(+), 15 deletions(-) + +diff --git a/core/src/config.cpp b/core/src/config.cpp +index 6de1888fd803d4bbe04c7a4ed2187103dd8a5081..4cab471b24b985ca717afae4322618759ffd47b4 100644 +--- a/core/src/config.cpp ++++ b/core/src/config.cpp +@@ -41,12 +41,16 @@ void ConfigManager::load(json def, bool lock) { + conf = def; + save(false); + } ++ ++ transformPaths(conf, true); ++ + if (lock) { mtx.unlock(); } + } + + void ConfigManager::save(bool lock) { + if (lock) { mtx.lock(); } + std::ofstream file(path.c_str()); ++ transformPaths(conf, false); + file << conf.dump(4); + file.close(); + if (lock) { mtx.unlock(); } +@@ -98,4 +102,29 @@ void ConfigManager::autoSaveWorker() { + termCond.wait_for(lock, std::chrono::milliseconds(1000), [this]() { return termFlag; }); + } + } +-} +\ No newline at end of file ++} ++ ++void ConfigManager::transformPaths(json& conf, bool expand) { ++ const char* env_prefix = std::getenv("SDRPP_PREFIX"); ++ const std::string prefix = env_prefix ? env_prefix : INSTALL_PREFIX; ++ ++ std::vector directoryKeys = { ++ "modulesDirectory", ++ "resourcesDirectory" ++ }; ++ ++ const std::string from = expand ? "@prefix@" : prefix; ++ const std::string to = expand ? prefix : "@prefix@"; ++ ++ for (const auto& key : directoryKeys) { ++ if (conf.contains(key)) { ++ auto dir = conf[key].get(); ++ ++ size_t pos = dir.find(from); ++ if (pos != std::string::npos) { ++ dir.replace(pos, from.length(), to); ++ conf[key] = dir; ++ } ++ } ++ } ++} +diff --git a/core/src/config.h b/core/src/config.h +index fbbdeb4a54e06524a399e35afe8e187732bf851e..f9deef01e8d0850ab65a68ac33c9ed124486a1d5 100644 +--- a/core/src/config.h ++++ b/core/src/config.h +@@ -33,4 +33,6 @@ class ConfigManager { + std::mutex termMtx; + std::condition_variable termCond; + volatile bool termFlag = false; +-}; +\ No newline at end of file ++ ++ static void transformPaths(json& conf, bool expand); ++}; +diff --git a/core/src/core.cpp b/core/src/core.cpp +index 37358062ed957e562bf971fa121d885073f2827c..f1b5396cad3154546bb3a2322403b7f3618ad253 100644 +--- a/core/src/core.cpp ++++ b/core/src/core.cpp +@@ -267,19 +267,8 @@ int sdrpp_main(int argc, char* argv[]) { + defConfig["lockMenuOrder"] = false; + #endif + +-#if defined(_WIN32) +- defConfig["modulesDirectory"] = "./modules"; +- defConfig["resourcesDirectory"] = "./res"; +-#elif defined(IS_MACOS_BUNDLE) +- defConfig["modulesDirectory"] = "../Plugins"; +- defConfig["resourcesDirectory"] = "../Resources"; +-#elif defined(__ANDROID__) +- defConfig["modulesDirectory"] = root + "/modules"; +- defConfig["resourcesDirectory"] = root + "/res"; +-#else +- defConfig["modulesDirectory"] = INSTALL_PREFIX "/lib/sdrpp/plugins"; +- defConfig["resourcesDirectory"] = INSTALL_PREFIX "/share/sdrpp"; +-#endif ++ defConfig["modulesDirectory"] = "@prefix@/lib/sdrpp/plugins"; ++ defConfig["resourcesDirectory"] = "@prefix@/share/sdrpp"; + + // Load config + flog::info("Loading config"); diff --git a/pkgs/by-name/sd/sdrpp/package.nix b/pkgs/by-name/sd/sdrpp/package.nix index 19bba205f0b5..dd5fe6b7024f 100644 --- a/pkgs/by-name/sd/sdrpp/package.nix +++ b/pkgs/by-name/sd/sdrpp/package.nix @@ -10,31 +10,39 @@ fftwFloat, volk, zstd, + # Sources airspy_source ? true, airspy, airspyhf_source ? true, airspyhf, - bladerf_source ? true, + audio_source ? true, + bladerf_source ? stdenv.hostPlatform.isLinux, libbladeRF, file_source ? true, hackrf_source ? true, hackrf, + hermes_source ? true, limesdr_source ? true, limesuite, - perseus_source ? false, # needs libperseus-sdr, not yet available in nixpks + network_source ? true, + # needs libperseus-sdr, not yet available in nixpks + perseus_source ? false, plutosdr_source ? stdenv.hostPlatform.isLinux, libiio, libad9361, rfspace_source ? true, rtl_sdr_source ? true, rtl-sdr-osmocom, - libusb1, # osmocom better w/ rtlsdr v4 + libusb1, + # osmocom better w/ rtlsdr v4 rtl_tcp_source ? true, sdrplay_source ? false, sdrplay, + sdrpp_server_source ? true, soapy_source ? true, soapysdr-with-plugins, + spectran_http_source ? true, spyserver_source ? true, usrp_source ? false, uhd, @@ -48,57 +56,54 @@ portaudio, # Decoders + atv_decoder ? true, + dab_decoder ? false, falcon9_decoder ? false, + kg_sstv_decoder ? false, m17_decoder ? false, codec2, meteor_demodulator ? true, + pager_decoder ? true, radio ? true, - weather_sat_decoder ? false, # is missing some dsp/pll.h + vor_receiver ? false, + weather_sat_decoder ? false, # Misc discord_presence ? true, frequency_manager ? true, + iq_exporter ? true, recorder ? true, + rigctl_client ? true, rigctl_server ? true, scanner ? true, }: -stdenv.mkDerivation rec { +stdenv.mkDerivation (finalAttrs: { pname = "sdrpp"; - # SDR++ uses a rolling release model. - # Choose a git hash from head and use the date from that commit as - # version qualifier - git_rev = "4658a1ade6707dee6f2ae09ba9eb71097223ea93"; - git_hash = "sha256-UxYAcqOMPQYdUbL2636LpOGbCaxHjLiJhsH62s+0AZU="; - git_date = "2025-10-09"; - version_number = "1.2.1"; - - version = "${version_number}-unstable-" + git_date; + upstreamVersion = "1.2.1"; + version = "${finalAttrs.upstreamVersion}-unstable-2025-10-09"; src = fetchFromGitHub { owner = "AlexandreRouma"; repo = "SDRPlusPlus"; - rev = git_rev; - hash = git_hash; + rev = "4658a1ade6707dee6f2ae09ba9eb71097223ea93"; + hash = "sha256-UxYAcqOMPQYdUbL2636LpOGbCaxHjLiJhsH62s+0AZU="; }; patches = [ - ./runtime-prefix.patch + ./0001-Allow-management-of-resources-and-modules-paths.patch # CMake 4 dropped support of versions lower than 3.5, # versions lower than 3.10 are deprecated. ./cmake4.patch ]; postPatch = '' - substituteInPlace CMakeLists.txt \ - --replace "/usr/share" "share" \ - --replace "set(CMAKE_INSTALL_PREFIX" "#set(CMAKE_INSTALL_PREFIX" substituteInPlace decoder_modules/m17_decoder/src/m17dsp.h \ - --replace "codec2.h" "codec2/codec2.h" - # Since the __TIME_ and __DATE__ is canonicalized in the build, - # use our qualified version shown in the programs window title. - substituteInPlace core/src/version.h --replace-fail "${version_number}" "$version" + --replace-fail "codec2.h" "codec2/codec2.h" + + substituteInPlace core/src/version.h \ + --replace-fail "${finalAttrs.upstreamVersion}" "${finalAttrs.version}" ''; nativeBuildInputs = [ @@ -133,25 +138,30 @@ stdenv.mkDerivation rec { uhd boost ] - ++ lib.optional audio_sink rtaudio + ++ lib.optional (audio_source || audio_sink) rtaudio ++ lib.optional portaudio_sink portaudio - ++ lib.optional m17_decoder codec2; + ++ lib.optional (dab_decoder || m17_decoder) codec2; cmakeFlags = [ # Sources (lib.cmakeBool "OPT_BUILD_AIRSPYHF_SOURCE" airspyhf_source) (lib.cmakeBool "OPT_BUILD_AIRSPY_SOURCE" airspy_source) + (lib.cmakeBool "OPT_BUILD_AUDIO_SOURCE" audio_source) (lib.cmakeBool "OPT_BUILD_BLADERF_SOURCE" bladerf_source) (lib.cmakeBool "OPT_BUILD_FILE_SOURCE" file_source) (lib.cmakeBool "OPT_BUILD_HACKRF_SOURCE" hackrf_source) + (lib.cmakeBool "OPT_BUILD_HERMES_SOURCE" hermes_source) (lib.cmakeBool "OPT_BUILD_LIMESDR_SOURCE" limesdr_source) + (lib.cmakeBool "OPT_BUILD_NETWORK_SOURCE" network_source) (lib.cmakeBool "OPT_BUILD_PERSEUS_SOURCE" perseus_source) (lib.cmakeBool "OPT_BUILD_PLUTOSDR_SOURCE" plutosdr_source) (lib.cmakeBool "OPT_BUILD_RFSPACE_SOURCE" rfspace_source) (lib.cmakeBool "OPT_BUILD_RTL_SDR_SOURCE" rtl_sdr_source) (lib.cmakeBool "OPT_BUILD_RTL_TCP_SOURCE" rtl_tcp_source) (lib.cmakeBool "OPT_BUILD_SDRPLAY_SOURCE" sdrplay_source) + (lib.cmakeBool "OPT_BUILD_SDRPP_SERVER_SOURCE" sdrpp_server_source) (lib.cmakeBool "OPT_BUILD_SOAPY_SOURCE" soapy_source) + (lib.cmakeBool "OPT_BUILD_SPECTRAN_HTTP_SOURCE" spectran_http_source) (lib.cmakeBool "OPT_BUILD_SPYSERVER_SOURCE" spyserver_source) (lib.cmakeBool "OPT_BUILD_USRP_SOURCE" usrp_source) @@ -161,16 +171,23 @@ stdenv.mkDerivation rec { (lib.cmakeBool "OPT_BUILD_NEW_PORTAUDIO_SINK" portaudio_sink) # Decoders + (lib.cmakeBool "OPT_BUILD_ATV_DECODER" atv_decoder) + (lib.cmakeBool "OPT_BUILD_DAB_DECODER" dab_decoder) (lib.cmakeBool "OPT_BUILD_FALCON9_DECODER" falcon9_decoder) + (lib.cmakeBool "OPT_BUILD_KG_SSTV_DECODER" kg_sstv_decoder) (lib.cmakeBool "OPT_BUILD_M17_DECODER" m17_decoder) (lib.cmakeBool "OPT_BUILD_METEOR_DEMODULATOR" meteor_demodulator) + (lib.cmakeBool "OPT_BUILD_PAGER_DECODER" pager_decoder) (lib.cmakeBool "OPT_BUILD_RADIO" radio) + (lib.cmakeBool "OPT_BUILD_VOR_RECEIVER" vor_receiver) (lib.cmakeBool "OPT_BUILD_WEATHER_SAT_DECODER" weather_sat_decoder) # Misc (lib.cmakeBool "OPT_BUILD_DISCORD_PRESENCE" discord_presence) (lib.cmakeBool "OPT_BUILD_FREQUENCY_MANAGER" frequency_manager) + (lib.cmakeBool "OPT_BUILD_IQ_EXPORTER" iq_exporter) (lib.cmakeBool "OPT_BUILD_RECORDER" recorder) + (lib.cmakeBool "OPT_BUILD_RIGCTL_CLIENT" rigctl_client) (lib.cmakeBool "OPT_BUILD_RIGCTL_SERVER" rigctl_server) (lib.cmakeBool "OPT_BUILD_SCANNER" scanner) ]; @@ -183,8 +200,12 @@ stdenv.mkDerivation rec { description = "Cross-Platform SDR Software"; homepage = "https://github.com/AlexandreRouma/SDRPlusPlus"; license = licenses.gpl3Only; - platforms = platforms.unix; - maintainers = with maintainers; [ sikmir ]; + # The DAB decoder is broken upstream. See: https://github.com/AlexandreRouma/SDRPlusPlus/issues/1511 + broken = dab_decoder; + maintainers = with maintainers; [ + sikmir + zaninime + ]; mainProgram = "sdrpp"; }; -} +}) diff --git a/pkgs/by-name/sd/sdrpp/runtime-prefix.patch b/pkgs/by-name/sd/sdrpp/runtime-prefix.patch deleted file mode 100644 index 55ecd8ce3eee..000000000000 --- a/pkgs/by-name/sd/sdrpp/runtime-prefix.patch +++ /dev/null @@ -1,60 +0,0 @@ -From a80a739163d2013ec400223a68a387f4f9297b2a Mon Sep 17 00:00:00 2001 -From: Nikolay Korotkiy -Date: Fri, 29 Oct 2021 01:38:21 +0300 -Subject: [PATCH] Fix sdrpp breaking every time the package is rebuilt. - -On NixOS, the INSTALL_PREFIX changes on every rebuild to the package, but sdrpp -fills it in as part of the default config and then installs that config -to the users home folder. Fix this by not substituting @INSTALL_PREFIX@ in the -default config until runtime. ---- - core/src/core.cpp | 8 ++++++-- - core/src/gui/main_window.cpp | 6 ++++++ - 2 files changed, 12 insertions(+), 2 deletions(-) - -diff --git a/core/src/core.cpp b/core/src/core.cpp -index 9546e60..98d6065 100644 ---- a/core/src/core.cpp -+++ b/core/src/core.cpp -@@ -242,8 +242,8 @@ int sdrpp_main(int argc, char *argv[]) { - defConfig["modulesDirectory"] = "./modules"; - defConfig["resourcesDirectory"] = "./res"; - #else -- defConfig["modulesDirectory"] = INSTALL_PREFIX "/lib/sdrpp/plugins"; -- defConfig["resourcesDirectory"] = INSTALL_PREFIX "/share/sdrpp"; -+ defConfig["modulesDirectory"] = "@prefix@/lib/sdrpp/plugins"; -+ defConfig["resourcesDirectory"] = "@prefix@/share/sdrpp"; - #endif - - // Load config -@@ -290,6 +290,10 @@ int sdrpp_main(int argc, char *argv[]) { - int winHeight = core::configManager.conf["windowSize"]["h"]; - maximized = core::configManager.conf["maximized"]; - std::string resDir = core::configManager.conf["resourcesDirectory"]; -+ { -+ std::size_t pos = resDir.find("@prefix@"); -+ if (pos != std::string::npos) resDir.replace(pos, 8, INSTALL_PREFIX); -+ } - json bandColors = core::configManager.conf["bandColors"]; - core::configManager.release(); - -diff --git a/core/src/gui/main_window.cpp b/core/src/gui/main_window.cpp -index 954dbd6..52f0eed 100644 ---- a/core/src/gui/main_window.cpp -+++ b/core/src/gui/main_window.cpp -@@ -44,6 +44,12 @@ void MainWindow::init() { - json menuElements = core::configManager.conf["menuElements"]; - std::string modulesDir = core::configManager.conf["modulesDirectory"]; - std::string resourcesDir = core::configManager.conf["resourcesDirectory"]; -+ { -+ std::size_t pos = modulesDir.find("@prefix@"); -+ if (pos != std::string::npos) modulesDir.replace(pos, 8, INSTALL_PREFIX); -+ pos = resourcesDir.find("@prefix@"); -+ if (pos != std::string::npos) resourcesDir.replace(pos, 8, INSTALL_PREFIX); -+ } - core::configManager.release(); - - // Load menu elements --- -2.33.0 -