From f39a96022a6cefd2644fc40c4351d89aef68d3d5 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Sun, 8 Nov 2015 16:45:06 -0500 Subject: [PATCH] Add OSX SoapySDR module bundling support. --- CMakeLists.txt | 59 ++++++++++++++++++++++++++++----------- src/CubicSDR.cpp | 13 +++++++++ src/CubicSDR.h | 14 +++++++++- src/sdr/SDREnumerator.cpp | 51 ++++++++++++++++++++------------- 4 files changed, 100 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 282b890..d8dd22a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.8) SET(CUBICSDR_VERSION_MAJOR "0") SET(CUBICSDR_VERSION_MINOR "1") -SET(CUBICSDR_VERSION_PATCH "15") +SET(CUBICSDR_VERSION_PATCH "16") SET(CUBICSDR_VERSION_REL "alpha") SET(CUBICSDR_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}-${CUBICSDR_VERSION_REL}") @@ -427,7 +427,11 @@ IF (APPLE AND BUNDLE_APP) set(BUNDLE_SOAPY_MODS OFF CACHE BOOL "Bundle local SoapySDR modules") - + IF (BUNDLE_SOAPY_MODS) + ADD_DEFINITIONS( + -DBUNDLE_SOAPY_MODS=1 + ) + ENDIF() ADD_DEFINITIONS( -std=c++0x @@ -470,7 +474,7 @@ IF (APPLE AND BUNDLE_APP) ${PROJECT_SOURCE_DIR}/icon/CubicSDR.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources - ) + ) target_link_libraries(CubicSDR ${LIQUID_LIB} ${FFTW_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${OTHER_LIBRARIES}) SET_TARGET_PROPERTIES(CubicSDR PROPERTIES MACOSX_BUNDLE TRUE) @@ -482,30 +486,51 @@ IF (APPLE AND BUNDLE_APP) # MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}" MACOSX_BUNDLE_GUI_IDENTIFIER "com.cubicproductions.cubicsdr" MACOSX_BUNDLE_ICON_FILE CubicSDR.icns - ) + ) SET(APPS "${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME}/CubicSDR.app") # SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) # SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) + + IF (BUNDLE_SOAPY_MODS) + + message(STATUS "SOAPY_ROOT: ${SOAPY_SDR_ROOT}") + file(GLOB SOAPY_MODS ${SOAPY_SDR_ROOT}/lib/SoapySDR/modules/*.so) + + FOREACH(SOAPY_MOD_FILE ${SOAPY_MODS}) + INSTALL( FILES "${SOAPY_MOD_FILE}" + DESTINATION "${APPS}/Contents/MacOS/modules" + COMPONENT Runtime + ) + ENDFOREACH() + + ENDIF(BUNDLE_SOAPY_MODS) INSTALL(CODE " - SET(BU_COPY_FULL_FRAMEWORK_CONTENTS ON) + SET(BU_COPY_FULL_FRAMEWORK_CONTENTS ON) include(BundleUtilities) fixup_bundle(\"${APPS}\" \"\" \"/usr/local/lib\") - VERIFY_APP(\"${APPS}\") " COMPONENT Runtime) - # IF (BUNDLE_SOAPY_MODS) - # install( DIRECTORY "${SOAPY_SDR_ROOT}/lib/modules" - # DESTINATION ${APPS}/modules - # COMPONENT Runtime - # FILES_MATCHING - # PATTERN "*.dylib" - # PATTERN "*_debug.dylib" EXCLUDE - # ) - # ENDIF(BUNDLE_SOAPY_MODS) - - + IF (BUNDLE_SOAPY_MODS) + FOREACH(SOAPY_MOD_FILE ${SOAPY_MODS}) + GET_FILENAME_COMPONENT(SOAPY_MOD_NAME ${SOAPY_MOD_FILE} NAME) + + IF(${SOAPY_MOD_NAME} STREQUAL "libsdrPlaySupport.so") # prevent inclusion of libmirsdrapi-rsp.so + message(STATUS "Excluding libsdrPlaySupport.so") + CONTINUE() + ELSE() + message(STATUS "Bundling ${SOAPY_MOD_NAME} from ${SOAPY_MOD_FILE}") + ENDIF() + INSTALL(CODE " + fixup_bundle(\"${APPS}\" \"${APPS}/Contents/MacOS/modules/${SOAPY_MOD_NAME}\" \"/usr/local/lib\") + " COMPONENT Runtime) + ENDFOREACH() + ENDIF(BUNDLE_SOAPY_MODS) + + INSTALL(CODE " + VERIFY_APP(\"${APPS}\") + " COMPONENT Runtime) INSTALL(TARGETS CubicSDR BUNDLE DESTINATION . COMPONENT Runtime diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 49460b2..b622047 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -270,6 +270,16 @@ bool CubicSDR::OnCmdLineParsed(wxCmdLineParser& parser) { config.load(); +#ifdef BUNDLE_SOAPY_MODS + if (parser.Found("l")) { + useLocalMod.store(true); + } else { + useLocalMod.store(false); + } +#else + useLocalMod.store(false); +#endif + return true; } @@ -611,3 +621,6 @@ void CubicSDR::setDeviceArgs(SoapySDR::Kwargs settingArgs_in) { settingArgs = settingArgs_in; } +bool CubicSDR::getUseLocalMod() { + return useLocalMod.load(); +} \ No newline at end of file diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 4fed242..1150008 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -111,7 +111,8 @@ public: void setStreamArgs(SoapySDR::Kwargs streamArgs_in); void setDeviceArgs(SoapySDR::Kwargs settingArgs_in); - + + bool getUseLocalMod(); private: AppFrame *appframe; AppConfig config; @@ -150,15 +151,26 @@ private: std::atomic_bool devicesReady; std::atomic_bool deviceSelectorOpen; std::atomic_bool sampleRateInitialized; + std::atomic_bool useLocalMod; std::string notifyMessage; std::mutex notify_busy; }; +#ifdef BUNDLE_SOAPY_MODS +static const wxCmdLineEntryDesc commandLineInfo [] = +{ + { wxCMD_LINE_SWITCH, "h", "help", "Command line parameter help", wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, + { wxCMD_LINE_OPTION, "c", "config", "Specify a named configuration to use, i.e. '-c ham'" }, + { wxCMD_LINE_SWITCH, "l", "localmod", "Check local SoapySDR modules instead of bundled first." }, + { wxCMD_LINE_NONE } +}; +#else static const wxCmdLineEntryDesc commandLineInfo [] = { { wxCMD_LINE_SWITCH, "h", "help", "Command line parameter help", wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, { wxCMD_LINE_OPTION, "c", "config", "Specify a named configuration to use, i.e. '-c ham'" }, { wxCMD_LINE_NONE } }; +#endif DECLARE_APP(CubicSDR) diff --git a/src/sdr/SDREnumerator.cpp b/src/sdr/SDREnumerator.cpp index 30746d2..501d0e7 100644 --- a/src/sdr/SDREnumerator.cpp +++ b/src/sdr/SDREnumerator.cpp @@ -36,31 +36,44 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot std::cout << "\tAPI Version: v" << SoapySDR::getAPIVersion() << std::endl; std::cout << "\tABI Version: v" << SoapySDR::getABIVersion() << std::endl; std::cout << "\tInstall root: " << SoapySDR::getRootPath() << std::endl; - - modules = SoapySDR::listModules(); - for (size_t i = 0; i < modules.size(); i++) { - std::cout << "\tModule found: " << modules[i] << std::endl; - } - if (modules.empty()) { - std::cout << "No modules found!" << std::endl; - } - std::cout << "\tLoading modules... " << std::flush; + std::cout << "\tLoading modules... " << std::endl; #ifdef BUNDLE_SOAPY_MODS - wxFileName exePath = wxFileName(wxStandardPaths::Get().GetExecutablePath()); - std::vector localMods = SoapySDR::listModules(exePath.GetPath().ToStdString() + "/modules/"); - for (std::vector::iterator mods_i = localMods.begin(); mods_i != localMods.end(); mods_i++) { - wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Initializing bundled SoapySDR module " + (*mods_i) + ".."); - SoapySDR::loadModule(*mods_i); - } - wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Loading SoapySDR modules.."); + bool localModPref = wxGetApp().getUseLocalMod(); + if (localModPref) { + wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Loading SoapySDR modules.."); + std::cout << "Checking local system SoapySDR modules.." << std::flush; + SoapySDR::loadModules(); + } - SoapySDR::loadModules(); + wxFileName exePath = wxFileName(wxStandardPaths::Get().GetExecutablePath()); + std::vector localMods = SoapySDR::listModules(exePath.GetPath().ToStdString() + "/modules/"); + for (std::vector::iterator mods_i = localMods.begin(); mods_i != localMods.end(); mods_i++) { + wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Initializing bundled SoapySDR module " + (*mods_i) + ".."); + std::cout << "Loading bundled SoapySDR module " << (*mods_i) << ".." << std::endl; + SoapySDR::loadModule(*mods_i); + } + + if (!localModPref) { + wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Loading SoapySDR modules.."); + std::cout << "Checking system SoapySDR modules.." << std::flush; + SoapySDR::loadModules(); + } #else + wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Loading SoapySDR modules.."); SoapySDR::loadModules(); #endif - std::cout << "done" << std::endl; - + wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "done."); + std::cout << "done." << std::endl; + +// modules = SoapySDR::listModules(); +// for (size_t i = 0; i < modules.size(); i++) { +// std::cout << "\tModule found: " << modules[i] << std::endl; +// } +// if (modules.empty()) { +// std::cout << "No modules found!" << std::endl; +// } + if (SDREnumerator::factories.size()) { SDREnumerator::factories.erase(SDREnumerator::factories.begin(), SDREnumerator::factories.end()); }