diff --git a/.gitignore b/.gitignore index 1eedf653a..b4d70d754 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ sdrangelove.supp .settings/ *.cs *.pro.user +.idea/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 7172f7276..d18226e65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.1.0) cmake_policy(SET CMP0043 OLD) +# QT Framework +set(CMAKE_PREFIX_PATH "/Applications/Qt/5.7/clang_64/lib/cmake") + # use, i.e. don't skip the full RPATH for the build tree set(CMAKE_SKIP_BUILD_RPATH FALSE) @@ -56,6 +59,13 @@ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|x86") SET(USE_SIMD "SSE2" CACHE STRING "Use SIMD instructions") ENDIF() +# MacOS Compatibility +if(APPLE) + find_package(ICONV) + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lc++abi") + +endif(APPLE) ############################################################################## #include(${QT_USE_FILE}) diff --git a/apple_compat.c b/apple_compat.c new file mode 100644 index 000000000..1270ed284 --- /dev/null +++ b/apple_compat.c @@ -0,0 +1,77 @@ +/* + * APPLE Compatibility + */ + +#ifdef __APPLE__ + +#include +#include + +#include "apple_compat.h" + +int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count) +{ + if(count == 0) + { + errno = EINVAL; + return -1; + } + if(pthread_mutex_init(&barrier->mutex, 0) < 0) + { + return -1; + } + if(pthread_cond_init(&barrier->cond, 0) < 0) + { + pthread_mutex_destroy(&barrier->mutex); + return -1; + } + barrier->tripCount = count; + barrier->count = 0; + + return 0; +} + +int pthread_barrier_destroy(pthread_barrier_t *barrier) +{ + pthread_cond_destroy(&barrier->cond); + pthread_mutex_destroy(&barrier->mutex); + return 0; +} + +int pthread_barrier_wait(pthread_barrier_t *barrier) +{ + pthread_mutex_lock(&barrier->mutex); + ++(barrier->count); + if(barrier->count >= barrier->tripCount) + { + barrier->count = 0; + pthread_cond_broadcast(&barrier->cond); + pthread_mutex_unlock(&barrier->mutex); + return 1; + } + else + { + pthread_cond_wait(&barrier->cond, &(barrier->mutex)); + pthread_mutex_unlock(&barrier->mutex); + return 0; + } +} + +/** + * Missing POSIX RealTime/Monotonic Clock + */ +#include + +int clock_gettime(int clk_id, struct timespec *t) { + mach_timebase_info_data_t timebase; + mach_timebase_info(&timebase); + uint64_t time; + time = mach_absolute_time(); + double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom); + double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9); + t->tv_sec = seconds; + t->tv_nsec = nseconds; + return 0; +} + +#endif // APPLE Compatibility \ No newline at end of file diff --git a/apple_compat.h b/apple_compat.h new file mode 100644 index 000000000..17feacfb2 --- /dev/null +++ b/apple_compat.h @@ -0,0 +1,45 @@ +/* + * APPLE Compatibility + */ + +#ifdef __APPLE__ + +/** + * Missing POSIX Thread Barriers implementation + */ +#ifndef PTHREAD_BARRIER_H_ +#define PTHREAD_BARRIER_H_ + +#include +#include + +typedef int pthread_barrierattr_t; +typedef struct +{ + pthread_mutex_t mutex; + pthread_cond_t cond; + int count; + int tripCount; +} pthread_barrier_t; + + +int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count); + +int pthread_barrier_destroy(pthread_barrier_t *barrier); + +int pthread_barrier_wait(pthread_barrier_t *barrier); + +#endif // PTHREAD_BARRIER_H_ + +// +#ifndef CLOCK_REALTIME +# define CLOCK_REALTIME 0 +#endif + +#ifndef CLOCK_MONOTONIC +# define CLOCK_MONOTONIC 0 +#endif + +int clock_gettime(int clk_id, struct timespec *t); + +#endif // APPLE Compatibility \ No newline at end of file diff --git a/cmake/Modules/FindICONV.cmake b/cmake/Modules/FindICONV.cmake new file mode 100644 index 000000000..5d58070ef --- /dev/null +++ b/cmake/Modules/FindICONV.cmake @@ -0,0 +1,73 @@ +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) +include(CheckFunctionExists) +if (ICONV_INCLUDE_DIR) + # Already in cache, be silent + set(ICONV_FIND_QUIETLY TRUE) +endif() + +find_path(ICONV_INCLUDE_DIR iconv.h + /usr/include + /usr/local/include + /opt/local/include) + +set(POTENTIAL_ICONV_LIBS iconv libiconv libiconv2) + +find_library(ICONV_LIBRARY NAMES ${POTENTIAL_ICONV_LIBS} + PATHS /usr/lib /usr/local/lib /opt/local/lib) + +if(WIN32) + set(ICONV_DLL_NAMES iconv.dll libiconv.dll libiconv2.dll) + find_file(ICONV_DLL + NAMES ${ICONV_DLL_NAMES} + PATHS ENV PATH + NO_DEFAULT_PATH) + find_file(ICONV_DLL_HELP + NAMES ${ICONV_DLL_NAMES} + PATHS ENV PATH + ${ICONV_INCLUDE_DIR}/../bin) + if(ICONV_FIND_REQUIRED) + if(NOT ICONV_DLL AND NOT ICONV_DLL_HELP) + message(FATAL_ERROR "Could not find iconv.dll, please add correct your PATH environment variable") + endif() + if(NOT ICONV_DLL AND ICONV_DLL_HELP) + get_filename_component(ICONV_DLL_HELP ${ICONV_DLL_HELP} PATH) + message(STATUS) + message(STATUS "Could not find iconv.dll in standard search path, please add ") + message(STATUS "${ICONV_DLL_HELP}") + message(STATUS "to your PATH environment variable.") + message(STATUS) + message(FATAL_ERROR "exit cmake") + endif() + endif() + if(ICONV_INCLUDE_DIR AND ICONV_LIBRARY AND ICONV_DLL) + set(ICONV_FOUND TRUE) + endif() +else() + check_function_exists(iconv HAVE_ICONV_IN_LIBC) + if(ICONV_INCLUDE_DIR AND HAVE_ICONV_IN_LIBC) + set(ICONV_FOUND TRUE) + set(ICONV_LIBRARY CACHE TYPE STRING FORCE) + endif() + if(ICONV_INCLUDE_DIR AND ICONV_LIBRARY) + set(ICONV_FOUND TRUE) + endif() +endif() + + + +if(ICONV_FOUND) + if(NOT ICONV_FIND_QUIETLY) + message(STATUS "Found iconv library: ${ICONV_LIBRARY}") + #message(STATUS "Found iconv dll : ${ICONV_DLL}") + endif() +else() + if(ICONV_FIND_REQUIRED) + message(STATUS "Looked for iconv library named ${POTENTIAL_ICONV_LIBS}.") + message(STATUS "Found no acceptable iconv library. This is fatal.") + message(STATUS "iconv header: ${ICONV_INCLUDE_DIR}") + message(STATUS "iconv lib : ${ICONV_LIBRARY}") + message(FATAL_ERROR "Could NOT find iconv library") + endif() +endif() + +mark_as_advanced(ICONV_LIBRARY ICONV_INCLUDE_DIR) \ No newline at end of file diff --git a/fcdhid/CMakeLists.txt b/fcdhid/CMakeLists.txt index f90316c9b..145f1f7d5 100644 --- a/fcdhid/CMakeLists.txt +++ b/fcdhid/CMakeLists.txt @@ -1,11 +1,13 @@ project(fcdhid) set(fcdhid_SOURCES + ../apple_compat.c hid-libusb.c fcdhid.c ) set(fcdhid_HEADERS + ../apple_compat.h fcdhid.h hid-libusb.h hidapi.h @@ -25,6 +27,7 @@ add_library(fcdhid SHARED target_link_libraries(fcdhid ${LIBUSB_LIBRARIES} + ${ICONV_LIBRARY} ) install(TARGETS fcdhid DESTINATION lib) \ No newline at end of file diff --git a/fcdhid/hid-libusb.c b/fcdhid/hid-libusb.c index af11e6a80..fbed9bd4b 100644 --- a/fcdhid/hid-libusb.c +++ b/fcdhid/hid-libusb.c @@ -65,6 +65,15 @@ extern "C" { #define DETACH_KERNEL_DRIVER #endif +/** + * MacOS does not implement POSIX Thread Barriers + */ +#ifdef __APPLE__ + +#include "../apple_compat.h" + +#endif + /* Uncomment to enable the retrieval of Usage and Usage Page in hid_enumerate(). Warning, on platforms different from FreeBSD this is very invasive as it requires the detach diff --git a/sdrangel.macos.pro b/sdrangel.macos.pro new file mode 100644 index 000000000..d711c86c0 --- /dev/null +++ b/sdrangel.macos.pro @@ -0,0 +1,30 @@ +#-------------------------------------------------------- +# +# Pro file for MacOS builds with Qt Creator +# +#-------------------------------------------------------- + +TEMPLATE = subdirs +SUBDIRS = sdrbase +SUBDIRS += lz4 +SUBDIRS += librtlsdr +SUBDIRS += libhackrf +SUBDIRS += libairspy +SUBDIRS += plugins/samplesource/filesource +SUBDIRS += plugins/samplesource/sdrdaemon +SUBDIRS += plugins/samplesource/rtlsdr +SUBDIRS += plugins/samplesource/hackrf +SUBDIRS += plugins/samplesource/airspy +SUBDIRS += plugins/channel/chanalyzer +SUBDIRS += plugins/channel/demodam +SUBDIRS += plugins/channel/demodbfm +SUBDIRS += plugins/channel/demodlora +SUBDIRS += plugins/channel/demodnfm +SUBDIRS += plugins/channel/demodssb +SUBDIRS += plugins/channel/demodwfm +SUBDIRS += plugins/channel/tcpsrc +SUBDIRS += plugins/channel/udpsrc + +# Main app must be last +CONFIG += ordered +SUBDIRS += app diff --git a/sdrbase/plugin/pluginmanager.cpp b/sdrbase/plugin/pluginmanager.cpp index 4a58ddb2a..d261d6f15 100644 --- a/sdrbase/plugin/pluginmanager.cpp +++ b/sdrbase/plugin/pluginmanager.cpp @@ -355,7 +355,7 @@ void PluginManager::loadPlugins(const QDir& dir) foreach (QString fileName, pluginsDir.entryList(QDir::Files)) { - if (fileName.endsWith(".so") || fileName.endsWith(".dll")) + if (fileName.endsWith(".so") || fileName.endsWith(".dll") || fileName.endsWith(".dylib")) { qDebug() << "PluginManager::loadPlugins: fileName: " << qPrintable(fileName);