Cleanup of host software CMake build system (#664)

* Clean up the CMake build system and improve the FindFFTW3 module.

* Fixes for Linux build

* Include winsock.h to get struct timeval

* Couple more fixes for MSVC, also add new FindMath module

* Update host build README for new CMake changes (esp. Windows)

* Try to fix Travis OS X build error

* Add docs about pthread-win32

* Whoops, AppVeyor caught a bug in FindFFTW where the includes not being found weren't generating a fatal error.

* Travis rebuild bump

* One more fix: replace hardcoded include paths with a PATH_SUFFIX to standard include paths

* Invert Windows preprocessor flag so it's only needed when using a static build.  This preserves compatibility with the previous system.

* Fix copy-paste error

* Update cmake modules from amber-cmake upstream, incorporate TryLinkLibrary into FindUSB1

* Fix missing include
This commit is contained in:
Jamie Smith
2021-12-03 11:11:04 -08:00
committed by GitHub
parent e9dd7eb291
commit d60fb83320
16 changed files with 1199 additions and 226 deletions

View File

@ -18,6 +18,7 @@ install:
- curl -fsS -o "C:\fftw-3.3.5.zip" "ftp://ftp.fftw.org/pub/fftw/fftw-3.3.5-dll64.zip"
- 7z x -y "C:\fftw-3.3.5.zip" -o"C:\fftw"
- cd c:\fftw
- ps: lib /machine:x64 /def:libfftw3-3.def
- ps: lib /machine:x64 /def:libfftw3f-3.def
# ARM GCC for firmware builds
# - appveyor DownloadFile "https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-win32.zip" -FileName "C:\gcc-arm-none-eabi-win32.zip"
@ -34,8 +35,9 @@ build_script:
-DTHREADS_PTHREADS_INCLUDE_DIR=c:\pthreads\Pre-built.2\include \
-DTHREADS_PTHREADS_WIN32_LIBRARY=c:\pthreads\Pre-built.2\lib\x64\pthreadVC2.lib \
-DPKG_CONFIG_EXECUTABLE="C:\pkg-config\bin\pkg-config.exe" \
-DFFTW_INCLUDES=C:\fftw \
-DFFTW_LIBRARIES=C:\fftw\libfftw3f-3.lib \
-DFFTW_INCLUDES_SERIAL=C:\fftw \
-DFFTW_LIBRARY_SERIAL=C:\fftw\libfftw3-3.lib \
-DFFTWF_LIBRARY_SERIAL=C:\fftw\libfftw3f-3.lib \
..
- msbuild HackRF.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
# Firmware

View File

@ -1,10 +1,104 @@
#top dir cmake project for libhackrf + tools
cmake_minimum_required(VERSION 2.8)
project (HackRF C)
cmake_minimum_required(VERSION 3.8)
project(HackRF LANGUAGES C)
set(CMAKE_C_FLAGS "$ENV{CFLAGS}" CACHE STRING "C Flags")
# standard policies for CMake 3.8
cmake_policy(VERSION 3.8)
list(APPEND CMAKE_MODULE_PATH
${CMAKE_CURRENT_SOURCE_DIR}/cmake
${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules
${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/amber-cmake)
include(TryLinkLibrary)
include(LibraryUtils)
# Compilation flags
# -----------------------------------------------------
if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_C_FLAGS_RELEASE "-O3")
set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
set(CMAKE_C_FLAGS_RELEASE "/O2")
set(CMAKE_C_FLAGS_DEBUG "/MDd /Zi /Ob0 /Od")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} /W3")
# disable verbose security warnings
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
# enable M_PI
add_definitions(-D_USE_MATH_DEFINES=1)
# disable deprecated API headers
add_definitions(-DWIN32_LEAN_AND_MEAN)
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
set(CMAKE_C_FLAGS_RELEASE "-O3")
set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
else()
message(WARNING "Unknown compiler ${CMAKE_C_COMPILER_ID}, don't know how to set CFLAGS")
endif()
# language standard
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_EXTENSIONS TRUE) # for M_PI
# endianness
include(TestBigEndian)
test_big_endian(BIGENDIAN)
if(BIGENDIAN)
add_definitions(-DHACKRF_BIG_ENDIAN)
endif()
# RPATH
# (set to point to lib dir in install prefix)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# Find dependencies
# -----------------------------------------------------
message(STATUS "Checking dependencies...")
# fftw3
find_package(FFTW COMPONENTS SinglePrecision REQUIRED)
# libusb1.0
find_package(USB1 REQUIRED)
import_library(libusb ${LIBUSB_LIBRARIES} ${LIBUSB_INCLUDE_DIR})
# pthread
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
# tell FindThreads to use MSVC pthread library
set(THREADS_USE_PTHREADS_WIN32 TRUE)
endif()
find_package(Threads REQUIRED)
if(EXISTS "${THREADS_PTHREADS_INCLUDE_DIR}")
import_libraries(pthread LIBRARIES ${CMAKE_THREAD_LIBS_INIT} INCLUDES ${THREADS_PTHREADS_INCLUDE_DIR})
else()
# no include dir
import_libraries(pthread LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
endif()
# libm
find_package(CMath REQUIRED)
# Options
# -----------------------------------------------------
set(INSTALL_DEFAULT_BINDIR "bin" CACHE STRING "Appended to CMAKE_INSTALL_PREFIX")
# Subdirectories
# -----------------------------------------------------
add_subdirectory(libhackrf)
add_subdirectory(hackrf-tools)

View File

@ -33,12 +33,18 @@ rm -rf *
## How to build host software on Windows:
### Prerequisites for Cygwin, MinGW, or Visual Studio:
* cmake-2.8.12.1 or later from http://www.cmake.org/cmake/resources/software.html
* libusbx-1.0.18 or later from http://sourceforge.net/projects/libusbx/files/latest/download?source=files
* fftw-3.3.5 or later from http://www.fftw.org/install/windows.html
You will need to install these tools:
* cmake-3.8 or later from http://www.cmake.org/cmake/resources/software.html
* Install Windows driver for HackRF hardware or use Zadig see http://sourceforge.net/projects/libwdi/files/zadig
- If you want to use Zadig select HackRF USB device and just install/replace it with WinUSB driver.
You will also need these dependency libraries:
* libusb-1.0.18 or later from https://libusb.info/
* Make sure to grab the binaries corresponding to your VS version from the zip file
* fftw-3.3.5 or later from http://www.fftw.org/install/windows.html
If your environment has a package manager, such as Cygwin or MSYS2, you should be able to install these from there. Otherwise, you can download binaries directly from these sites and copy them to a build dependencies prefix. DLLs go in the bin folder, headers in include, .dll.a and .lib files in the lib folder, like normal.
>**Note for Windows build:**
You shall always execute hackrf-tools from Windows command shell and not from Cygwin or MinGW shell because on Cygwin/MinGW
Ctrl C is not managed correctly and especially for hackrf_transfer the Ctrl C(abort) will not stop correctly and will corrupt the file.
@ -53,26 +59,39 @@ make install
```
### For MinGW:
If you downloaded the fftw3 binaries above, you have to turn that fftw3 DLL into something MinGW can link to by running these commands in your prefix bin folder:
```
C:\your\build\prefix\bin> dlltool -d libfftw3f-3.def -l libfftw3f-3.dll.a -D libfftw3f-3.dll
C:\your\build\prefix\bin> dlltool -d libfftw3-3.def -l libfftw3-3.dll.a -D libfftw3-3.dll
```
Then move the generated .dll.a files to your prefix lib folder.
Now you can build from a Windows command prompt:
```
mkdir host/build
cd host/build
cmake ../ -G "MSYS Makefiles" -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/
make
make install
cmake ../ -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH=C:/your/build/prefix -DCMAKE_INSTALL_PREFIX=C:/your/install/prefix
mingw32-make
mingw32-make install
```
### For Visual Studio 2015 x64
Create library definition for MSVC to link to
`C:\fftw-3.3.5-dll64> lib /machine:x64 /def:libfftw3f-3.def`
Similarly to the MinGW instructions, create fftw3 import libraries for MSVC to link to. You may have to run these from a Visual Studio command prompt in the folder where you extracted the fftw3 .dll and .def files:
```
C:\your\build\prefix\bin> lib /machine:x64 /def:libfftw3f-3.def
C:\your\build\prefix\bin> lib /machine:x64 /def:libfftw3-3.def
```
Then move the generated .lib files to your prefix lib folder. Also rename them to get rid of the "lib" prefix, e.g. `fftw3-3.lib`.
For libusb, libusb-1.0.dll needs to be extracted to your bin folder, libusb-1.0.lib needs to be extracted to your lib folder and renamed usb-1.0.lib, and the libusb-1.0/ folder needs to be extracted to your include folder.
For MSVC you will also need one additional dependency, [pthreads-win32](http://mirrors.kernel.org/sourceware/pthreads-win32/pthreads-w32-2-9-1-release.zip). Download that and extract the headers and `pthreadVC2.lib` from the prebuilts folder inside the zip.
```
c:\hackrf\host\build> cmake ../ -G "Visual Studio 14 2015 Win64" \
-DLIBUSB_INCLUDE_DIR=c:\libusb-1.0.21\libusb \
-DLIBUSB_LIBRARIES=c:\libusb-1.0.21\MS64\dll\lib\libusb-1.0.lib \
-DTHREADS_PTHREADS_INCLUDE_DIR=c:\pthreads-w32-2-9-1-release\Pre-built.2\include \
-DTHREADS_PTHREADS_WIN32_LIBRARY=c:\pthreads-w32-2-9-1-release\Pre-built.2\lib\x64\pthreadVC2.lib \
-DFFTW_INCLUDES=C:\fftw-3.3.5-dll64 \
-DFFTW_LIBRARIES=C:\fftw-3.3.5-dll64\libfftw3f-3.lib
c:\hackrf\host\build> cmake ../ -G "Visual Studio 14 2015 Win64" -DCMAKE_PREFIX_PATH=C:/your/build/prefix -DCMAKE_INSTALL_PREFIX=C:/your/install/prefix
```
CMake will produce a solution file named `HackRF.sln` and a series of

View File

@ -1,30 +1,368 @@
# - Find FFTW
# Find the native FFTW includes and library
# Components:
# MPI Fortran SinglePrecision QuadPrecision
# FFTW_COMPILE_OPTIONS - Compile options to apply when using fftw
# FFTW_INCLUDES - where to find fftw3.h
# FFTW_LIBRARIES - List of libraries when using FFTW.
# FFTW_FOUND - True if FFTW found.
# FFTW_IS_SHARED - True if FFTW is being linked as a shared library
# FFTW_<Component>_FOUND - Whether the given component was found.
#
# FFTW_INCLUDES - where to find fftw3.h
# FFTW_LIBRARIES - List of libraries when using FFTW.
# FFTW_FOUND - True if FFTW found.
# Note that FFTW splits itself into multiple libraries,
# single precision (fftwf), double precision (fftw), and quad precision (fftwl).
# By default FindFFTW will find only the standard double precision variant.
# To guarantee that you get the other variants, request the relevant components.
#
# Why is there a "Fortran" component you ask? It's because some systems lack the Fortran headers (e.g. fftw3.f03)
#
# when using components:
# FFTW_INCLUDES_SERIAL - include path for FFTW serial
# FFTW_LIBRARIES_SERIAL - library for use of fftw from C and Fortran
# FFTW_INCLUDES_MPI - include path for FFTW MPI
# FFTW_LIBRARIES_MPI - extra FFTW library to use MPI
#
# This module also creates the following imported targets, if the relevant components are enabled:
# fftw::fftwl - Main (double precision) library
# fftw::fftwf - Single precision library
# fftw::fftwq - Quad precision library
# fftw::mpi_f - MPI single precision library
# fftw::mpi_l - MPI double precision library
# fftw::mpi_q - MPI quad precision library
# fftw::fftw - All enabled libraries
if (FFTW_INCLUDES)
if (FFTW_FOUND)
# Already in cache, be silent
set (FFTW_FIND_QUIETLY TRUE)
endif (FFTW_INCLUDES)
endif()
find_path (FFTW_INCLUDES fftw3.h)
include(CheckCSourceCompiles)
IF (WIN32)
include_directories(${FFTW_INCLUDES})
find_library (FFTW_LIBRARIES NAMES ${FFTW_LIBRARIES})
ELSE(WIN32)
find_library (FFTW_LIBRARIES NAMES fftw3f)
ENDIF(WIN32)
set(FFTW_REQUIRED_VARIABLES )
set(FFTW_COMPILE_OPTIONS )
set(FIND_FFTW_DEBUG FALSE)
# utility function for finding multiple precisions
macro(fftw_find_precision COMPONENT PREC LIBNAMES CHECK_FUNCTION TYPE)
if(FIND_FFTW_DEBUG)
message("Searching for split ${TYPE} FFTW library (${COMPONENT}) with names ${LIBNAMES}")
endif()
# first find the library
find_library(FFTW${PREC}_LIBRARY_${TYPE} NAMES ${LIBNAMES})
if(EXISTS "${FFTW${PREC}_LIBRARY_${TYPE}}")
if(FIND_FFTW_DEBUG)
message("Found ${COMPONENT} ${TYPE} FFTW library: ${FFTW${PREC}_LIBRARY_${TYPE}}")
endif()
# now check if it works
set(LIBS_TO_CHECK ${FFTW${PREC}_LIBRARY_${TYPE}})
if("${TYPE}" STREQUAL "SERIAL")
# only link serial FFTW
list(APPEND LIBS_TO_CHECK ${FFTW_LIBRARY_SERIAL})
else()
# link serial and parallel
list(APPEND LIBS_TO_CHECK ${FFTW_LIBRARY_MPI} ${FFTW_LIBRARY_SERIAL})
endif()
fftw_check_c_function(${CHECK_FUNCTION} FFTW${PREC}_${TYPE}_WORKS ${LIBS_TO_CHECK})
unset(LIBS_TO_CHECK)
else()
if(FIND_FFTW_DEBUG)
message("Could not find ${COMPONENT} ${TYPE} FFTW library: ${FFTW${PREC}_LIBRARY_${TYPE}}")
endif()
set(FFTW${PREC}_${TYPE}_WORKS FALSE)
endif()
if(FFTW${PREC}_${TYPE}_WORKS)
set(FFTW_LIBRARIES ${FFTW${PREC}_LIBRARY_SERIAL} ${FFTW_LIBRARIES})
set(FFTW_LIBRARIES_${TYPE} ${FFTW${PREC}_LIBRARY_SERIAL} ${FFTW_LIBRARIES_${TYPE}})
# if the component is already set to not found, then don't make it found
if(NOT (DEFINED FFTW_${COMPONENT}_FOUND AND NOT FFTW_${COMPONENT}_FOUND))
set(FFTW_${COMPONENT}_FOUND TRUE)
endif()
endif()
if(FFTW_FIND_REQUIRED_${COMPONENT})
list(APPEND FFTW_REQUIRED_VARIABLES FFTW${PREC}_LIBRARY_${TYPE} FFTW${PREC}_${TYPE}_WORKS)
endif()
endmacro(fftw_find_precision)
# Check if a given function can be found in a given library.
# Similar to CheckFunctionExists, but can handle DLL imports on Windows.
function(fftw_check_c_function FUNCTION RESULT_VARIABLE) # ARGN: LIBRARIES...
# mirror the logic in fftw3.h
if(FFTW_DLL_IMPORT)
set(FUNCTION_PREFIX "extern __declspec(dllimport)")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(FUNCTION_PREFIX "extern")
else()
set(FUNCTION_PREFIX "")
endif()
try_link_library(${RESULT_VARIABLE}
LANGUAGE C
FUNCTION ${FUNCTION}
FUNC_PREFIX ${FUNCTION_PREFIX}
LIBRARIES ${ARGN})
endfunction(fftw_check_c_function)
# headers
# --------------------------------------------------------------------
find_path (FFTW_INCLUDES_SERIAL fftw3.h)
set(FFTW_INCLUDES ${FFTW_INCLUDES_SERIAL})
list(APPEND FFTW_REQUIRED_VARIABLES FFTW_INCLUDES_SERIAL)
# serial libraries
# --------------------------------------------------------------------
find_library(FFTW_LIBRARY_SERIAL NAMES fftw3-3 fftw3 fftw)
set(FFTW_LIBRARIES ${FFTW_LIBRARY_SERIAL})
set(FFTW_LIBRARIES_SERIAL ${FFTW_LIBRARY_SERIAL})
if(FIND_FFTW_DEBUG AND EXISTS "${FFTW_LIBRARY_SERIAL}")
message("Found main FFTW library: ${FFTW_LIBRARY_SERIAL}")
endif()
# set up DLL compile flags (need to check type of library)
set(FFTW_IS_SHARED FALSE)
set(FFTW_DLL_IMPORT FALSE)
if(EXISTS "${FFTW_LIBRARY_SERIAL}")
get_lib_type(${FFTW_LIBRARY_SERIAL} FFTW_LIB_TYPE)
if(FIND_FFTW_DEBUG)
message("Lib type: ${FFTW_LIB_TYPE}")
endif()
if(FFTW_LIB_TYPE STREQUAL "SHARED" OR FFTW_LIB_TYPE STREQUAL "IMPORT")
set(FFTW_IS_SHARED TRUE)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND FFTW_LIB_TYPE STREQUAL "IMPORT")
set(FFTW_DLL_IMPORT TRUE)
set(FFTW_COMPILE_OPTIONS -DFFTW_DLL)
endif()
endif()
if(EXISTS "${FFTW_LIBRARY_SERIAL}")
fftw_check_c_function(fftw_execute FFTW_WORKS ${FFTW_LIBRARY_SERIAL})
else()
set(FFTW_WORKS FALSE)
endif()
set(FFTW_REQUIRED_VARIABLES FFTW_LIBRARY_SERIAL FFTW_WORKS ${FFTW_REQUIRED_VARIABLES})
# search for precision libraries
if("${FFTW_FIND_COMPONENTS}" MATCHES "SinglePrecision")
fftw_find_precision(SinglePrecision F "fftw3f-3;fftw3f;fftwf" fftwf_execute SERIAL)
endif()
if("${FFTW_FIND_COMPONENTS}" MATCHES "QuadPrecision")
fftw_find_precision(QuadPrecision L "fftw3l-3;fftw3l;fftwl" fftwl_execute SERIAL)
endif()
# Fortran component
# --------------------------------------------------------------------
if("${FFTW_FIND_COMPONENTS}" MATCHES "Fortran")
# should exist if Fortran support is present
set(FFTW_FORTRAN_HEADER "${FFTW_INCLUDES_SERIAL}/fftw3.f03")
if(NOT EXISTS "${FFTW_INCLUDES_SERIAL}")
message(STATUS "Cannot search for FFTW Fortran headers because the serial headers were not found")
set(FFTW_Fortran_FOUND FALSE)
elseif(EXISTS "${FFTW_FORTRAN_HEADER}")
# check that the Fortran compiler can link fftw and that the manglings match
# Deal with annoying issue: sometimes /usr/include is removed from Fortran
# include directories since CMake incorrectly thinks it's part of the implcit
# include directories.
# We could try clearing "CMAKE_Fortran_IMPLICIT_INCLUDE_DIRECTORIES" but that won't
# work in try_link_library().
set(FFTW_INCLUDES_FORTRAN ${FFTW_INCLUDES_SERIAL})
if("${FFTW_INCLUDES_FORTRAN}" IN_LIST CMAKE_Fortran_IMPLICIT_INCLUDE_DIRECTORIES)
get_filename_component(FFTW_FORTRAN_INCLUDE_FOLDER ${FFTW_INCLUDES_FORTRAN} NAME )
set(FFTW_INCLUDES_FORTRAN ${FFTW_INCLUDES_FORTRAN}/../${FFTW_FORTRAN_INCLUDE_FOLDER})
endif()
try_link_library(FFTW_FORTRAN_WORKS
LANGUAGE Fortran
FUNCTION fftw_cleanup
LIBRARIES ${FFTW_LIBRARY_SERIAL}
INCLUDES ${FFTW_INCLUDES_FORTRAN}
FUNC_CALL "
use, intrinsic :: iso_c_binding
implicit none
include 'fftw3.f03'
call fftw_cleanup()")
if(FFTW_FORTRAN_WORKS)
set(FFTW_Fortran_FOUND TRUE)
list(APPEND FFTW_INCLUDES ${FFTW_INCLUDES_FORTRAN})
else()
set(FFTW_Fortran_FOUND FALSE)
endif()
else()
set(FFTW_Fortran_FOUND FALSE)
message(STATUS "Cannot find FFTW Fortran headers - ${FFTW_FORTRAN_HEADER} is missing.")
endif()
if(FFTW_FIND_REQUIRED_Fortran)
list(APPEND FFTW_REQUIRED_VARIABLES FFTW_FORTRAN_HEADER FFTW_FORTRAN_WORKS)
endif()
endif()
# MPI component
# --------------------------------------------------------------------
if("${FFTW_FIND_COMPONENTS}" MATCHES "MPI")
find_library(FFTW_LIBRARY_MPI NAMES fftw3_mpi fftw_mpi)
set(FFTW_LIBRARIES_MPI ${FFTW_LIBRARY_MPI})
find_path(FFTW_INCLUDES_MPI fftw3-mpi.h)
list(APPEND FFTW_INCLUDES ${FFTW_INCLUDES_MPI})
set(CMAKE_REQUIRED_LIBRARIES ${FFTW_LIBRARY_MPI})
if(EXISTS "${FFTW_LIBRARY_MPI}")
fftw_check_c_function(fftw_mpi_init FFTW_MPI_WORKS)
else()
set(FFTW_MPI_WORKS FALSE)
endif()
if(FFTW_MPI_WORKS)
set(FFTW_MPI_FOUND TRUE)
endif()
if(FFTW_FIND_REQUIRED_MPI)
list(APPEND FFTW_REQUIRED_VARIABLES FFTW_LIBRARY_MPI FFTW_INCLUDES_MPI FFTW_MPI_WORKS)
endif()
if("${FFTW_FIND_COMPONENTS}" MATCHES "SinglePrecision")
fftw_find_precision(SinglePrecision F "fftw3f_mpi-3;fftw3f_mpi;fftwf_mpi" fftwl_mpi_init MPI)
endif()
if("${FFTW_FIND_COMPONENTS}" MATCHES "QuadPrecision")
fftw_find_precision(QuadPrecision L "fftw3l_mpi-3;fftw3l_mpi;fftwl_mpi" fftwl_mpi_init MPI)
endif()
# also look for MPI fortran header if we requested fortran and MPI
if("${FFTW_FIND_COMPONENTS}" MATCHES "Fortran" AND FFTW_Fortran_FOUND)
set(FFTW_FORTRAN_MPI_HEADER "${FFTW_INCLUDES_MPI}/fftw3-mpi.f03")
# reevaluate our life choices
if(EXISTS "${FFTW_FORTRAN_MPI_HEADER}")
set(FFTW_Fortran_FOUND TRUE)
else()
set(FFTW_Fortran_FOUND FALSE)
message(STATUS "Cannot find FFTW Fortran headers - ${FFTW_FORTRAN_MPI_HEADER} is missing")
endif()
endif()
set(FFTW_LIBRARIES ${FFTW_LIBRARIES_MPI} ${FFTW_LIBRARIES})
mark_as_advanced (FFTW_LIBRARIES_MPI FFTW_INCLUDES_MPI)
endif()
# handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE if
# all listed variables are TRUE
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (FFTW DEFAULT_MSG FFTW_LIBRARIES FFTW_INCLUDES)
find_package_handle_standard_args (FFTW REQUIRED_VARS ${FFTW_REQUIRED_VARIABLES})
mark_as_advanced (FFTW_LIBRARIES FFTW_INCLUDES)
mark_as_advanced(${FFTW_REQUIRED_VARIABLES})
# dump variables in debug mode
if(FIND_FFTW_DEBUG)
message("FFTW_COMPILE_OPTIONS: ${FFTW_COMPILE_OPTIONS}")
message("FFTW_INCLUDES: ${FFTW_INCLUDES}")
message("FFTW_LIBRARIES: ${FFTW_LIBRARIES}")
message("FFTW_FOUND: ${FFTW_FOUND}")
message("FFTW_IS_SHARED: ${FFTW_IS_SHARED}")
endif()
# import targets
if(FFTW_FOUND)
# main lib (double precision)
add_library(fftw::fftwl UNKNOWN IMPORTED)
set_property(TARGET fftw::fftwl PROPERTY IMPORTED_LOCATION ${FFTW_LIBRARY_SERIAL})
set_property(TARGET fftw::fftwl PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${FFTW_INCLUDES_SERIAL})
set_property(TARGET fftw::fftwl PROPERTY INTERFACE_COMPILE_OPTIONS ${FFTW_COMPILE_OPTIONS})
set(FFTW_ALL_IMPORTED_LIBRARIES fftw::fftwl)
if(FFTW_SinglePrecision_FOUND)
add_library(fftw::fftwf UNKNOWN IMPORTED)
set_property(TARGET fftw::fftwf PROPERTY IMPORTED_LOCATION ${FFTWF_LIBRARY_SERIAL})
set_property(TARGET fftw::fftwf PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${FFTW_INCLUDES_SERIAL})
set_property(TARGET fftw::fftwf PROPERTY INTERFACE_COMPILE_OPTIONS ${FFTW_COMPILE_OPTIONS})
list(APPEND FFTW_ALL_IMPORTED_LIBRARIES fftw::fftwf)
endif()
if(FFTW_QuadPrecision_FOUND)
add_library(fftw::fftwq UNKNOWN IMPORTED)
set_property(TARGET fftw::fftwq PROPERTY IMPORTED_LOCATION ${FFTWQ_LIBRARY_SERIAL})
set_property(TARGET fftw::fftwq PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${FFTW_INCLUDES_SERIAL})
set_property(TARGET fftw::fftwq PROPERTY INTERFACE_COMPILE_OPTIONS ${FFTW_COMPILE_OPTIONS})
list(APPEND FFTW_ALL_IMPORTED_LIBRARIES fftw::fftwq)
endif()
if(FFTW_MPI_FOUND)
add_library(fftw::mpi_l UNKNOWN IMPORTED)
set_property(TARGET fftw::mpi_l PROPERTY IMPORTED_LOCATION ${FFTW_LIBRARY_MPI})
set_property(TARGET fftw::mpi_l PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${FFTW_INCLUDES_MPI})
set_property(TARGET fftw::mpi_l PROPERTY INTERFACE_LINK_LIBRARIES fftw::fftwl)
list(APPEND FFTW_ALL_IMPORTED_LIBRARIES fftw::mpi_l)
if(FFTW_SinglePrecision_FOUND)
add_library(fftw::mpi_f UNKNOWN IMPORTED)
set_property(TARGET fftw::mpi_f PROPERTY IMPORTED_LOCATION ${FFTWF_LIBRARY_MPI})
set_property(TARGET fftw::mpi_f PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${FFTW_INCLUDES_MPI})
set_property(TARGET fftw::mpi_f PROPERTY INTERFACE_LINK_LIBRARIES fftw::fftwf)
list(APPEND FFTW_ALL_IMPORTED_LIBRARIES fftw::mpi_f)
endif()
if(FFTW_QuadPrecision_FOUND)
add_library(fftw::mpi_q UNKNOWN IMPORTED)
set_property(TARGET fftw::mpi_q PROPERTY IMPORTED_LOCATION ${FFTWQ_LIBRARY_MPI})
set_property(TARGET fftw::mpi_q PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${FFTW_INCLUDES_MPI})
set_property(TARGET fftw::mpi_q PROPERTY INTERFACE_LINK_LIBRARIES fftw::fftwq)
list(APPEND FFTW_ALL_IMPORTED_LIBRARIES fftw::mpi_q)
endif()
endif()
# add combined target
add_library(fftw::fftw INTERFACE IMPORTED)
set_property(TARGET fftw::fftw PROPERTY INTERFACE_LINK_LIBRARIES ${FFTW_ALL_IMPORTED_LIBRARIES})
set_property(TARGET fftw::fftw PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${FFTW_INCLUDES})
endif()
# don't leak required libraries
set(CMAKE_REQUIRED_LIBRARIES "")

View File

@ -12,44 +12,32 @@
if (LIBHACKRF_INCLUDE_DIR AND LIBHACKRF_LIBRARIES)
# in cache already
set(LIBHACKRF_FOUND TRUE)
set(LIBHACKRF_FIND_QUIETLY TRUE)
endif()
else (LIBHACKRF_INCLUDE_DIR AND LIBHACKRF_LIBRARIES)
IF (NOT WIN32)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PC_LIBHACKRF QUIET libhackrf)
ENDIF(NOT WIN32)
IF (NOT WIN32)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PC_LIBHACKRF QUIET libhackrf)
ENDIF(NOT WIN32)
FIND_PATH(LIBHACKRF_INCLUDE_DIR
NAMES hackrf.h
HINTS $ENV{LIBHACKRF_DIR}/include ${PC_LIBHACKRF_INCLUDEDIR}
PATHS /usr/local/include/libhackrf /usr/include/libhackrf /usr/local/include
/usr/include ${CMAKE_SOURCE_DIR}/../libhackrf/src
/opt/local/include/libhackrf
${LIBHACKRF_INCLUDE_DIR}
)
FIND_PATH(LIBHACKRF_INCLUDE_DIR
NAMES hackrf.h
HINTS $ENV{LIBHACKRF_DIR}/include ${PC_LIBHACKRF_INCLUDEDIR}
PATH_SUFFIXES libhackrf
)
set(libhackrf_library_names hackrf)
set(libhackrf_library_names hackrf)
FIND_LIBRARY(LIBHACKRF_LIBRARIES
NAMES ${libhackrf_library_names}
HINTS $ENV{LIBHACKRF_DIR}/lib ${PC_LIBHACKRF_LIBDIR}
PATHS /usr/local/lib /usr/lib /opt/local/lib ${PC_LIBHACKRF_LIBDIR} ${PC_LIBHACKRF_LIBRARY_DIRS} ${CMAKE_SOURCE_DIR}/../libhackrf/src
)
FIND_LIBRARY(LIBHACKRF_LIBRARIES
NAMES ${libhackrf_library_names}
HINTS $ENV{LIBHACKRF_DIR}/lib ${PC_LIBHACKRF_LIBDIR}
PATHS /usr/local/lib /usr/lib /opt/local/lib ${PC_LIBHACKRF_LIBRARY_DIRS}
)
if(LIBHACKRF_INCLUDE_DIR)
set(CMAKE_REQUIRED_INCLUDES ${LIBHACKRF_INCLUDE_DIR})
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBHACKRF DEFAULT_MSG LIBHACKRF_LIBRARIES LIBHACKRF_INCLUDE_DIR)
if(LIBHACKRF_LIBRARIES)
set(CMAKE_REQUIRED_LIBRARIES ${LIBHACKRF_LIBRARIES})
endif()
MARK_AS_ADVANCED(LIBHACKRF_INCLUDE_DIR LIBHACKRF_LIBRARIES)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBHACKRF DEFAULT_MSG LIBHACKRF_LIBRARIES LIBHACKRF_INCLUDE_DIR)
MARK_AS_ADVANCED(LIBHACKRF_INCLUDE_DIR LIBHACKRF_LIBRARIES)
endif (LIBHACKRF_INCLUDE_DIR AND LIBHACKRF_LIBRARIES)

View File

@ -1,4 +1,4 @@
# - Try to find the freetype library
# - Try to find the libusb library
# Once done this defines
#
# LIBUSB_FOUND - system has libusb
@ -14,30 +14,36 @@
if (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
# in cache already
set(LIBUSB_FOUND TRUE)
set(USB1_FIND_QUIETLY TRUE)
endif()
else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
IF (NOT WIN32)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PC_LIBUSB libusb-1.0)
ENDIF(NOT WIN32)
set(LIBUSB_LIBRARY_NAME usb-1.0)
IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(LIBUSB_LIBRARY_NAME usb)
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
IF (NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PC_LIBUSB libusb-1.0)
ENDIF()
FIND_PATH(LIBUSB_INCLUDE_DIR libusb.h
PATHS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS})
set(LIBUSB_LIBRARY_NAME usb-1.0)
IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(LIBUSB_LIBRARY_NAME usb)
ENDIF()
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES ${LIBUSB_LIBRARY_NAME}
PATHS ${PC_LIBUSB_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS})
FIND_PATH(LIBUSB_INCLUDE_DIR libusb.h
PATHS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS}
PATH_SUFFIXES libusb-1.0)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR)
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES ${LIBUSB_LIBRARY_NAME}
PATHS ${PC_LIBUSB_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS})
MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
try_link_library(LIBUSB1_WORKS
LANGUAGE C
FUNCTION libusb_init
LIBRARIES ${LIBUSB_LIBRARIES})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(USB1 DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR LIBUSB1_WORKS)
MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
endif (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)

View File

@ -0,0 +1,92 @@
#[=======================================================================[.rst:
FindCMath
-------
Finds the C Math library.
Imported Targets
^^^^^^^^^^^^^^^^
This module provides the following imported targets, if found:
``C::Math``
The C math library
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``CMath_FOUND``
True if the system has the C math library.
``CMath_LIBRARIES``
List of C math libraries. Might be empty.
#]=======================================================================]
include(CMakePushCheckState)
include(CheckCSourceCompiles)
set(CHECK_SINE_C_SOURCE "#include <math.h>
int main(int argc, char** argv)
{
return sin(argc - 1);
}")
set(CMath_WORKS FALSE)
check_c_source_compiles("${CHECK_SINE_C_SOURCE}" CMath_LINKS_WITHOUT_M)
if ("${CMath_LINKS_WITHOUT_M}")
set(CMath_LIBRARIES "")
else()
find_library(CMath_LIBRARIES NAMES m math libm)
if(EXISTS "${CMath_LIBRARIES}")
cmake_push_check_state()
set(CMAKE_REQUIRED_FLAGS "")
set(CMAKE_REQUIRED_LIBRARIES "${CMath_LIBRARIES}")
check_c_source_compiles("${CHECK_SINE_C_SOURCE}" CMath_LINKS_WITH_M)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE_CMATH})
set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE_CMATH})
cmake_pop_check_state()
else()
set(CMath_LINKS_WITH_M FALSE)
endif()
endif ()
if (("${CMath_LINKS_WITH_M}" OR "${CMath_LINKS_WITHOUT_M}") )
set(CMath_WORKS TRUE)
endif()
# we want FPHSA to print a library path when libm is found as a library
if(CMath_LINKS_WITH_M)
set(CMath_REQUIRED_VARS CMath_LIBRARIES CMath_WORKS)
else()
set(CMath_REQUIRED_VARS CMath_WORKS)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CMath DEFAULT_MSG ${CMath_REQUIRED_VARS})
if ("${CMath_FOUND}" AND NOT TARGET C::Math)
if(CMath_LINKS_WITH_M)
# create imported target
import_library(C::Math "${CMath_LIBRARIES}")
else()
# create empty target
add_library(C::Math INTERFACE IMPORTED GLOBAL)
endif()
endif ()
# Mark variables as advanced, effectively hiding from ccmake interface
mark_as_advanced(
CMath_LINKS_WITHOUT_M
CMath_LINKS_WITH_M
CMath_LIBRARIES
)

View File

@ -0,0 +1,292 @@
# Script containing several advanced functions for handling libraries in CMake.
# linker flag prefix -- if a link library starts with this character, it will be ignored by import_libraries()
# this is needed because things can return linker flags mixed with its libraries (which is actually the official CMake way of doing things)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
set(LINKER_FLAG_PREFIX "/") # stupid illogical MSVC command-line format...
else()
set(LINKER_FLAG_PREFIX "-")
endif()
#Unfortunately, CMake doesn't let you import a library without knowing whether it is shared or static, and there's no easy way to tell which it is.
#sets OUTPUT_VARAIBLE to "IMPORT", "SHARED", or "STATIC" depending on the library passed
function(get_lib_type LIBRARY OUTPUT_VARIABLE)
if(NOT EXISTS ${LIBRARY})
message(FATAL_ERROR "get_lib_type(): library ${LIBRARY} does not exist!")
endif()
get_filename_component(LIB_NAME ${LIBRARY} NAME)
set(CACHE_VAR_NAME GET_LIB_TYPE_CACHED_RESULT_${LIB_NAME})
if((DEFINED ${CACHE_VAR_NAME}) AND ("${${CACHE_VAR_NAME}}" STREQUAL "SHARED" OR "${${CACHE_VAR_NAME}}" STREQUAL "STATIC" OR "${${CACHE_VAR_NAME}}" STREQUAL "IMPORT"))
# use cache variable
set(${OUTPUT_VARIABLE} ${${CACHE_VAR_NAME}} PARENT_SCOPE)
return()
endif()
# first, check for import libraries
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
if(MINGW)
# on MinGW, import libraries have a different file extension, so our job is easy.
if(${LIB_NAME} MATCHES ".*${CMAKE_IMPORT_LIBRARY_SUFFIX}")
set(LIB_TYPE IMPORT)
endif()
else() # MSVC, Intel, or some other Windows compiler
# we have to work a little harder, and use Dumpbin to check the library type, since import and static libraries have the same extensions
get_filename_component(CL_INSTALL_DIR ${CMAKE_C_COMPILER} DIRECTORY)
find_program(DUMPBIN dumpbin HINTS ${CL_INSTALL_DIR})
if(NOT DUMPBIN)
message(FATAL_ERROR "The Microsoft Dumpbin tool was not found. It is needed to analyze libraries, so please set the DUMPBIN variable to point to it.")
endif()
# NOTE: this can take around 2-5 seconds for large libraries -- hence why we cache the result of this function
execute_process(COMMAND ${DUMPBIN} -headers ${LIBRARY} OUTPUT_VARIABLE DUMPBIN_OUTPUT ERROR_VARIABLE DUMPBIN_ERROUT RESULT_VARIABLE DUMPBIN_RESULT)
# sanity check
if(NOT ${DUMPBIN_RESULT} EQUAL 0)
message(FATAL_ERROR "Could not analyze the type of library ${LIBRARY}: dumpbin failed to execute with output ${DUMPBIN_OUTPUT} and error message ${DUMPBIN_ERROUT}")
endif()
# check for dynamic symbol entries
# https://stackoverflow.com/questions/488809/tools-for-inspecting-lib-files
if("${DUMPBIN_OUTPUT}" MATCHES "Symbol name :")
# found one! It's an import library!
set(LIB_TYPE IMPORT)
else()
# by process of elimination, it's a static library
set(LIB_TYPE STATIC)
endif()
endif()
endif()
# now we can figure the rest out by suffix matching
if((NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") OR (CMAKE_SYSTEM_NAME STREQUAL "Windows" AND MINGW AND "${LIB_TYPE}" STREQUAL ""))
if(${LIB_NAME} MATCHES ".*${CMAKE_SHARED_LIBRARY_SUFFIX}")
set(LIB_TYPE SHARED)
elseif(${LIB_NAME} MATCHES ".*${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(LIB_TYPE STATIC)
else()
message(FATAL_ERROR "Could not determine whether \"${LIBRARY}\" is a static or shared library, it does not have a known suffix.")
endif()
endif()
set(${OUTPUT_VARIABLE} ${LIB_TYPE} PARENT_SCOPE)
set(${CACHE_VAR_NAME} ${LIB_TYPE} CACHE INTERNAL "Result of get_lib_type() for ${LIB_NAME}" FORCE)
endfunction(get_lib_type)
# Takes a list of CMake libraries that you might pass to a target, and returns a list of resolved library paths that correspond to it.
# Some libraries are known by full path, others are known by link-name only (as in, the name you'd pass to "ld -l"). They'll be returned in order in LIB_PATHS.
# Accepts 5 types of thing: full paths to libraries, CMake library targets built by this project, CMake imported targets, CMake interface targets (returns their INTERFACE_LINK_LIBRARIES), and regular linker library names.
# For example, on my system,
# resolve_cmake_library_list("-Wl,--no-as-needed;mkl::core;mkl::threading;mkl::fortran_interface;/usr/lib/x86_64-linux-gnu/libdl.so;Threads::Threads;arpack;/usr/lib/x86_64-linux-gnu/libm.so")
# returns
# "-Wl,--no-as-needed;/home/jamie/anaconda3/lib/libmkl_core.so;/home/jamie/anaconda3/lib/libmkl_sequential.so;/home/jamie/anaconda3/lib/libmkl_gf_lp64.so;/usr/lib/x86_64-linux-gnu/libdl.so;-lpthread;arpack;/usr/lib/x86_64-linux-gnu/libm.so"
# usage: resolve_cmake_library_list(<path output var> <libs...>)
function(resolve_cmake_library_list LIB_PATH_OUTPUT)
# we don't want to add generator expressions to the library tracker...
string(GENEX_STRIP "${ARGN}" LIBS_TO_RESOLVE)
set(LIB_PATHS "")
foreach(LIBRARY ${LIBS_TO_RESOLVE})
if("${LIBRARY}" MATCHES "^${LINKER_FLAG_PREFIX}")
# linker flag
list(APPEND LIB_PATHS "${LIBRARY}")
elseif(EXISTS "${LIBRARY}")
# full path to library
list(APPEND LIB_PATHS "${LIBRARY}")
elseif(TARGET "${LIBRARY}")
get_property(TARGET_LIB_TYPE TARGET ${LIBRARY} PROPERTY TYPE)
# it's an error to check if an interface library has an imported location
if("${TARGET_LIB_TYPE}" STREQUAL "INTERFACE_LIBRARY")
# interface library -- but it will have dependencies that we need to get.
get_property(INTERFACE_LIB_DEPENDENCIES TARGET ${LIBRARY} PROPERTY INTERFACE_LINK_LIBRARIES)
if(NOT "${INTERFACE_LIB_DEPENDENCIES}" STREQUAL "")
# avoid crashing CMake if somebody accidentally made an interface library depend on itself
list(REMOVE_ITEM INTERFACE_LIB_DEPENDENCIES "${LIBRARY}")
# now parse those dependencies!
resolve_cmake_library_list(INTERFACE_DEPS_LIB_PATHS ${INTERFACE_LIB_DEPENDENCIES})
list(APPEND LIB_PATHS ${INTERFACE_DEPS_LIB_PATHS})
endif()
else()
# must be either imported or an actual target
get_property(LIBRARY_HAS_IMPORTED_LOCATION TARGET ${LIBRARY} PROPERTY IMPORTED_LOCATION SET)
if(LIBRARY_HAS_IMPORTED_LOCATION)
# CMake imported target
get_property(LIBRARY_IMPORTED_LOCATION TARGET ${LIBRARY} PROPERTY IMPORTED_LOCATION)
list(APPEND LIB_PATHS "${LIBRARY_IMPORTED_LOCATION}")
else()
# else it's a CMake target that is built by this project
# detect if the library has been renamed
get_property(LIB_NAME TARGET ${LIBRARY} PROPERTY OUTPUT_NAME)
if("${LIB_NAME}" STREQUAL "")
# use target name if output name was not set
set(LIB_NAME ${LIBRARY})
endif()
list(APPEND LIB_PATHS ${LIB_NAME})
endif()
endif()
else()
# otherwise it's a library name to find on the linker search path (using CMake in "naive mode")
list(APPEND LIB_PATHS ${LIBRARY})
endif()
endforeach()
# debugging code
if(FALSE)
message("resolve_cmake_library_list(${LIBS_TO_RESOLVE}):")
message(" -> ${LIB_PATHS}")
endif()
set(${LIB_PATH_OUTPUT} ${LIB_PATHS} PARENT_SCOPE)
endfunction(resolve_cmake_library_list)
# gets the "linker name" (the name you'd pass to "ld -l") for a library file.
function(get_linker_name LIBRARY_PATH OUTPUT_VARIABLE)
# get full library name
get_filename_component(LIBNAME "${LIBRARY_PATH}" NAME)
#remove prefix
string(REGEX REPLACE "^lib" "" LIBNAME "${LIBNAME}")
#remove numbers after the file extension
string(REGEX REPLACE "(\\.[0-9])+$" "" LIBNAME "${LIBNAME}")
#remove the file extension
get_lib_type(${LIBRARY_PATH} LIB_TYPE)
if("${LIB_TYPE}" STREQUAL "IMPORT")
string(REGEX REPLACE "${CMAKE_IMPORT_LIBRARY_SUFFIX}$" "" LIBNAME ${LIBNAME})
elseif("${LIB_TYPE}" STREQUAL "STATIC")
string(REGEX REPLACE "${CMAKE_STATIC_LIBRARY_SUFFIX}\$" "" LIBNAME ${LIBNAME})
else()
string(REGEX REPLACE "${CMAKE_SHARED_LIBRARY_SUFFIX}\$" "" LIBNAME ${LIBNAME})
endif()
set(${OUTPUT_VARIABLE} ${LIBNAME} PARENT_SCOPE)
endfunction(get_linker_name)
# Converts the result of resolve_cmake_library_list() into a "link line" ready to be passed to gcc or ld, and a
# list of directories to add to the search path.
macro(resolved_lib_list_to_link_line LINK_LINE_VAR DIRS_VAR) # ARGN: LIB_PATH_LIST
set(${LINK_LINE_VAR} "")
set(${DIRS_VAR} "")
foreach(LIBRARY ${ARGN})
if("${LIBRARY}" MATCHES "^${LINKER_FLAG_PREFIX}")
# linker flag -- put in library list to preserve ordering
list(APPEND ${LINK_LINE_VAR} "${LIBRARY}")
elseif("${LIBRARY}" MATCHES "(.+)\\.framework")
# OS X framework -- translate to "-framework" linker flag
get_filename_component(FRAMEWORK_BASENAME "${LIBRARY}" NAME_WE)
string(TOLOWER "${FRAMEWORK_BASENAME}" FRAMEWORK_BASENAME_LCASE)
list(APPEND ${LINK_LINE_VAR} "-framework" "${FRAMEWORK_BASENAME_LCASE}")
elseif(EXISTS "${LIBRARY}")
if(NOT IS_DIRECTORY "${LIBRARY}")
# full path to library
get_filename_component(LIB_DIR ${LIBRARY} DIRECTORY)
list(APPEND ${DIRS_VAR} ${LIB_DIR})
get_linker_name("${LIBRARY}" LIB_LINK_NAME)
list(APPEND ${LINK_LINE_VAR} "-l${LIB_LINK_NAME}")
endif()
else()
# target built by this project
list(APPEND ${LINK_LINE_VAR} "-l${LIBRARY}")
endif()
endforeach()
list(REMOVE_DUPLICATES ${DIRS_VAR})
endmacro(resolved_lib_list_to_link_line)
# import functions
# --------------------------------------------------------------------
# Shorthand for setting up a CMake imported target for a library file, with a path and include directories.
# After calling this function, using NAME in a library list will tell CMake to link to the provided file, and add the provided include directories.
# Automatically adds the library to the library tracker.
#usage: import_library(<library name> <library path> [include dir 1] [include dir 2]...)
function(import_library NAME PATH) #3rd arg: INCLUDE_DIRS
#Try to figure out whether it is shared or static.
get_lib_type(${PATH} LIB_TYPE)
if("${LIB_TYPE}" STREQUAL "SHARED")
add_library(${NAME} SHARED IMPORTED GLOBAL)
else()
add_library(${NAME} STATIC IMPORTED GLOBAL)
endif()
set_property(TARGET ${NAME} PROPERTY IMPORTED_LOCATION ${PATH})
set_property(TARGET ${NAME} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${ARGN})
endfunction(import_library)
# Shorthand for adding one library target which corresponds to multiple linkable things.
# "linkable things" can be any of 6 different types:
# 1. CMake imported targets (as created by import_library() or by another module)
# 2. File paths to libraries
# 3. CMake non-imported targets
# 4. Linker flags
# 5. Names of libraries to find on the linker path
# 6. Generator expressions
# Things of the first 2 types are added to the library tracker.
#usage: import_libraries(<library name> LIBRARIES <library paths...> INCLUDES [<include dirs...>])
function(import_libraries NAME)
cmake_parse_arguments(IMP_LIBS "" "" "LIBRARIES;INCLUDES" ${ARGN})
if("${IMP_LIBS_LIBRARIES}" STREQUAL "")
message(FATAL_ERROR "Incorrect usage. At least one LIBRARY should be provided.")
endif()
if(NOT "${IMP_LIBS_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Incorrect usage. Extra arguments provided.")
endif()
# we actually don't use imported libraries at all; we just create an interface target and set its dependencies
add_library(${NAME} INTERFACE)
set_property(TARGET ${NAME} PROPERTY INTERFACE_LINK_LIBRARIES ${IMP_LIBS_LIBRARIES})
set_property(TARGET ${NAME} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${IMP_LIBS_INCLUDES})
endfunction(import_libraries)

View File

@ -0,0 +1,219 @@
#[=======================================================================[.rst:
TryLinkLibrary
------------------
Check if a library works and is linkable using the current compiler. This works by compiling and linking an executable file that calls one of the library's functions.
TryLinkLibrary was designed as an upgraded replacement for the modules CheckLibraryExists and CheckC(XX)SourceCompiles. It can replace any existing usage of these modules with a more convenient and flexible syntax. It can also handle other situations, such as Fortran code and Windows DLLs. Last but not least, it can work with imported and interface targets in its LIBRARIES, so it's compatible with newer find modules that only provide imported targets.
By default, source code for a void no-argument function prototype is generated according to the function name and then called in the test code. This will work for most cases, but breaks in certain scenarios:
- DLL imports/exports on Windows. This requires the function to be declared with a specific prefix, like "extern" or "extern __declspec(dllimport)". Use the FUNC_PREFIX option to set this.
- C++ mangling. C++ functions have different symbol names based on their arguments and return type. For C++, use the FUNC_DECLARATION and FUNC_CALL options to specify custom blocks of code for this.
- Fortran modules. Requires a seperate use statement and then a function call. Use FUNC_CALL to provide code for this.
.. command:: try_link_library
.. code-block:: cmake
try_link_library(<result var>
LANGUAGE <C|CXX|Fortran>
FUNCTION <function name>
[LIBRARIES <library paths...>]
[INCLUDES <include paths...>]
[FUNC_PREFIX <prefix>]
[FUNC_DECLARATION <declaration code>]
[FUNC_CALL <calling code>])
::
<result var> - Name of cache variable to store result in. Gets set to TRUE or FALSE.
LANGUAGE - Language to perform the check in. Important so that mangling is done correctly.
FUNCTION - Name of function in the library to attempt to call. If both FUNC_DECLARATION and FUNC_CALL are provided, then this will only be used for status messages.
LIBRARIES - Library paths and imported targets to link when doing this check.
INCLUDES - Include paths for headers/modules that are used in the check.
FUNC_PREFIX - Optional code to put before the start of the function declaration in C and CXX.
FUNC_DECLARATION - Optional code to use in place of the default function declaration in C and CXX. Must prepare the named function to be called later in the code. Can be multiline. Can also include the library's header if that is easier to work with.
FUNC_CALL - Optional code to use to call the function. Can be multiline. NOTE: CMake argument passing weirdness prevents a trailing semicolon from being passed in FUNC_CALL. For C and C++, a trailing semicolon is added to the code passed.
Under some conditions, if it appears that nonexistant libraries were passed to the LIBRARIES argument or nonexistant directories were passed to INCLUDES, the check will immediately
report false since preceding code has clearly failed to find the needed libraries. This will happen if:
* A library is not a target and ends in -NOTFOUND
* A library is an imported target name (containing "::"), but does not currently exist
* An include ends in -NOTFOUND
The following variables may be set before calling this macro to modify
the way the check is run:
::
CMAKE_REQUIRED_FLAGS = string of compile command line flags
CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
CMAKE_REQUIRED_LINK_OPTIONS = list of options to pass to link command
CMAKE_REQUIRED_LIBRARIES = list of additonal libraries to link
CMAKE_REQUIRED_QUIET = execute quietly without messages
CMAKE_POSITION_INDEPENDENT_CODE = whether to compile a position independent executable (and therefore require the checked libraries to be position independent)
#]=======================================================================]
function(try_link_library RESULT_VAR)
if(DEFINED "${RESULT_VAR}")
# already in cache
return()
endif()
# Parse arguments
# ----------------------------------------------------------
# NOTE: FUNC_DECLARATION and FUNC_CALL must be listed as multi-value arguments in order to allow code containing semicolons
cmake_parse_arguments(TLL "" "LANGUAGE;FUNCTION;FUNC_PREFIX" "LIBRARIES;INCLUDES;FUNC_DECLARATION;FUNC_CALL" ${ARGN})
if("${TLL_LANGUAGE}" STREQUAL "" OR "${TLL_FUNCTION}" STREQUAL "")
message(FATAL_ERROR "Usage error: required arguments missing.")
endif()
if(NOT "${TLL_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Usage error: extra or unparsed arguments provided.")
endif()
if(NOT ("${TLL_LANGUAGE}" STREQUAL "C" OR "${TLL_LANGUAGE}" STREQUAL "CXX" OR "${TLL_LANGUAGE}" STREQUAL "Fortran"))
message(FATAL_ERROR "Usage error: unsupported LANGUAGE.")
endif()
if(NOT "${CMAKE_${TLL_LANGUAGE}_COMPILER_LOADED}")
message(FATAL_ERROR "Error: no compiler for ${TLL_LANGUAGE} has been loaded.")
endif()
# Write source file
# ----------------------------------------------------------
if("${TLL_LANGUAGE}" STREQUAL "C")
set(SOURCE_EXTENSION ".c")
elseif("${TLL_LANGUAGE}" STREQUAL "CXX")
set(SOURCE_EXTENSION ".cpp")
elseif("${TLL_LANGUAGE}" STREQUAL "Fortran")
set(SOURCE_EXTENSION ".F90")
endif()
set(SOURCE_FILE_PATH "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/TryLinkLibrary${SOURCE_EXTENSION}")
if("${TLL_LANGUAGE}" STREQUAL "Fortran")
if("${TLL_FUNC_CALL}" STREQUAL "")
set(TLL_FUNC_CALL "call ${TLL_FUNCTION}()")
endif()
file(WRITE ${SOURCE_FILE_PATH}
"program testf
${TLL_FUNC_CALL}
end program testf
")
else() # C or CXX
if("${TLL_FUNC_DECLARATION}" STREQUAL "")
set(TLL_FUNC_DECLARATION "void ${TLL_FUNCTION}();")
endif()
if("${TLL_FUNC_CALL}" STREQUAL "")
set(TLL_FUNC_CALL "${TLL_FUNCTION}()")
endif()
file(WRITE ${SOURCE_FILE_PATH} "
${TLL_FUNC_PREFIX} ${TLL_FUNC_DECLARATION}
int main(int argc, char** args)
{
${TLL_FUNC_CALL};
return 0;
}")
endif()
# Gather libraries
# ----------------------------------------------------------
set(ALL_LIBRARIES ${TLL_LIBRARIES} ${CMAKE_REQUIRED_LIBRARIES})
# convert library targets to paths
resolve_cmake_library_list(ALL_LIBRARY_PATHS ${ALL_LIBRARIES})
# check for missing libraries
set(MISSING_LIBRARIES FALSE)
foreach(LIBRARY ${ALL_LIBRARY_PATHS})
if("${LIBRARY}" MATCHES "-NOTFOUND$")
set(MISSING_LIBRARIES TRUE)
elseif(NOT EXISTS "${LIBRARY}")
# resolved library is not a full path, so it must be a target or a library to be linked with -l
if("${LIBRARY}" MATCHES "::")
# library has an imported target name. Passing an unresolved target with this name to try_compile would cause a
# cmake error, so we have to bail out here.
set(MISSING_LIBRARIES TRUE)
endif()
endif()
endforeach()
# Also check for NOTFOUND includes
foreach(INCLUDE ${TLL_INCLUDES})
if("${INCLUDE}" MATCHES "-NOTFOUND$")
set(MISSING_LIBRARIES TRUE)
endif()
endforeach()
if(MISSING_LIBRARIES)
set(${RESULT_VAR} FALSE PARENT_SCOPE)
return()
endif()
# generate message text
set(LIBRARY_MESSAGE_TEXT "")
foreach(LIBRARY ${ALL_LIBRARY_PATHS})
get_filename_component(LIBRARY_FILENAME ${LIBRARY} NAME)
string(APPEND LIBRARY_MESSAGE_TEXT " ${LIBRARY_FILENAME}")
endforeach()
# Compile the code
# ----------------------------------------------------------
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for ${TLL_FUNCTION} in${LIBRARY_MESSAGE_TEXT}")
endif()
try_compile(${RESULT_VAR}
${CMAKE_BINARY_DIR}
SOURCES ${SOURCE_FILE_PATH}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
LINK_LIBRARIES ${ALL_LIBRARY_PATHS}
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES=${TLL_INCLUDES}"
OUTPUT_VARIABLE TRY_COMPILE_OUTPUT)
if(${RESULT_VAR})
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for ${TLL_FUNCTION} in${LIBRARY_MESSAGE_TEXT} - found")
endif()
# update docstring and type
set(${RESULT_VAR} TRUE CACHE INTERNAL "Have function ${TLL_FUNCTION} in${LIBRARY_MESSAGE_TEXT}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the function ${TLL_FUNCTION} exists in${LIBRARY_MESSAGE_TEXT} "
"passed with the following output:\n"
"${TRY_COMPILE_OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for ${TLL_FUNCTION} in${LIBRARY_MESSAGE_TEXT} - not found")
message(STATUS "Detailed information about why this check failed can be found in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log")
endif()
# update docstring and type
set(${RESULT_VAR} FALSE CACHE INTERNAL "Have function ${TLL_FUNCTION} in library ${TLL_NAME}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the function ${TLL_FUNCTION} exists in the library ${TLL_NAME} "
"failed with the following output:\n"
"${TRY_COMPILE_OUTPUT}\n\n")
endif()
endfunction(try_link_library)

View File

@ -21,41 +21,16 @@
# Based heavily upon the libftdi cmake setup.
cmake_minimum_required(VERSION 2.8)
project(hackrf-tools C)
project(hackrf-tools LANGUAGES C)
# configure release definition
set(PACKAGE hackrf-tools)
include(${PROJECT_SOURCE_DIR}/../cmake/set_release.cmake)
include(set_release)
add_definitions(-DTOOL_RELEASE="${RELEASE}")
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake/modules)
if(MSVC)
include_directories(getopt)
add_definitions(/D _CRT_SECURE_NO_WARNINGS)
else()
add_definitions(-Wall)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90")
endif()
if(NOT libhackrf_SOURCE_DIR)
find_package(LIBHACKRF REQUIRED)
include_directories(${LIBHACKRF_INCLUDE_DIR})
else()
include_directories(${libhackrf_SOURCE_DIR}/src)
include_directories(getopt)
endif()
add_subdirectory(src)
########################################################################
# Create uninstall target
########################################################################
if(NOT HackRF_SOURCE_DIR)
configure_file(
${PROJECT_SOURCE_DIR}/../cmake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
@ONLY)
add_custom_target(uninstall
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
)
endif()

View File

@ -21,12 +21,7 @@
# Based heavily upon the libftdi cmake setup.
set(INSTALL_DEFAULT_BINDIR "bin" CACHE STRING "Appended to CMAKE_INSTALL_PREFIX")
find_package(FFTW REQUIRED)
include_directories(${FFTW_INCLUDES})
get_filename_component(FFTW_LIBRARY_DIRS ${FFTW_LIBRARIES} DIRECTORY)
link_directories(${FFTW_LIBRARY_DIRS})
SET(TOOLS
hackrf_transfer
@ -39,23 +34,14 @@ SET(TOOLS
hackrf_operacake
)
set(TOOLS_LINK_LIBS C::Math fftw::fftw hackrf)
if(MSVC)
# use getopt support library
add_library(libgetopt_static STATIC
../getopt/getopt.c
)
LIST(APPEND TOOLS_LINK_LIBS ${FFTW_LIBRARIES})
else()
LIST(APPEND TOOLS_LINK_LIBS m fftw3f)
endif()
if(NOT libhackrf_SOURCE_DIR)
include_directories(${LIBHACKRF_INCLUDE_DIR})
LIST(APPEND TOOLS_LINK_LIBS ${LIBHACKRF_LIBRARIES})
else()
LIST(APPEND TOOLS_LINK_LIBS hackrf)
endif()
if(MSVC)
LIST(APPEND TOOLS_LINK_LIBS libgetopt_static)
endif()

View File

@ -45,8 +45,8 @@ typedef int bool;
#endif
#ifdef _WIN32
#define _USE_MATH_DEFINES
#include <windows.h>
#include <winsock.h>
#ifdef _MSC_VER
#ifdef _WIN64

View File

@ -44,6 +44,7 @@ typedef int bool;
#ifdef _WIN32
#include <windows.h>
#include <winsock.h>
#ifdef _MSC_VER

View File

@ -20,36 +20,16 @@
#
# Based heavily upon the libftdi cmake setup.
project(libhackrf LANGUAGES C VERSION 0.6)
cmake_minimum_required(VERSION 2.8)
project(libhackrf C)
set(MAJOR_VERSION 0)
set(MINOR_VERSION 6)
# configure definitions for library version and release
set(PACKAGE libhackrf)
set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION})
set(VERSION ${VERSION_STRING})
add_definitions(-DLIBRARY_VERSION="${VERSION_STRING}")
include(${PROJECT_SOURCE_DIR}/../cmake/set_release.cmake)
add_definitions(-DLIBRARY_VERSION="${libhackrf_VERSION}")
include(set_release)
add_definitions(-DLIBRARY_RELEASE="${RELEASE}")
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake/modules)
if(MSVC)
set(THREADS_USE_PTHREADS_WIN32 true)
else()
add_definitions(-Wall)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90")
INCLUDE(TestBigEndian)
TEST_BIG_ENDIAN(BIGENDIAN)
if(${BIGENDIAN})
add_definitions(-DHACKRF_BIG_ENDIAN)
endif(${BIGENDIAN})
endif()
find_package(USB1 REQUIRED)
find_package(Threads REQUIRED)
include_directories(${LIBUSB_INCLUDE_DIR} ${THREADS_PTHREADS_INCLUDE_DIR})
# build library
add_subdirectory(src)
########################################################################
@ -90,7 +70,7 @@ INSTALL(
)
########################################################################
# Create Pkg Config File
# Create udev rules for hackrf devices
########################################################################
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@ -152,17 +132,3 @@ else(SYSTEM_IS_LINUX)
message(STATUS "udev rules not supported on this platform. Hide this message via -DINSTALL_UDEV_RULES=Off")
endif(INSTALL_UDEV_RULES)
endif(SYSTEM_IS_LINUX)
########################################################################
# Create uninstall target
########################################################################
if(NOT HackRF_SOURCE_DIR)
configure_file(
${PROJECT_SOURCE_DIR}/../cmake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
@ONLY)
add_custom_target(uninstall
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
)
endif()

View File

@ -23,59 +23,50 @@
# Based heavily upon the libftdi cmake setup.
# Targets
set(c_sources ${CMAKE_CURRENT_SOURCE_DIR}/hackrf.c CACHE INTERNAL "List of C sources")
set(c_headers ${CMAKE_CURRENT_SOURCE_DIR}/hackrf.h CACHE INTERNAL "List of C headers")
set(LIBHACKRF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/hackrf.c)
set(LIBHACKRF_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/hackrf.h)
# Dynamic library
add_library(hackrf SHARED ${c_sources})
set_target_properties(hackrf PROPERTIES VERSION ${MAJOR_VERSION}.${MINOR_VERSION}.0 SOVERSION 0)
add_library(hackrf SHARED ${LIBHACKRF_SOURCES})
set_target_properties(hackrf PROPERTIES VERSION ${libhackrf_VERSION} SOVERSION 0)
# Static library
add_library(hackrf-static STATIC ${c_sources})
if(MSVC)
add_library(hackrf-static STATIC ${LIBHACKRF_SOURCES})
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
# avoid .lib files with identical names
set_target_properties(hackrf-static PROPERTIES OUTPUT_NAME "hackrf_static")
else()
set_target_properties(hackrf-static PROPERTIES OUTPUT_NAME "hackrf")
endif()
# prevent cleaning one target from cleaning the other
set_target_properties(hackrf PROPERTIES CLEAN_DIRECT_OUTPUT 1)
set_target_properties(hackrf-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
# Dependencies
target_link_libraries(hackrf ${LIBUSB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(hackrf libusb pthread)
target_link_libraries(hackrf-static libusb pthread)
# For cygwin just force UNIX OFF and WIN32 ON
if( ${CYGWIN} )
SET(UNIX OFF)
SET(WIN32 ON)
endif( ${CYGWIN} )
# add DLL flag to dynamic version
target_compile_definitions(hackrf-static PUBLIC hackrf_STATIC)
# add interface include directories
target_include_directories(hackrf PUBLIC .)
target_include_directories(hackrf-static PUBLIC .)
# install DLL to bin and link library to lib
install(TARGETS hackrf
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
COMPONENT sharedlibs
)
install(TARGETS hackrf-static
DESTINATION bin
COMPONENT staticlibs
)
install(FILES ${LIBHACKRF_HEADERS}
DESTINATION include/${PROJECT_NAME}
COMPONENT headers
)
if( ${UNIX} )
install(TARGETS hackrf
LIBRARY DESTINATION lib${LIB_SUFFIX}
COMPONENT sharedlibs
)
install(TARGETS hackrf-static
ARCHIVE DESTINATION lib${LIB_SUFFIX}
COMPONENT staticlibs
)
install(FILES ${c_headers}
DESTINATION include/${PROJECT_NAME}
COMPONENT headers
)
endif( ${UNIX} )
if( ${WIN32} )
install(TARGETS hackrf
DESTINATION bin
COMPONENT sharedlibs
)
install(TARGETS hackrf-static
DESTINATION bin
COMPONENT staticlibs
)
install(FILES ${c_headers}
DESTINATION include/${PROJECT_NAME}
COMPONENT headers
)
endif( ${WIN32} )

View File

@ -27,13 +27,17 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI
#include <stdint.h>
#ifdef _WIN32
#define ADD_EXPORTS
/* You should define ADD_EXPORTS *only* when building the DLL. */
#ifdef ADD_EXPORTS
#define ADDAPI __declspec(dllexport)
/* users of the library should define hackrf_DLL when linking to it as a static library */
#ifdef hackrf_STATIC
#define ADDAPI
#else
#define ADDAPI __declspec(dllimport)
/* hackrf_EXPORTS is only defined by CMake when building. */
#ifdef hackrf_EXPORTS
#define ADDAPI __declspec(dllexport)
#else
#define ADDAPI __declspec(dllimport)
#endif
#endif
/* Define calling convention in one place, for convenience. */