Skip to content

Instantly share code, notes, and snippets.

@rodrisan
Last active June 28, 2026 19:10
Show Gist options
  • Select an option

  • Save rodrisan/3e62020ad5dc13fa24729aa4c47b17da to your computer and use it in GitHub Desktop.

Select an option

Save rodrisan/3e62020ad5dc13fa24729aa4c47b17da to your computer and use it in GitHub Desktop.
Build & install SDR++ with RTL-SDR Blog V4 support on macOS Mojave 10.14.6

SDR++ on macOS Mojave — with RTL-SDR Blog V4 support

A single, documented, re-runnable script that builds and installs SDR++ (with working RTL-SDR Blog V4 support) on macOS Mojave 10.14.6 running on Intel hardware — the kind of machine where Homebrew no longer works and the OS can't be upgraded.

It produces a self-contained /Applications/SDR++.app that runs entirely on Mojave, drives the RTL-SDR Blog V4 (R828D tuner), and depends only on MacPorts and the Xcode Command Line Tools.


Why this script exists

On Mojave you can't just run sudo port install SDRPlusPlus. The blocker is a single fact: Mojave's libc++ has no std::filesystem — that arrived in macOS 10.15 Catalina. That one gap cascades:

  • MacPorts' volk port now ships VOLK 3.1.2, which requires std::filesystem, so sudo port install volk fails at configure on 10.14.
  • The SDRPlusPlus MacPorts port depends on volk, so it fails at the same spot.

The script works around this by building VOLK 2.5.0 from source (the last release that falls back to Boost when std::filesystem is missing) and building SDR++ with its own -DOPT_OVERRIDE_STD_FILESYSTEM=ON flag. Along the way it also handles three other Mojave/MacPorts quirks — see How it works.


Requirements

Requirement Notes
Mac hardware Intel (x86_64). Not for Apple Silicon.
macOS 10.14.x Mojave (target). Harmless on newer; the workarounds just become unnecessary.
Xcode Command Line Tools xcode-select --install
MacPorts Install for your OS: https://www.macports.org/install.php
Homebrew Not required and not used. A stray Homebrew install won't break the build — MacPorts is forced to take precedence.
Disk / time A few GB of sources and build artifacts; expect a long compile on older CPUs (the script defaults to 2 parallel jobs for 4 GB RAM machines).

Quick start

Put build-sdrpp-mojave.sh wherever you want the sources to live, then:

chmod +x build-sdrpp-mojave.sh
./build-sdrpp-mojave.sh

The script stops on the first error and uses sudo only for the privileged steps (MacPorts installs, make install into /usr/local, copying into /Applications) — you'll be prompted for your password.

When it finishes, plug in the dongle and:

rtl_test                       # expect: "RTL-SDR Blog V4 Detected"
open /Applications/SDR++.app   # right-click -> Open if Gatekeeper blocks it

What the script does

It runs in five stages, each verified before moving on:

  1. MacPorts dependenciespkgconfig cmake fftw-3 fftw-3-single glfw zstd portaudio libusb boost python311 py311-mako. Note volk is deliberately absent (built from source in stage 2), and python311 is required because newer Python removed a module VOLK needs (see below).
  2. VOLK 2.5.0 from source, with the cpu_features submodule and a Boost fallback for the missing std::filesystem. Installed into /usr/local.
  3. RTL-SDR Blog V4 driver from source (the R828D fork) into /usr/local, with a linker fix so it finds MacPorts' libusb.
  4. SDR++ from source — a minimal, dependency-light module set (see below).
  5. Bundle & install — packages a self-contained SDR++.app and copies it to /Applications.

Library layout convention

Prefix Holds
/opt/local MacPorts packages (FFTW, GLFW, zstd, PortAudio, libusb, Boost)
/usr/local Hand-built libraries (VOLK 2.5.0, the RTL-SDR Blog V4 driver)

SDR++ is pointed at both, with /opt/local taking precedence so MacPorts libraries always win.

SDR++ modules that are built

