From 3dc0c26ff50db7e4215f74c4a8ab133f8c485609 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 6 Mar 2022 01:30:15 +0100 Subject: [PATCH] Repair FCD support with better FindHIDAPI cmake module. Fixes #1160 --- CMakeLists.txt | 10 +- cmake/Modules/FindHIDAPI.cmake | 305 ++++++++++++++++++ fcdhid/CMakeLists.txt | 2 + plugins/samplesource/CMakeLists.txt | 8 +- plugins/samplesource/fcdpro/CMakeLists.txt | 17 +- .../samplesource/fcdproplus/CMakeLists.txt | 15 +- 6 files changed, 334 insertions(+), 23 deletions(-) create mode 100644 cmake/Modules/FindHIDAPI.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 39b082431..2acec2142 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -448,10 +448,12 @@ if(ENABLE_USRP) find_package(UHD) endif() -# if(ENABLE_FUNCUBE AND UNIX AND LIBUSB_FOUND) -# add_subdirectory(fcdlib) -# add_subdirectory(fcdhid) -# endif() +find_package(HIDAPI) + +if(ENABLE_FUNCUBE AND UNIX AND LIBUSB_FOUND AND HIDAPI_FOUND) + add_subdirectory(fcdlib) + add_subdirectory(fcdhid) +endif() # base libraries add_subdirectory(sdrbase) diff --git a/cmake/Modules/FindHIDAPI.cmake b/cmake/Modules/FindHIDAPI.cmake new file mode 100644 index 000000000..dd30df128 --- /dev/null +++ b/cmake/Modules/FindHIDAPI.cmake @@ -0,0 +1,305 @@ +# From https://github.com/rpavlik/cmake-modules/blob/main/FindHIDAPI.cmake + +#.rst: +# FindHIDAPI +# ---------- +# +# Try to find HIDAPI library, from http://www.signal11.us/oss/hidapi/ +# +# Cache Variables: (probably not for direct use in your scripts) +# HIDAPI_INCLUDE_DIR +# HIDAPI_LIBRARY +# +# Non-cache variables you might use in your CMakeLists.txt: +# HIDAPI_FOUND +# HIDAPI_INCLUDE_DIRS +# HIDAPI_LIBRARIES +# +# COMPONENTS +# ^^^^^^^^^^ +# +# This module respects several COMPONENTS specifying the backend you prefer: +# ``any`` (the default), ``libusb``, and ``hidraw``. +# The availablility of the latter two depends on your platform. +# +# +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` target ``HIDAPI::hidapi`` (in all cases or +# if no components specified), ``HIDAPI::hidapi-libusb`` (if you requested the libusb component), +# and ``HIDAPI::hidapi-hidraw`` (if you requested the hidraw component), +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# ``HIDAPI_FOUND`` +# True if HIDAPI or the requested components (if any) were found. +# +# We recommend using the imported targets instead of the following. +# +# ``HIDAPI_INCLUDE_DIRS`` +# ``HIDAPI_LIBRARIES`` +# +# Original Author: +# 2009-2010, 2019 Ryan Pavlik +# http://academic.cleardefinition.com +# +# Copyright 2009-2010, Iowa State University +# Copyright 2019, Collabora, Ltd. +# SPDX-License-Identifier: BSL-1.0 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(HIDAPI_ROOT_DIR + "${HIDAPI_ROOT_DIR}" + CACHE PATH "Root to search for HIDAPI") + +option(hidapi_USE_STATIC_LIBS "hidapi: link static libs" OFF) + +# Clean up components +if(HIDAPI_FIND_COMPONENTS) + if(WIN32 OR APPLE) + # This makes no sense on Windows or Mac, which have native APIs + list(REMOVE HIDAPI_FIND_COMPONENTS libusb) + endif() + + if(NOT ${CMAKE_SYSTEM} MATCHES "Linux") + # hidraw is only on linux + list(REMOVE HIDAPI_FIND_COMPONENTS hidraw) + endif() +endif() +if(NOT HIDAPI_FIND_COMPONENTS) + # Default to any + set(HIDAPI_FIND_COMPONENTS any) +endif() + +# Ask pkg-config for hints +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + set(_old_prefix_path "${CMAKE_PREFIX_PATH}") + # So pkg-config uses HIDAPI_ROOT_DIR too. + if(HIDAPI_ROOT_DIR) + list(APPEND CMAKE_PREFIX_PATH ${HIDAPI_ROOT_DIR}) + endif() + pkg_check_modules(PC_HIDAPI_LIBUSB QUIET hidapi-libusb) + pkg_check_modules(PC_HIDAPI_HIDRAW QUIET hidapi-hidraw) + # Restore + set(CMAKE_PREFIX_PATH "${_old_prefix_path}") +endif() + +set(HIDAPI_NAME hidapi) +set(HIDAPI_USB_NAME hidapi-libusb) +set(HIDAPI_RAW_NAME hidapi-hidraw) +if ((UNIX OR APPLE) AND hidapi_USE_STATIC_LIBS) + set(HIDAPI_NAME libhidapi.a) + set(HIDAPI_USB_NAME libhidapi-libusb.a) + set(HIDAPI_RAW_NAME libhidapi-hidraw.a) +endif() + +# Actually search +find_library( + HIDAPI_UNDECORATED_LIBRARY + NAMES ${HIDAPI_NAME} + PATHS "${HIDAPI_ROOT_DIR}" + PATH_SUFFIXES lib) + +find_library( + HIDAPI_LIBUSB_LIBRARY + NAMES ${HIDAPI_NAME} ${HIDAPI_USB_NAME} + PATHS "${HIDAPI_ROOT_DIR}" + PATH_SUFFIXES lib + HINTS ${PC_HIDAPI_LIBUSB_LIBRARY_DIRS}) + +if(CMAKE_SYSTEM MATCHES "Linux") + find_library( + HIDAPI_HIDRAW_LIBRARY + NAMES ${HIDAPI_RAW_NAME} + HINTS ${PC_HIDAPI_HIDRAW_LIBRARY_DIRS}) +endif() + +find_path( + HIDAPI_INCLUDE_DIR + NAMES hidapi.h + PATHS "${HIDAPI_ROOT_DIR}" + PATH_SUFFIXES hidapi include include/hidapi + HINTS ${PC_HIDAPI_HIDRAW_INCLUDE_DIRS} ${PC_HIDAPI_LIBUSB_INCLUDE_DIRS}) + +find_package(Threads QUIET) + +### +# Compute the "I don't care which backend" library +### +set(HIDAPI_LIBRARY) + +# First, try to use a preferred backend if supplied +if("${HIDAPI_FIND_COMPONENTS}" MATCHES "libusb" + AND HIDAPI_LIBUSB_LIBRARY + AND NOT HIDAPI_LIBRARY) + set(HIDAPI_LIBRARY ${HIDAPI_LIBUSB_LIBRARY}) +endif() +if("${HIDAPI_FIND_COMPONENTS}" MATCHES "hidraw" + AND HIDAPI_HIDRAW_LIBRARY + AND NOT HIDAPI_LIBRARY) + set(HIDAPI_LIBRARY ${HIDAPI_HIDRAW_LIBRARY}) +endif() + +# Then, if we don't have a preferred one, settle for anything. +if(NOT HIDAPI_LIBRARY) + if(HIDAPI_LIBUSB_LIBRARY) + set(HIDAPI_LIBRARY ${HIDAPI_LIBUSB_LIBRARY}) + elseif(HIDAPI_HIDRAW_LIBRARY) + set(HIDAPI_LIBRARY ${HIDAPI_HIDRAW_LIBRARY}) + elseif(HIDAPI_UNDECORATED_LIBRARY) + set(HIDAPI_LIBRARY ${HIDAPI_UNDECORATED_LIBRARY}) + endif() +endif() + +### +# Determine if the various requested components are found. +### +set(_hidapi_component_required_vars) + +foreach(_comp IN LISTS HIDAPI_FIND_COMPONENTS) + if("${_comp}" STREQUAL "any") + list(APPEND _hidapi_component_required_vars HIDAPI_INCLUDE_DIR + HIDAPI_LIBRARY) + if(HIDAPI_INCLUDE_DIR AND EXISTS "${HIDAPI_LIBRARY}") + set(HIDAPI_any_FOUND TRUE) + mark_as_advanced(HIDAPI_INCLUDE_DIR) + else() + set(HIDAPI_any_FOUND FALSE) + endif() + + elseif("${_comp}" STREQUAL "libusb") + list(APPEND _hidapi_component_required_vars HIDAPI_INCLUDE_DIR + HIDAPI_LIBUSB_LIBRARY) + if(HIDAPI_INCLUDE_DIR AND EXISTS "${HIDAPI_LIBUSB_LIBRARY}") + set(HIDAPI_libusb_FOUND TRUE) + mark_as_advanced(HIDAPI_INCLUDE_DIR HIDAPI_LIBUSB_LIBRARY) + else() + set(HIDAPI_libusb_FOUND FALSE) + endif() + + elseif("${_comp}" STREQUAL "hidraw") + list(APPEND _hidapi_component_required_vars HIDAPI_INCLUDE_DIR + HIDAPI_HIDRAW_LIBRARY) + if(HIDAPI_INCLUDE_DIR AND EXISTS "${HIDAPI_HIDRAW_LIBRARY}") + set(HIDAPI_hidraw_FOUND TRUE) + mark_as_advanced(HIDAPI_INCLUDE_DIR HIDAPI_HIDRAW_LIBRARY) + else() + set(HIDAPI_hidraw_FOUND FALSE) + endif() + + else() + message(WARNING "${_comp} is not a recognized HIDAPI component") + set(HIDAPI_${_comp}_FOUND FALSE) + endif() +endforeach() +unset(_comp) + +# If we have static linking and are under Linux, we need to link libusb for +# the USB backend, and udev for both backends. +if (hidapi_USE_STATIC_LIBS AND (UNIX AND NOT APPLE)) + if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_LIBUDEV libudev) + endif() + find_library(UDEV_LIBRARY + NAMES + libudev.a + udev + PATHS + ${PC_LIBUDEV_LIBRARY_DIRS} + ${PC_LIBUDEV_LIBDIR} + HINTS + "${UDEV_ROOT_DIR}" + ) + add_library(hidapi_udev STATIC IMPORTED) + set_target_properties( + hidapi_udev + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${UDEV_LIBRARY}") + list(APPEND _hidapi_component_required_vars UDEV_LIBRARY) + set(HIDAPI_EXTRA_LINK_LIBS hidapi_udev) + if(HIDAPI_LIBRARY STREQUAL ${HIDAPI_LIBUSB_LIBRARY}) + if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_LIBUSB1 libusb-1.0) + endif() + find_library(LIBUSB1_LIBRARY + NAMES + libusb-1.0.a + PATHS + ${PC_LIBUSB1_LIBRARY_DIRS} + ${PC_LIBUSB1_LIBDIR} + HINTS + "${LIBUSB1_ROOT_DIR}") + add_library(hidapi_libusb STATIC IMPORTED) + set_target_properties( + hidapi_libusb + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LINK_INTERFACE_LIBRARIES hidapi_udev + IMPORTED_LOCATION "${LIBUSB1_LIBRARY}") + list(APPEND _hidapi_usb_required_vars LIBUSB1_LIBRARY) + list(APPEND HIDAPI_USB_LINK_LIBS hidapi_libusb) + list(APPEND HIDAPI_EXTRA_LINK_LIBS ${HIDAPI_USB_LINK_LIBS}) + endif() +endif() + +# If we have static linking and are under Windows, we need to link with +# setupapi. +if (hidapi_USE_STATIC_LIBS AND WIN32) + list(APPEND HIDAPI_EXTRA_LINK_LIBS Setupapi) +endif() + +# If we have static linking and are under OSX, we need to link IOKit, +# CoreFoundation and AppKit. +if (hidapi_USE_STATIC_LIBS AND APPLE) + find_library(IOKIT_LIBRARY IOKit) + find_library(COREFOUNDATION_LIBRARY CoreFoundation) + find_library(APPKIT_LIBRARY AppKit) + list(APPEND _hidapi_component_required_vars IOKIT_LIBRARY COREFOUNDATION_LIBRARY APPKIT_LIBRARY) + list(APPEND HIDAPI_EXTRA_LINK_LIBS ${IOKIT_LIBRARY} ${COREFOUNDATION_LIBRARY} ${APPKIT_LIBRARY}) +endif() + +### +# FPHSA call +### +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + HIDAPI + REQUIRED_VARS ${_hidapi_component_required_vars} THREADS_FOUND + HANDLE_COMPONENTS) +if(HIDAPI_FOUND) + set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARY}") + set(HIDAPI_INCLUDE_DIRS "${HIDAPI_INCLUDE_DIR}") + if(NOT TARGET HIDAPI::hidapi) + add_library(HIDAPI::hidapi UNKNOWN IMPORTED) + set_target_properties( + HIDAPI::hidapi + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${HIDAPI_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${HIDAPI_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LIBRARIES "Threads::Threads;${HIDAPI_EXTRA_LINK_LIBS}") + endif() +endif() + +if(HIDAPI_libusb_FOUND AND NOT TARGET HIDAPI::hidapi-libusb) + add_library(HIDAPI::hidapi-libusb UNKNOWN IMPORTED) + set_target_properties( + HIDAPI::hidapi-libusb + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${HIDAPI_LIBUSB_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${HIDAPI_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LIBRARIES "Threads::Threads;${HIDAPI_EXTRA_LINK_LIBS};${HIDAPI_USB_LINK_LIBS}") +endif() + +if(HIDAPI_hidraw_FOUND AND NOT TARGET HIDAPI::hidapi-hidraw) + add_library(HIDAPI::hidapi-hidraw UNKNOWN IMPORTED) + set_target_properties( + HIDAPI::hidapi-hidraw + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${HIDAPI_HIDRAW_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${HIDAPI_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LIBRARIES "Threads::Threads;${HIDAPI_EXTRA_LINK_LIBS}") +endif() diff --git a/fcdhid/CMakeLists.txt b/fcdhid/CMakeLists.txt index 409a9a445..d808bde54 100644 --- a/fcdhid/CMakeLists.txt +++ b/fcdhid/CMakeLists.txt @@ -11,6 +11,7 @@ set(fcdhid_HEADERS include_directories( ${LIBUSB_INCLUDE_DIR} + ${HIDAPI_INCLUDE_DIRS} ${ICONV_INCLUDE_DIR} ${CUSTOM_APPLE_INCLUDE} ) @@ -21,6 +22,7 @@ add_library(fcdhid SHARED target_link_libraries(fcdhid ${LIBUSB_LIBRARIES} + ${HIDAPI_LIBRARIES} ${ICONV_LIBRARY} ) diff --git a/plugins/samplesource/CMakeLists.txt b/plugins/samplesource/CMakeLists.txt index cb9f21b1c..0fa6361e4 100644 --- a/plugins/samplesource/CMakeLists.txt +++ b/plugins/samplesource/CMakeLists.txt @@ -21,10 +21,10 @@ if(ENABLE_BLADERF AND LIBBLADERF_FOUND) add_subdirectory(bladerf2input) endif() -# if(ENABLE_FUNCUBE AND UNIX AND LIBUSB_FOUND) -# add_subdirectory(fcdpro) -# add_subdirectory(fcdproplus) -# endif() +if(ENABLE_FUNCUBE AND UNIX AND LIBUSB_FOUND AND HIDAPI_FOUND) + add_subdirectory(fcdpro) + add_subdirectory(fcdproplus) +endif() if(ENABLE_HACKRF AND LIBHACKRF_FOUND) add_subdirectory(hackrfinput) diff --git a/plugins/samplesource/fcdpro/CMakeLists.txt b/plugins/samplesource/fcdpro/CMakeLists.txt index 828eb6647..8c59e5ab1 100644 --- a/plugins/samplesource/fcdpro/CMakeLists.txt +++ b/plugins/samplesource/fcdpro/CMakeLists.txt @@ -17,8 +17,9 @@ set(fcdpro_HEADERS ) include_directories( - ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client - ${CMAKE_SOURCE_DIR}/fcdhid + ${HIDAPI_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CMAKE_SOURCE_DIR}/fcdhid ${CMAKE_SOURCE_DIR}/fcdlib ) @@ -26,7 +27,6 @@ if(NOT SERVER_MODE) set(fcdpro_SOURCES ${fcdpro_SOURCES} fcdprogui.cpp - fcdprogui.ui ) set(fcdpro_HEADERS @@ -50,13 +50,14 @@ add_library(${TARGET_NAME} SHARED ) target_link_libraries(${TARGET_NAME} - Qt5::Core - ${TARGET_LIB} + ${HIDAPI_LIBRARIES} + Qt5::Core + ${TARGET_LIB} sdrbase ${TARGET_LIB_GUI} - swagger - fcdhid - fcdlib + swagger + fcdhid + fcdlib ) install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER}) diff --git a/plugins/samplesource/fcdproplus/CMakeLists.txt b/plugins/samplesource/fcdproplus/CMakeLists.txt index d6c075964..90fc9ba0f 100644 --- a/plugins/samplesource/fcdproplus/CMakeLists.txt +++ b/plugins/samplesource/fcdproplus/CMakeLists.txt @@ -17,7 +17,8 @@ set(fcdproplus_HEADERS ) include_directories( - ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${HIDAPI_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client ${CMAKE_SOURCE_DIR}/fcdhid ${CMAKE_SOURCE_DIR}/fcdlib ) @@ -26,7 +27,6 @@ if(NOT SERVER_MODE) set(fcdproplus_SOURCES ${fcdproplus_SOURCES} fcdproplusgui.cpp - fcdproplusgui.ui ) set(fcdproplus_HEADERS @@ -50,13 +50,14 @@ add_library(${TARGET_NAME} SHARED ) target_link_libraries(${TARGET_NAME} - Qt5::Core - ${TARGET_LIB} + ${HIDAPI_LIBRARIES} + Qt5::Core + ${TARGET_LIB} sdrbase ${TARGET_LIB_GUI} - swagger - fcdhid - fcdlib + swagger + fcdhid + fcdlib ) install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})