From 4208bcf1f417da17b287ecf2360524f3189438b7 Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 11:52:55 +0000 Subject: [PATCH 01/12] Fix AirspyHF instant replay. --- plugins/samplesource/airspyhf/airspyhfinput.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/samplesource/airspyhf/airspyhfinput.cpp b/plugins/samplesource/airspyhf/airspyhfinput.cpp index f1a81ab94..715b78e58 100644 --- a/plugins/samplesource/airspyhf/airspyhfinput.cpp +++ b/plugins/samplesource/airspyhf/airspyhfinput.cpp @@ -292,7 +292,8 @@ int AirspyHFInput::getSampleRate() const uint32_t AirspyHFInput::getSampleRateFromIndex(quint32 devSampleRateIndex) const { - int index; + int index = (int) devSampleRateIndex; + if (devSampleRateIndex >= m_sampleRates.size()) { index = m_sampleRates.size() - 1; } From e75900b6668153ffa467487d82f023a2e64063e3 Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 11:53:36 +0000 Subject: [PATCH 02/12] Fix sdrplay shared library name on Mac arm64, as incorrect in 3.12 API release. --- plugins/samplesource/sdrplayv3/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/samplesource/sdrplayv3/CMakeLists.txt b/plugins/samplesource/sdrplayv3/CMakeLists.txt index 15a095921..9a4d9530d 100644 --- a/plugins/samplesource/sdrplayv3/CMakeLists.txt +++ b/plugins/samplesource/sdrplayv3/CMakeLists.txt @@ -56,6 +56,13 @@ target_link_libraries(${TARGET_NAME} ${SDRPLAY_LIBRARIES} ) +# Library name is wrong in 3.12 release +if (APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL arm64)) + add_custom_command(TARGET ${TARGET_NAME} + POST_BUILD COMMAND + ${CMAKE_INSTALL_NAME_TOOL} -change libsdrplay_api_arm64.so.3.12 libsdrplay_api.so.3.12 $) +endif() + install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER}) # Install debug symbols From cdb78c903f357aea91bd3a0bc8fd11861bf4881f Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 11:54:14 +0000 Subject: [PATCH 03/12] SDRPlay V3 API - don't call close unless open was a success, as will crash on Mac, --- .../sdrplayv3/sdrplayv3plugin.cpp | 33 +++++++++++++------ .../samplesource/sdrplayv3/sdrplayv3plugin.h | 1 + 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/plugins/samplesource/sdrplayv3/sdrplayv3plugin.cpp b/plugins/samplesource/sdrplayv3/sdrplayv3plugin.cpp index bed1a3155..9c463b311 100644 --- a/plugins/samplesource/sdrplayv3/sdrplayv3plugin.cpp +++ b/plugins/samplesource/sdrplayv3/sdrplayv3plugin.cpp @@ -43,25 +43,38 @@ static constexpr const char* const m_hardwareID = "SDRplayV3"; static constexpr const char* const m_deviceTypeID = SDRPLAYV3_DEVICE_TYPE_ID; SDRPlayV3Plugin::SDRPlayV3Plugin(QObject* parent) : - QObject(parent) + QObject(parent), + m_opened(false) { sdrplay_api_ErrT err; float ver = 0.0f; - qDebug() << "SDRPlayV3Plugin: calling sdrplay_api_Open()"; - if ((err = sdrplay_api_Open()) != sdrplay_api_Success) + if ((err = sdrplay_api_Open()) == sdrplay_api_Success) + { + m_opened = true; + + if ((err = sdrplay_api_ApiVersion(&ver)) == sdrplay_api_Success) + { + if (ver != SDRPLAY_API_VERSION) { + qCritical() << "SDRPlayV3Plugin::SDRPlayV3Plugin: SDRPlay API versions do not match " << ver << " " << SDRPLAY_API_VERSION; + } + } + else + { + qCritical() << "SDRPlayV3Plugin::SDRPlayV3Plugin: failed to get SDRPlay API version."; + } + } + else + { qCritical() << "SDRPlayV3Plugin::SDRPlayV3Plugin: sdrplay_api_Open() was unsuccessful. " << sdrplay_api_GetErrorString(err); - - if ((err = sdrplay_api_ApiVersion(&ver)) != sdrplay_api_Success) - qCritical() << "SDRPlayV3Plugin::SDRPlayV3Plugin: failed to get SDRPlay API version."; - - if (ver != SDRPLAY_API_VERSION) - qCritical() << "SDRPlayV3Plugin::SDRPlayV3Plugin: SDRPlay API versions do not match " << ver << " " << SDRPLAY_API_VERSION; + } } SDRPlayV3Plugin::~SDRPlayV3Plugin() { - sdrplay_api_Close(); + if (m_opened) { + sdrplay_api_Close(); + } } const PluginDescriptor& SDRPlayV3Plugin::getPluginDescriptor() const diff --git a/plugins/samplesource/sdrplayv3/sdrplayv3plugin.h b/plugins/samplesource/sdrplayv3/sdrplayv3plugin.h index d747b221c..05c504f68 100644 --- a/plugins/samplesource/sdrplayv3/sdrplayv3plugin.h +++ b/plugins/samplesource/sdrplayv3/sdrplayv3plugin.h @@ -52,6 +52,7 @@ public: virtual DeviceWebAPIAdapter* createDeviceWebAPIAdapter() const; private: + bool m_opened; // Whether sdrplay_api_Open was successful static const PluginDescriptor m_pluginDescriptor; }; From c7196fad6b57f5deda4ec360ded55d010fc617fa Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 11:54:53 +0000 Subject: [PATCH 04/12] Delete python stuff before installing any packages. --- .github/workflows/sdrangel.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sdrangel.yml b/.github/workflows/sdrangel.yml index f08f67dc3..9e16679b6 100644 --- a/.github/workflows/sdrangel.yml +++ b/.github/workflows/sdrangel.yml @@ -108,8 +108,6 @@ jobs: fetch-depth: 0 - name: Update brew run: brew update - - name: Install brew packages - run: brew install nasm boost hidapi libusb fftw ffmpeg faad2 zlib airspy airspyhf hackrf rtl-sdr libbladerf soapysdr qt - name: Install brew uhd package run: | rm -f /usr/local/bin/2to3* @@ -122,6 +120,8 @@ jobs: run: | rm -f /usr/local/bin/2to3 brew install opencv + - name: Install brew packages + run: brew install nasm boost hidapi libusb fftw ffmpeg faad2 zlib airspy airspyhf hackrf rtl-sdr libbladerf soapysdr qt - name: Configure SDRangel run: | mkdir build && cd build From c0bc9f3d5f4b23c82eec64e9cf78671f404cae59 Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 11:55:17 +0000 Subject: [PATCH 05/12] Add Docker install instructions. --- swagger/docker/readme.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/swagger/docker/readme.md b/swagger/docker/readme.md index 4dbd2da6a..246d18dc6 100644 --- a/swagger/docker/readme.md +++ b/swagger/docker/readme.md @@ -8,6 +8,12 @@ The `compose` folder contains files to build the Docker compose stack comprising The SDRangel source tree is mounted in both containers as writable so the generated code can be written directly from the code generator or the Swagger files served by the http server. +

Install Docker on Ubuntu

+ +sudo apt install docker.io docker-buildx docker-compose +sudo usermod -aG docker $USER +* reboot * +

Server

Use `build.sh` to build the image. It takes the following arguments: From ff8bbe5cd38d6be054dbef09c998bfdbab8cab09 Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 11:56:07 +0000 Subject: [PATCH 06/12] Remove html from labels --- plugins/feature/map/czml.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/feature/map/czml.cpp b/plugins/feature/map/czml.cpp index 0be708a02..1ba0f1bb0 100644 --- a/plugins/feature/map/czml.cpp +++ b/plugins/feature/map/czml.cpp @@ -510,8 +510,10 @@ QJsonObject CZML::update(ObjectMapItem *mapItem, bool isTarget, bool isSelected) QJsonObject labelDistanceDisplayCondition { {"distanceDisplayCondition", labelDisplayDistance} }; + QString labelText = mapItem->m_label; + labelText.replace("
", "\n"); QJsonObject label { - {"text", mapItem->m_label}, + {"text", labelText}, {"show", m_settings->m_displayNames && mapItem->m_itemSettings->m_enabled && mapItem->m_itemSettings->m_display3DLabel}, {"scale", mapItem->m_itemSettings->m_3DLabelScale}, {"pixelOffset", labelPixelOffset}, From 4aaa5edb091de53f70b7e70fc28be8146373e25c Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 11:56:28 +0000 Subject: [PATCH 07/12] Add dialog positioner for audio select dialog --- plugins/feature/simpleptt/simplepttgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/feature/simpleptt/simplepttgui.cpp b/plugins/feature/simpleptt/simplepttgui.cpp index e29ffa137..51569ac49 100644 --- a/plugins/feature/simpleptt/simplepttgui.cpp +++ b/plugins/feature/simpleptt/simplepttgui.cpp @@ -719,6 +719,7 @@ void SimplePTTGUI::audioSelect(const QPoint& p) qDebug("SimplePTTGUI::audioSelect"); AudioSelectDialog audioSelect(DSPEngine::instance()->getAudioDeviceManager(), m_settings.m_audioDeviceName, true); audioSelect.move(p); + new DialogPositioner(&audioSelect, false); audioSelect.exec(); if (audioSelect.m_selected) From 6880dfba9dfa1ec52b12171c816edf75a4fcdc81 Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 12:01:54 +0000 Subject: [PATCH 08/12] Add comment how to view filter freq response --- sdrbase/dsp/firfilter.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdrbase/dsp/firfilter.h b/sdrbase/dsp/firfilter.h index 867ca9ee3..77cbee39c 100644 --- a/sdrbase/dsp/firfilter.h +++ b/sdrbase/dsp/firfilter.h @@ -60,6 +60,9 @@ public: } // Print taps as a Matlab vector + // To view: + // h=fvtool(filter); + // h.Fs=... void printTaps(const char *name) { printf("%s = [", name); From c9db48c7544cba130a028459621657a2522abd46 Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 12:03:37 +0000 Subject: [PATCH 09/12] Use sourceforge for Boost as faster to download. Use Boost 1.78.0 on Intel Mac, as 1.83 causes UHD to fail to load at runtime. Fix Lame link on Mac arm64 --- external/CMakeLists.txt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 77a3b482b..78351eeec 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -31,6 +31,15 @@ set(SOAPYSDR_REMOTE_TAG "soapy-remote-0.5.1") set(AIRSPY_TAG "37c768ce9997b32e7328eb48972a7fda0a1f8554") set(HACKRF_TAG "v2022.09.1") set(LIBXML2_TAG "v2.10.4") +set(UHD_TAG "v4.5.0.0") +if (APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64)) + # UHD fails to load with 1.80+ + set(BOOST_TAG "1.78.0") + set(BOOST_TAG2 "1_78_0") +else() + set(BOOST_TAG "1.83.0") + set(BOOST_TAG2 "1_83_0") +endif() # For some external project macros include(ExternalProject) @@ -340,7 +349,7 @@ endif (NOT FFTW3F_FOUND AND NOT USE_PRECOMPILED_LIBS) # So instead, we use FetchContent and build Boost at CMake configure time include(FetchContent) FetchContent_Declare(boost - URL https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.gz + URL "https://sourceforge.net/projects/boost/files/boost/${BOOST_TAG}/boost_${BOOST_TAG2}.tar.gz/download" ) find_package(Boost QUIET) @@ -483,7 +492,11 @@ if (NOT FFMPEG_FOUND AND NOT USE_PRECOMPILED_LIBS) # ffmpeg doesn't try to use pkg-config for lame, as it doesn't include a .pc file #set(LAME_PKG_CONFIG_DIR "${install_dir}/lib/pkgconfig") set(LAME_EXTRA_CFLAGS "-I${install_dir}/include") - set(LAME_EXTRA_LDFLAGS "-L${install_dir}/lib") + if (APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL arm64)) + set(LAME_EXTRA_LDFLAGS "-L${install_dir}/lib -Wl,-ld_classic") + else() + set(LAME_EXTRA_LDFLAGS "-L${install_dir}/lib") + endif() set_global_cache(LAME_FOUND ON) set(LAME_EXTERNAL ON CACHE INTERNAL "") if (APPLE) @@ -1491,7 +1504,7 @@ if (WIN32 OR APPLE) endif () ExternalProject_Add(uhd GIT_REPOSITORY https://github.com/EttusResearch/uhd.git - GIT_TAG v4.5.0.0 + GIT_TAG ${UHD_TAG} DEPENDS ${LIBUSB_DEPENDS} ${Boost_DEPENDS} PREFIX "${EXTERNAL_BUILD_LIBRARIES}/uhd" SOURCE_SUBDIR "host" From e64e0a1cd45c5f20f30eca4cc1bfeb42691365d7 Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 12:04:57 +0000 Subject: [PATCH 10/12] Display FIFO size on overflow. --- sdrbase/dsp/datafifo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdrbase/dsp/datafifo.cpp b/sdrbase/dsp/datafifo.cpp index 898c2d0d9..7995ae133 100644 --- a/sdrbase/dsp/datafifo.cpp +++ b/sdrbase/dsp/datafifo.cpp @@ -116,14 +116,14 @@ unsigned int DataFifo::write(const quint8* data, unsigned int count, DataType da { m_suppressed = 0; m_msgRateTimer.start(); - qCritical("DataFifo::write: overflow - dropping %u samples", count - total); + qCritical("DataFifo::write: overflow - dropping %u samples (size=%u)", count - total, m_size); } else { if (m_msgRateTimer.elapsed() > 2500) { qCritical("DataFifo::write: %u messages dropped", m_suppressed); - qCritical("DataFifo::write: overflow - dropping %u samples", count - total); + qCritical("DataFifo::write: overflow - dropping %u samples (size=%u)", count - total, m_size); m_suppressed = -1; } else From 3ca14c2bb10dd2eaef00297a193efd183a854c71 Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 1 Dec 2023 12:47:50 +0000 Subject: [PATCH 11/12] Stop scanning when Tune menu selected. --- plugins/channelrx/freqscanner/freqscanner.cpp | 10 ++++---- plugins/channelrx/freqscanner/freqscanner.h | 2 +- .../channelrx/freqscanner/freqscannergui.cpp | 23 +++++++++++++++---- .../freqscanner/freqscannersettings.cpp | 9 ++++++++ .../freqscanner/freqscannersettings.h | 1 + 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/plugins/channelrx/freqscanner/freqscanner.cpp b/plugins/channelrx/freqscanner/freqscanner.cpp index 54cf255f2..274defd91 100644 --- a/plugins/channelrx/freqscanner/freqscanner.cpp +++ b/plugins/channelrx/freqscanner/freqscanner.cpp @@ -249,7 +249,7 @@ bool FreqScanner::handleMessage(const Message& cmd) } else if (MsgStartScan::match(cmd)) { - muteAll(); + muteAll(m_settings); startScan(); return true; @@ -657,14 +657,14 @@ void FreqScanner::setCenterFrequency(qint64 frequency) } // Mute all channels -void FreqScanner::muteAll() +void FreqScanner::muteAll(const FreqScannerSettings& settings) { QStringList channels; - channels.append(m_settings.m_channel); - for (int i = 0; i < m_settings.m_frequencySettings.size(); i++) + channels.append(settings.m_channel); + for (int i = 0; i < settings.m_frequencySettings.size(); i++) { - QString channel = m_settings.m_frequencySettings[i].m_channel; + QString channel = settings.m_frequencySettings[i].m_channel; if (!channel.isEmpty() && !channels.contains(channel)) { channels.append(channel); } diff --git a/plugins/channelrx/freqscanner/freqscanner.h b/plugins/channelrx/freqscanner/freqscanner.h index 7613e704d..9bfa0d0fb 100644 --- a/plugins/channelrx/freqscanner/freqscanner.h +++ b/plugins/channelrx/freqscanner/freqscanner.h @@ -350,6 +350,7 @@ public: uint32_t getNumberOfDeviceStreams() const; void calcScannerSampleRate(int channelBW, int basebandSampleRate, int& scannerSampleRate, int& fftSize, int& binsPerChannel); + static void muteAll(const FreqScannerSettings& settings); static const char * const m_channelIdURI; static const char * const m_channelId; @@ -408,7 +409,6 @@ private: void processScanResults(const QDateTime& fftStartTime, const QList& results); void setDeviceCenterFrequency(qint64 frequency); void applyChannelSetting(const QString& channel); - void muteAll(); static QList *createFrequencyList(const FreqScannerSettings& settings); diff --git a/plugins/channelrx/freqscanner/freqscannergui.cpp b/plugins/channelrx/freqscanner/freqscannergui.cpp index a08247a79..7454e3ad6 100644 --- a/plugins/channelrx/freqscanner/freqscannergui.cpp +++ b/plugins/channelrx/freqscanner/freqscannergui.cpp @@ -932,18 +932,29 @@ void FreqScannerGUI::table_customContextMenuRequested(QPoint pos) // Tune to frequency + qint64 frequency = ui->table->item(row, COL_FREQUENCY)->text().toLongLong(); + FreqScannerSettings::FrequencySettings *frequencySettings = m_settings.getFrequencySettings(frequency); + QString channel = m_settings.getChannel(frequencySettings); const QRegExp re("R([0-9]+):([0-9]+)"); - if (re.indexIn(m_settings.m_channel) >= 0) + if (re.indexIn(channel) >= 0) { int scanDeviceSetIndex = re.capturedTexts()[1].toInt(); int scanChannelIndex = re.capturedTexts()[2].toInt(); - qDebug() << "scanDeviceSetIndex" << scanDeviceSetIndex << "scanChannelIndex" << scanChannelIndex; - qint64 frequency = ui->table->item(row, COL_FREQUENCY)->text().toLongLong(); + ButtonSwitch *startStop = ui->startStop; QAction* findChannelMapAction = new QAction(QString("Tune R%1:%2 to %3").arg(scanDeviceSetIndex).arg(scanChannelIndex).arg(frequency), tableContextMenu); - connect(findChannelMapAction, &QAction::triggered, this, [this, scanDeviceSetIndex, scanChannelIndex, frequency]()->void { + connect(findChannelMapAction, &QAction::triggered, this, [this, scanDeviceSetIndex, scanChannelIndex, frequency, startStop]()->void { + // Stop scanning + if (startStop->isChecked()) { + startStop->click(); + } + + // Mute all channels + m_freqScanner->muteAll(m_settings); + + // Tune to frequency if ((frequency - m_settings.m_channelBandwidth / 2 < m_deviceCenterFrequency - m_basebandSampleRate / 2) || (frequency + m_settings.m_channelBandwidth / 2 >= m_deviceCenterFrequency + m_basebandSampleRate / 2)) { @@ -958,7 +969,6 @@ void FreqScannerGUI::table_customContextMenuRequested(QPoint pos) if (!ChannelWebAPIUtils::setCenterFrequency(getDeviceSetIndex(), centerFrequency)) { qWarning() << "Scanner failed to set frequency" << centerFrequency; } - ChannelWebAPIUtils::setFrequencyOffset(scanDeviceSetIndex, scanChannelIndex, offset); } else @@ -967,6 +977,9 @@ void FreqScannerGUI::table_customContextMenuRequested(QPoint pos) ChannelWebAPIUtils::setFrequencyOffset(scanDeviceSetIndex, scanChannelIndex, offset); } + // Unmute channel + ChannelWebAPIUtils::setAudioMute(scanDeviceSetIndex, scanChannelIndex, false); + }); tableContextMenu->addAction(findChannelMapAction); } diff --git a/plugins/channelrx/freqscanner/freqscannersettings.cpp b/plugins/channelrx/freqscanner/freqscannersettings.cpp index edc83c9ce..e9751eec8 100644 --- a/plugins/channelrx/freqscanner/freqscannersettings.cpp +++ b/plugins/channelrx/freqscanner/freqscannersettings.cpp @@ -420,6 +420,15 @@ QDataStream& operator>>(QDataStream& in, FreqScannerSettings::FrequencySettings& return in; } +QString FreqScannerSettings::getChannel(FreqScannerSettings::FrequencySettings *frequencySettings) const +{ + QString channel = m_channel; + if (!frequencySettings->m_channel.isEmpty()) { + channel = frequencySettings->m_channel; + } + return channel; +} + Real FreqScannerSettings::getThreshold(FreqScannerSettings::FrequencySettings *frequencySettings) const { Real threshold = m_threshold; diff --git a/plugins/channelrx/freqscanner/freqscannersettings.h b/plugins/channelrx/freqscanner/freqscannersettings.h index e07ba7b49..8c073e119 100644 --- a/plugins/channelrx/freqscanner/freqscannersettings.h +++ b/plugins/channelrx/freqscanner/freqscannersettings.h @@ -103,6 +103,7 @@ struct FreqScannerSettings bool deserialize(const QByteArray& data); void applySettings(const QStringList& settingsKeys, const FreqScannerSettings& settings); QString getDebugString(const QStringList& settingsKeys, bool force = false) const; + QString getChannel(FreqScannerSettings::FrequencySettings *frequencySettings) const; Real getThreshold(FreqScannerSettings::FrequencySettings *frequencySettings) const; int getChannelBandwidth(FreqScannerSettings::FrequencySettings *frequencySettings) const; FreqScannerSettings::FrequencySettings *getFrequencySettings(qint64 frequency); From c48c8cdf4a000e918f9cdd87b48488dfac44ad48 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Fri, 1 Dec 2023 18:17:05 +0000 Subject: [PATCH 12/12] Use full path to library --- plugins/samplesource/sdrplayv3/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/samplesource/sdrplayv3/CMakeLists.txt b/plugins/samplesource/sdrplayv3/CMakeLists.txt index 9a4d9530d..94d05e0a1 100644 --- a/plugins/samplesource/sdrplayv3/CMakeLists.txt +++ b/plugins/samplesource/sdrplayv3/CMakeLists.txt @@ -60,7 +60,7 @@ target_link_libraries(${TARGET_NAME} if (APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL arm64)) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND - ${CMAKE_INSTALL_NAME_TOOL} -change libsdrplay_api_arm64.so.3.12 libsdrplay_api.so.3.12 $) + ${CMAKE_INSTALL_NAME_TOOL} -change libsdrplay_api_arm64.so.3.12 /Library/SDRplayAPI/3.12.0/lib/libsdrplay_api.so.3.12.0 $) endif() install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})