Enabled: RTL-SDR, RTL-TCP, File source, the no-dependency network sources (Network, SpyServer, SDR++ Server, RFspace, Hermes), the Radio demodulator, Recorder, Frequency Manager, the PortAudio sinks, plus the no-dependency decoders (ATV, Meteor, etc.).

Disabled (to avoid extra dependencies): Airspy / Airspy HF+, HackRF, SDRplay, LimeSDR, BladeRF, PlutoSDR, SoapySDR, the Audio source/sink (rtaudio), the M17 decoder (codec2), and Discord Rich Presence. To re-enable any of them, install its library and flip the matching -DOPT_BUILD_* flag from OFF to ON in the SDR++ stage.


Configuration

Override defaults with environment variables:

Variable Default Purpose
DEV_DIR the script's own directory Where volk/, rtl-sdr-blog/, and SDRPlusPlus/ are cloned and built.
JOBS 2 Parallel compile jobs. Drop to 1 if a compiler process is Killed — that means you ran out of RAM.
JOBS=1 DEV_DIR="$HOME/sdr-build" ./build-sdrpp-mojave.sh

The script is re-runnable: existing clones are reused, build directories are wiped clean each run, and a previous /Applications/SDR++.app is removed before reinstalling.


Pinned / confirmed versions

Confirmed working on macOS 10.14.6 (Darwin 18, Intel x86_64):

Component Version
Toolchain Apple clang (Xcode Command Line Tools)
CMake MacPorts cmake (3.13+ required; 3.29.x used)
pkg-config 0.29.2 (MacPorts)
Python MacPorts python311 (3.11.x) — not 3.12
Boost MacPorts boost shim → boost176 (1.76)
VOLK 2.5.0 (pinned), built with the cpu_features submodule
glfw3 3.4.0
fftw3f 3.3.11
libzstd 1.5.6 (MacPorts)
portaudio / libusb MacPorts current
rtl-sdr-blog git master (R828D / V4 support)
SDR++ git master (built as C++17; reports ~v1.3.0)

The driver and SDR++ track upstream git master. If a future upstream change shifts something, the stage that breaks will point straight at the fix.


How it works

Four Mojave/MacPorts problems the script solves, each the result of a real debugging session:

  1. No std::filesystem (the core issue). VOLK 2.5.0 is the last release that detects the missing std::filesystem and falls back to Boost; SDR++ uses its OPT_OVERRIDE_STD_FILESYSTEM flag for the same reason.

  2. Python 3.12 removed distutils. VOLK generates kernel C code at build time with a Python + Mako generator, and its CMake checks for distutils, which was removed from the standard library in Python 3.12. The script uses MacPorts python311 (3.11 still ships distutils).

  3. VOLK CPU detection needs cpu_features. In VOLK 2.5.0 there is no legacy cpuid fallback — every CPU feature check returns "true" unless Google's cpu_features library is compiled in. Build it without and VOLK assumes the CPU has AVX-512 (which Haswell-era Macs do not), selects those kernels, and crashes with SIGILL ("illegal hardware instruction") the moment DSP starts. The script fetches the cpu_features submodule and builds with -DVOLK_CPU_FEATURES=ON.

  4. MacPorts linker path. The RTL-SDR CMake emits -lusb-1.0 but doesn't add MacPorts' /opt/local/lib to the linker search path, so the final link can't find libusb. The script adds it explicitly.

The bundle helper is also patched to chmod u+w each copied library before rewriting its install paths, because some dylibs ship read-only and install_name_tool can't otherwise modify the copies.


Verifying and tuning

# 1. Driver sees the dongle (nothing else using it):
rtl_test
#    -> "RTL-SDR Blog V4 Detected", no "PLL not locked" spam.

# 2. Launch (or run the inner binary directly if the .app is blocked):
/Applications/SDR++.app/Contents/MacOS/sdrpp

# 3. One-time performance tune, safe once CPU detection is correct:
/usr/local/bin/volk_profile

In SDR++: Source = RTL-SDR, sample rate 1.8–2.0 MS/s, AGC off, manual gain (~35 dB to start), and your PPM correction. Keep the sample rate modest on older dual-core CPUs.


Troubleshooting

All of these are already handled by the current script. They're documented here in case you modify it or hit a variant.

Symptom Cause Fix
Failed to configure volk from port install volk MacPorts ships VOLK 3.1.2, which needs std::filesystem (absent on Mojave) Build VOLK 2.5.0 from source (stage 2)
Python module 'distutils' ... not found Python 3.12 removed distutils Build VOLK against MacPorts python311
library not found for -lusb-1.0 rtl-sdr CMake omits /opt/local/lib Add /opt/local/lib to the linker flags
install_name_tool: ... Permission denied during bundling A copied dylib is read-only (e.g. Homebrew's mode-444 libs) chmod u+w the copy before rewriting it
cp: /Applications/SDR++.app/...: Permission denied A previous read-only .app blocks overwrite Remove the old /Applications/SDR++.app first
illegal hardware instruction (SIGILL) on Start VOLK built without cpu_features → wrong CPU detection → AVX-512 kernels on a CPU without AVX-512 Build VOLK with -DVOLK_CPU_FEATURES=ON
Compiler process Killed mid-build Out of RAM (4 GB machines) Re-run with JOBS=1

Uninstalling

# The app
rm -rf /Applications/SDR++.app

# Hand-built libraries (optional)
sudo rm -f /usr/local/lib/libvolk* /usr/local/lib/librtlsdr* \
           /usr/local/bin/volk_profile /usr/local/bin/rtl_*
sudo rm -rf /usr/local/include/volk /usr/local/include/rtl-sdr*

# MacPorts dependencies (optional — only if nothing else needs them)
# sudo port uninstall fftw-3 fftw-3-single glfw zstd portaudio libusb boost \
#     python311 py311-mako

# Build sources
rm -rf "$DEV_DIR"/{volk,rtl-sdr-blog,SDRPlusPlus}   # or wherever you set DEV_DIR

Distribution layout

.
├── README.md                 # this file
└── build-sdrpp-mojave.sh      # the build script

Notes & credits

#!/usr/bin/env bash
# =============================================================================
# build-sdrpp-mojave.sh
#
# Build & install SDR++ with RTL-SDR Blog V4 support on macOS Mojave 10.14.6
# (Intel), where Homebrew no longer works and the OS cannot be upgraded.
#
# -------------------------------------------------------------------------
# WHY THIS SCRIPT IS NOT JUST "port install SDRPlusPlus"
# -------------------------------------------------------------------------
# The one hard obstacle on Mojave: its libc++ has no std::filesystem (that
# arrived in macOS 10.15 Catalina). That single fact breaks the easy paths:
#
# * MacPorts' `volk` port now ships VOLK 3.1.2, which REQUIRES std::filesystem,
# so `sudo port install volk` fails at configure on 10.14 -- and because
# the `SDRPlusPlus` port depends on `volk`, `sudo port install SDRPlusPlus`
# fails at the exact same spot.
#
# The fix: build VOLK 2.5.0 from source. It is the last release that detects a
# missing std::filesystem and falls back to Boost. SDR++ itself is then built
# with its own -DOPT_OVERRIDE_STD_FILESYSTEM=ON flag (same problem, its switch).
#
# Two more Mojave/MacPorts quirks handled below:
# * Python: VOLK's code generator needs `distutils`, which was REMOVED from
# Python 3.12. We force MacPorts python311 (3.11 still ships distutils).
# * Linker: rtl-sdr's CMake emits `-lusb-1.0` but never adds MacPorts'
# /opt/local/lib to the linker search path. We add it explicitly.
#
# -------------------------------------------------------------------------
# LIBRARY LAYOUT CONVENTION
# -------------------------------------------------------------------------
# /opt/local -> MacPorts packages (fftw, glfw, zstd, portaudio, libusb, boost)
# /usr/local -> our hand-built libs (VOLK 2.5.0, rtl-sdr-blog V4 driver)
# SDR++ is pointed at BOTH via CMAKE_PREFIX_PATH and PKG_CONFIG_PATH.
#
# -------------------------------------------------------------------------
# PREREQUISITES (install these manually first)
# -------------------------------------------------------------------------
# * Xcode Command Line Tools : xcode-select --install
# * MacPorts for Mojave : https://www.macports.org/install.php
# This script assumes a MacPorts-only system. Homebrew is NOT required and is
# not used; every dependency comes from MacPorts (/opt/local) or is built by
# hand into /usr/local. If a stray Homebrew install exists, the PKG_CONFIG_PATH
# ordering below ensures MacPorts libraries are still the ones that get linked.
#
# -------------------------------------------------------------------------
# VERSIONS CONFIRMED WORKING (macOS 10.14.6 / Darwin 18 / Intel x86_64)
# -------------------------------------------------------------------------
# Toolchain ............ Apple clang (Xcode Command Line Tools)
# CMake ................ MacPorts cmake (3.13+ required; 3.29.x used here)
# MacPorts pkg-config .. 0.29.2
# Python ............... MacPorts python311 (3.11.x) <-- NOT 3.12: no distutils
# Boost ................ MacPorts `boost` shim -> boost176 (1.76)
# VOLK ................. 2.5.0 (pinned; last pre-std::filesystem release)
# built WITH cpu_features submodule (mandatory: see Stage 2)
# glfw3 ................ 3.4.0 (MacPorts)
# fftw3f ............... 3.3.11 (MacPorts)
# libzstd .............. 1.5.6 (MacPorts /opt/local)
# portaudio / libusb ... MacPorts current
# rtl-sdr-blog ......... git master (R828D / Blog V4 support)
# SDR++ ................ git master (built as C++17)
#
# -------------------------------------------------------------------------
# USAGE
# -------------------------------------------------------------------------
# chmod +x build-sdrpp-mojave.sh
# ./build-sdrpp-mojave.sh
#
# Re-runnable. Stops on first error. Privileged steps use `sudo` (you will be
# prompted for your password). Override defaults with env vars, e.g.:
# JOBS=1 DEV_DIR="$HOME/src" ./build-sdrpp-mojave.sh
# (Drop to JOBS=1 if a compiler process is "Killed" -- that means you ran out
# of RAM. This machine has 4 GB, so the default is intentionally conservative.)
# =============================================================================
set -euo pipefail
# ----------------------------- Configuration ---------------------------------
# Directory this script lives in -- sources are cloned/built alongside it.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEV_DIR="${DEV_DIR:-$SCRIPT_DIR}" # where sources are cloned/built
PREFIX_LOCAL="/usr/local" # our hand-built libs land here
PREFIX_PORTS="/opt/local" # MacPorts prefix
JOBS="${JOBS:-2}" # parallel compile jobs (4 GB RAM -> 2)
DEPLOY_TARGET="10.14" # macOS deployment target
PY="${PREFIX_PORTS}/bin/python3.11" # Python WITH distutils (NOT 3.12)
VOLK_TAG="v2.5.0" # last VOLK before std::filesystem
# Use MacPorts' CMake (installed in Stage 1). We do NOT fall back to a PATH cmake
# to avoid accidentally picking up a Homebrew install -- this script assumes a
# MacPorts-only system. Verified for existence right after Stage 1.
CMAKE="${PREFIX_PORTS}/bin/cmake"
# Make both library worlds visible, with MacPorts (/opt/local) taking PRECEDENCE.
# /usr/local is searched only for our hand-built libs (VOLK, librtlsdr). Ordering
# /opt/local first guarantees fftw/glfw/zstd/portaudio resolve to MacPorts even on
# a machine that still has stray Homebrew .pc files under /usr/local/lib/pkgconfig.
export PKG_CONFIG_PATH="${PREFIX_PORTS}/lib/pkgconfig:${PREFIX_LOCAL}/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
export LIBRARY_PATH="${PREFIX_PORTS}/lib:${LIBRARY_PATH:-}" # rtl-sdr linker bridge
# ------------------------------- Helpers -------------------------------------
log() { printf '\n\033[1;36m==> %s\033[0m\n' "$*"; }
warn() { printf '\033[1;33m[warn] %s\033[0m\n' "$*"; }
die() { printf '\033[1;31m[error] %s\033[0m\n' "$*" >&2; exit 1; }
# Clone a repo only if not already present (keeps the script re-runnable).
clone_once() { # clone_once <url> <dest_dir> [extra git args...]
local url="$1"; local dst="$2"; shift 2
if [ -d "$dst/.git" ]; then
log "Already cloned: $dst (reusing existing checkout)"
else
log "Cloning $url -> $dst"
git clone "$@" "$url" "$dst"
fi
}
# ----------------------------- Preflight checks ------------------------------
log "Preflight checks"
[ "$(uname -s)" = "Darwin" ] || die "This script is for macOS only."
OS_VER="$(sw_vers -productVersion 2>/dev/null || echo unknown)"
case "$OS_VER" in
10.14*) echo "macOS $OS_VER (Mojave) -- target platform, good." ;;
unknown) warn "Could not detect macOS version; continuing." ;;
*) warn "Detected macOS $OS_VER. This script was written for 10.14; the
std::filesystem workarounds are harmless on newer systems but
unnecessary. Continuing." ;;
esac
command -v port >/dev/null 2>&1 || die "MacPorts (port) not found. Install it: https://www.macports.org/install.php"
xcode-select -p >/dev/null 2>&1 || die "Xcode Command Line Tools not found. Run: xcode-select --install"
# CMake is provided by MacPorts and installed in Stage 1 below, then verified there.
echo "Python for VOLK codegen: $PY"
echo "Sources/builds under: $DEV_DIR Parallel jobs: $JOBS"
mkdir -p "$DEV_DIR"
# =============================================================================
# STAGE 1 -- MacPorts dependencies
# =============================================================================
# NOTE: `volk` is deliberately ABSENT (broken on Mojave; built from source in
# Stage 2). `boost` is the shim port that symlinks boost176 into /opt/local so
# CMake's FindBoost locates it with a plain BOOST_ROOT=/opt/local.
# `python311` + `py311-mako` give VOLK a Python that still has distutils, plus
# the Mako templating module its code generator imports.
log "STAGE 1/5: Installing MacPorts dependencies"
sudo port -N install \
pkgconfig \
cmake \
fftw-3 \
fftw-3-single \
glfw \
zstd \
portaudio \
libusb \
boost \
python311 \
py311-mako
[ -x "$PY" ] || die "Expected $PY after installing python311, but it's missing."
command -v "$CMAKE" >/dev/null 2>&1 || die "Expected MacPorts CMake at $CMAKE after install, but it's missing."
echo "Using CMake: $CMAKE ($("$CMAKE" --version | head -1 | awk '{print $3}'))"
# =============================================================================
# STAGE 2 -- VOLK 2.5.0 from source (the Mojave linchpin)
# =============================================================================
# Key flags:
# DISABLE_FIND_PACKAGE_FILESYSTEM=ON -> force the Boost fallback path
# deterministically (no std::filesystem).
# BOOST_ROOT=/opt/local -> VOLK defaults BOOST_ROOT to the install
# prefix (/usr/local); point it at MacPorts.
# VOLK_CPU_FEATURES=ON -> REQUIRED. In VOLK 2.5.0 there is no
# legacy cpuid fallback: every feature
# check returns 1 (true) unless Google's
# cpu_features is compiled in. Build it
# OFF and VOLK thinks the CPU has AVX-512
# etc., selects those kernels, and the
# program dies with SIGILL ("illegal
# hardware instruction") when DSP starts.
# cpu_features links statically into
# libvolk (no extra runtime dylib).
# PYTHON_EXECUTABLE=python3.11 -> avoid 3.12 (distutils removed).
log "STAGE 2/5: Building VOLK ${VOLK_TAG} from source"
clone_once https://github.com/gnuradio/volk.git "$DEV_DIR/volk" --depth 1 --branch "$VOLK_TAG"
# Fetch the cpu_features submodule (mandatory for correct x86 detection, above).
git -C "$DEV_DIR/volk" submodule update --init
[ -f "$DEV_DIR/volk/cpu_features/CMakeLists.txt" ] || die "cpu_features submodule missing; 'git submodule update --init' failed."
rm -rf "$DEV_DIR/volk/build"
mkdir -p "$DEV_DIR/volk/build"
cd "$DEV_DIR/volk/build"
"$CMAKE" .. \
-DCMAKE_INSTALL_PREFIX="$PREFIX_LOCAL" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_OSX_DEPLOYMENT_TARGET="$DEPLOY_TARGET" \
-DBOOST_ROOT="$PREFIX_PORTS" \
-DCMAKE_DISABLE_FIND_PACKAGE_FILESYSTEM=ON \
-DVOLK_CPU_FEATURES=ON \
-DENABLE_TESTING=OFF \
-DENABLE_MODTOOL=OFF \
-DPYTHON_EXECUTABLE="$PY"
make -j"$JOBS"
sudo make install
# Verify VOLK is discoverable before continuing.
pkg-config --exists volk || die "VOLK installed but pkg-config can't find volk.pc"
echo "VOLK $(pkg-config --modversion volk) installed at $PREFIX_LOCAL"
# =============================================================================
# STAGE 3 -- RTL-SDR Blog V4 driver from source
# =============================================================================
# The Blog V4 uses an R828D tuner and REQUIRES the rtlsdrblog driver fork;
# mainline/MacPorts librtlsdr will not drive it correctly. We install to
# /usr/local. The two linker-flag lines add /opt/local/lib so the final link
# finds MacPorts' libusb (rtl-sdr's CMake omits this path on macOS+MacPorts).
log "STAGE 3/5: Building RTL-SDR Blog V4 driver"
clone_once https://github.com/rtlsdrblog/rtl-sdr-blog "$DEV_DIR/rtl-sdr-blog"
rm -rf "$DEV_DIR/rtl-sdr-blog/build"
mkdir -p "$DEV_DIR/rtl-sdr-blog/build"
cd "$DEV_DIR/rtl-sdr-blog/build"
"$CMAKE" .. \
-DCMAKE_INSTALL_PREFIX="$PREFIX_LOCAL" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_SHARED_LINKER_FLAGS="-L${PREFIX_PORTS}/lib" \
-DCMAKE_EXE_LINKER_FLAGS="-L${PREFIX_PORTS}/lib"
make -j"$JOBS"
sudo make install
# =============================================================================
# STAGE 4 -- SDR++ from source
# =============================================================================
# Mandatory macOS flags:
# OPT_OVERRIDE_STD_FILESYSTEM=ON -> use bundled filesystem (Mojave has none)
# USE_BUNDLE_DEFAULTS=ON -> resource/module paths for the .app
# PORTAUDIO sinks ON, AUDIO_SINK OFF (rtaudio not installed)
# Minimal module set: keep RTL-SDR + RTL-TCP + file source + radio/recorder/
# freq-manager, plus the no-dependency network modules left on by default.
# Everything with an unmet external dependency is turned OFF:
# AUDIO_SOURCE/AUDIO_SINK (rtaudio), AIRSPY/AIRSPYHF, HACKRF, SDRPLAY,
# LIMESDR, BLADERF, PLUTOSDR, SOAPY, M17 (codec2), DISCORD (AppKit/ObjC bloat).
# To re-enable any module later, install its library and flip OFF -> ON.
log "STAGE 4/5: Building SDR++"
clone_once https://github.com/AlexandreRouma/SDRPlusPlus "$DEV_DIR/SDRPlusPlus"
rm -rf "$DEV_DIR/SDRPlusPlus/build"
mkdir -p "$DEV_DIR/SDRPlusPlus/build"
cd "$DEV_DIR/SDRPlusPlus/build"
"$CMAKE" .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_OSX_DEPLOYMENT_TARGET="$DEPLOY_TARGET" \
-DCMAKE_PREFIX_PATH="${PREFIX_PORTS};${PREFIX_LOCAL}" \
-DOPT_OVERRIDE_STD_FILESYSTEM=ON \
-DUSE_BUNDLE_DEFAULTS=ON \
-DOPT_BUILD_AUDIO_SINK=OFF \
-DOPT_BUILD_AUDIO_SOURCE=OFF \
-DOPT_BUILD_DISCORD_PRESENCE=OFF \
-DOPT_BUILD_PORTAUDIO_SINK=ON \
-DOPT_BUILD_NEW_PORTAUDIO_SINK=ON \
-DOPT_BUILD_RTL_SDR_SOURCE=ON \
-DOPT_BUILD_RTL_TCP_SOURCE=ON \
-DOPT_BUILD_FILE_SOURCE=ON \
-DOPT_BUILD_RADIO=ON \
-DOPT_BUILD_RECORDER=ON \
-DOPT_BUILD_FREQUENCY_MANAGER=ON \
-DOPT_BUILD_AIRSPY_SOURCE=OFF \
-DOPT_BUILD_AIRSPYHF_SOURCE=OFF \
-DOPT_BUILD_HACKRF_SOURCE=OFF \
-DOPT_BUILD_SDRPLAY_SOURCE=OFF \
-DOPT_BUILD_LIMESDR_SOURCE=OFF \
-DOPT_BUILD_BLADERF_SOURCE=OFF \
-DOPT_BUILD_PLUTOSDR_SOURCE=OFF \
-DOPT_BUILD_SOAPY_SOURCE=OFF \
-DOPT_BUILD_M17_DECODER=OFF
make -j"$JOBS"
# =============================================================================
# STAGE 5 -- Bundle into SDR++.app and install
# =============================================================================
# make_macos_bundle.sh gathers dependent dylibs with otool/install_name_tool
# (no dylibbundler needed) and ad-hoc signs the app. It prints "==NOT==
# Installing" for the modules we didn't build -- expected and harmless.
log "STAGE 5/5: Creating SDR++.app and installing to /Applications"
cd "$DEV_DIR/SDRPlusPlus"
# Patch the bundle helper: make each copied dylib writable before install_name_tool
# rewrites its paths. Some libraries ship read-only (notably Homebrew's mode-444
# dylibs, e.g. libzstd) and the copy inherits that, causing
# "install_name_tool: ... Permission denied". The added `chmod u+w` fixes it.
# Idempotent: re-running won't insert a second chmod.
perl -0777 -i -pe \
's/(\n\s*cp \$3 \$EXEC_DEST)(\n)/$1\n chmod u+w \$EXEC_DEST$2/ unless /chmod u\+w \$EXEC_DEST/;' \
macos/bundle_utils.sh
sh make_macos_bundle.sh ./build ./SDR++.app
# Remove any previous install first. An older/partial SDR++.app can contain
# read-only dylibs that would make `cp` fail with "Permission denied" when it
# tries to overwrite them in place.
if [ -e /Applications/SDR++.app ]; then
rm -rf /Applications/SDR++.app 2>/dev/null || sudo rm -rf /Applications/SDR++.app
fi
if cp -R ./SDR++.app /Applications/ 2>/dev/null; then
echo "Installed to /Applications/SDR++.app"
else
warn "Could not write /Applications directly; retrying with sudo."
sudo cp -R ./SDR++.app /Applications/
echo "Installed to /Applications/SDR++.app (via sudo)"
fi
# ------------------------------- Done ----------------------------------------
log "BUILD COMPLETE"
cat <<'EOF'
SDR++ is installed at /Applications/SDR++.app
Verify the V4 driver (plug in the dongle, nothing else using it):
rtl_test
-> expect "RTL-SDR Blog V4 Detected" and no "PLL not locked" spam.
Launch:
open /Applications/SDR++.app
If Gatekeeper blocks it (the app is ad-hoc signed), right-click -> Open once,
or run the inner binary directly:
/Applications/SDR++.app/Contents/MacOS/sdrpp
In SDR++: Source = RTL-SDR | Sample rate 1.8-2.0 MSPS | AGC off |
manual gain ~35 dB | set your PPM correction.
(Keep sample rate modest -- this is a dual-core 1.4 GHz CPU.)
Optional one-time performance tune (safe now that CPU detection is correct):
/usr/local/bin/volk_profile
Benchmarks each kernel on your actual CPU and records the fastest in
~/.volk/volk_config. Slow to run on this chip, but only needed once.
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment