diff options
author | Michael Dickens <michael.dickens@ettus.com> | 2019-09-09 16:50:39 -0400 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-10-15 11:24:48 -0700 |
commit | 90f8cbc12fe674d373652657b61b8466dcbc3469 (patch) | |
tree | ae9c99fc657b3b25cd6fb4ed1e76a7c9e29056c7 /host/cmake/Modules | |
parent | ca7d9e14d1bd45a630a49e43836d80bcc7864b95 (diff) | |
download | uhd-90f8cbc12fe674d373652657b61b8466dcbc3469.tar.gz uhd-90f8cbc12fe674d373652657b61b8466dcbc3469.tar.bz2 uhd-90f8cbc12fe674d373652657b61b8466dcbc3469.zip |
cmake: add UHDBoost.cmake and use it for building UHD
Also install UHDBoost.cmake along with the CMake UHD find scripts, so
that it can be used by external modules. Tweak the UHDConfig.cmake
script so that, once installed, the new UHDBoost.cmake script is found.
Note that the project using UHD must first find UHD before trying to find
Boost. Also note that if the C++ standard is not set before UHDBoost is
loaded, it will be set to that currently used by UHD: C++14.
Diffstat (limited to 'host/cmake/Modules')
-rw-r--r-- | host/cmake/Modules/UHDBoost.cmake | 324 | ||||
-rw-r--r-- | host/cmake/Modules/UHDConfig.cmake.in | 4 |
2 files changed, 327 insertions, 1 deletions
diff --git a/host/cmake/Modules/UHDBoost.cmake b/host/cmake/Modules/UHDBoost.cmake new file mode 100644 index 000000000..5ebb4acef --- /dev/null +++ b/host/cmake/Modules/UHDBoost.cmake @@ -0,0 +1,324 @@ +# +# Copyright 2019 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +# The following variables can be defined external to this script. +# +# ENABLE_STATIC_LIBS : whether to enable static libraries, which will +# require static Boost libraries too. If not using static libraries, +# shared libraries will be used. The default is to use shared +# libraries, and this default will be used if this variable is not +# defined or if is it NO/OFF/FALSE. +# +# UHD_BOOST_REQUIRED_COMPONENTS : Boost components that are required +# for Boost_FOUND to be true. The linkage (shared or static) must be +# correct and the library must also be found. +# +# UHD_BOOST_OPTIONAL_COMPONENTS : Boost components that are +# optional. They do not impact Boost_FOUND. The linkage will still be +# honored, and the library must still be found for the return +# variables to be set. +# +# NOTE: If neither UHD_BOOST_REQUIRED_COMPONENTS and +# UHD_BOOST_OPTIONAL_COMPONENTS are defined and/or are empty, then +# this script just checked to see if the minimum required version of +# Boost can be found, and sets Boost_FOUND accordingly; all of the +# other return variables will be unset / undefined. +# +# UHD_BOOST_REQUIRED : Whether to set Boost required components as +# "required" during finding. If not specified, then defaults to +# TRUE. If REQUIRED is TRUE and Boost is not found, then this script +# will error out. Otherwise this script will not error out, and the +# variable Boost_FOUND will indicate whether a compatible version +# Boost was found or not. +# +# Upon find returning, the following variables will be set upon return +# of this script: +# +# Boost_FOUND : will be TRUE if all of the required Boost components +# are found with the correct linkage (static or shared); otherwise +# this variable will be FALSE unless there are no components specified +# in which case this variable will be unset. +# +# Boost_INCLUDE_DIRS : directories to use with 'include_directories', +# where the top-level "boost" directory is located for headers. +# +# Boost_LIBRARY_DIRS : directories for use in finding libraries; this +# variable is generally not used in favor of either (1) defining +# library names with the full path; or (2) using targets where the +# full path is defined already. This variable is probably deprecated. +# +# Boost_LIBRARIES : a list of found Boost libraries, each of which can +# be either (1) or (2) above; either will work with modern CMake. +# +######################################################################## +message(STATUS "") +message(STATUS "Checking for Boost version ${BOOST_MIN_VERSION} or greater") + +# unset return variables +unset(Boost_FOUND) +unset(Boost_INCLUDE_DIRS) +unset(Boost_LIBRARY_DIRS) +unset(Boost_LIBRARIES) + +# check whether to set REQUIRED or not +# if not set, default is to require Boost +if(NOT UHD_BOOST_REQUIRED) + # UHD_BOOST_REQUIRED is not set; use the default + set(UHD_BOOST_REQUIRED "REQUIRED") +elseif(UHD_BOOST_REQUIRED) + # UHD_BOOST_REQUIRED is set to TRUE/ON/1 + set(UHD_BOOST_REQUIRED "REQUIRED") +else() + # UHD_BOOST_REQUIRED is not set to TRUE/ON/1 + unset(UHD_BOOST_REQUIRED) +endif() + +# set this for verbosity during 'find' +# set(Boost_DEBUG TRUE) + +# verify we're looking for something +list(LENGTH UHD_BOOST_OPTIONAL_COMPONENTS UHD_BOOST_OPTIONAL_COMPONENTS_LEN) +list(LENGTH UHD_BOOST_REQUIRED_COMPONENTS UHD_BOOST_REQUIRED_COMPONENTS_LEN) +if(UHD_BOOST_OPTIONAL_COMPONENTS_LEN EQUAL 0 AND + UHD_BOOST_REQUIRED_COMPONENTS_LEN EQUAL 0) + # just see if Boost can be found + find_package(Boost ${BOOST_MIN_VERSION} QUIET ${UHD_BOOST_REQUIRED}) + if(Boost_FOUND) + message(STATUS "Boost version ${BOOST_MIN_VERSION} or greater - found") + else() + message(STATUS "Boost version ${BOOST_MIN_VERSION} or greater - not found") + endif() + return() +endif() + +# if the OS is MINGW and if 'thread' is in the list, change its name +if(MINGW) + list(FIND UHD_BOOST_REQUIRED_COMPONENTS "thread" THREAD_NDX) + if(NOT ${THREAD_NDX} EQUAL -1) + list(REMOVE_AT UHD_BOOST_REQUIRED_COMPONENTS ${THREAD_NDX}) + list(INSERT UHD_BOOST_REQUIRED_COMPONENTS ${THREAD_NDX} thread_win32) + endif() +endif() + +# if 'system' is in the list, make sure it comes last; sometimes this +# linkage makes a difference +list(FIND UHD_BOOST_REQUIRED_COMPONENTS "system" SYSTEM_NDX) +if(NOT ${SYSTEM_NDX} EQUAL -1) + list(REMOVE_AT UHD_BOOST_REQUIRED_COMPONENTS ${SYSTEM_NDX}) + list(APPEND UHD_BOOST_REQUIRED_COMPONENTS "system") +endif() + +# special library directory that's used by some Linux +if(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64") + list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix +endif(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64") + +# special Microsoft Visual C handling +if(MSVC) + set(BOOST_ALL_DYN_LINK "${BOOST_ALL_DYN_LINK}" CACHE BOOL "boost enable dynamic linking") + if(BOOST_ALL_DYN_LINK) + add_definitions(-DBOOST_ALL_DYN_LINK) #setup boost auto-linking in msvc + else(BOOST_ALL_DYN_LINK) + set(UHD_BOOST_REQUIRED_COMPONENTS) #empty components list for static link + endif(BOOST_ALL_DYN_LINK) +endif(MSVC) + +# Starting in CMake 3.15.0, if policy 'CMP0093' is available and set +# to 'NEW', then the Boost_VERSION will be returned as X.Y.Z (e.g., +# 1.70.0) instead of XXYYZZ (107000). The OLD policy is the default +# for now, but is deprecated and relevant code should be updated to +# the NEW policy format. This change matches the version format +# returned by Boost's CMake scripts. See also: +# https://cmake.org/cmake/help/v3.15/policy/CMP0093.html#policy:CMP0093 +# Tell FindBoost, if used, to report Boost_VERSION in X.Y.Z format. +# NOTE: This must be set -before- calling "find_package(Boost ...)". +# NOTE: This setting is for CMake scripts only; each language (e.g., +# C++) that uses Boost maintains its current format for the Boost +# version variable. +if(POLICY CMP0093) + cmake_policy(SET CMP0093 NEW) +endif() + +# if no CXX STANDARD is set, default to that required by UHD: c++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) + message(WARNING "\nC++ standard not yet set; setting to C++14.\n") +endif() + +# tell boost the linkage required +set(Boost_USE_STATIC_LIBS ${ENABLE_STATIC_LIBS}) +# temporarily explicitly enable or disable shared libraries, +# build-wise; this can be disabled on a case by case basis for each +# library built. +if(BUILD_SHARED_LIBS) + set(BUILD_SHARED_LIBS_SET TRUE) + set(OLD_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) +else() + set(BUILD_SHARED_LIBS_SET FALSE) +endif() +if(ENABLE_STATIC_LIBS) + set(BUILD_SHARED_LIBS FALSE) +else() + set(BUILD_SHARED_LIBS TRUE) +endif() + +if(${UHD_BOOST_OPTIONAL_COMPONENTS_LEN} GREATER 0) + message(STATUS " Looking for optional Boost components...") + find_package(Boost ${BOOST_MIN_VERSION} QUIET + OPTIONAL_COMPONENTS ${UHD_BOOST_OPTIONAL_COMPONENTS}) +endif() + +if(${UHD_BOOST_REQUIRED_COMPONENTS_LEN} GREATER 0) + message(STATUS " Looking for required Boost components...") + find_package(Boost ${BOOST_MIN_VERSION} QUIET + COMPONENTS ${UHD_BOOST_REQUIRED_COMPONENTS} ${UHD_BOOST_REQUIRED}) +endif() + +# restore BUILD_SHARED_LIBS, if set +if(BUILD_SHARED_LIBS_SET) + set(BUILD_SHARED_LIBS ${OLD_BUILD_SHARED_LIBS}) + unset(OLD_BUILD_SHARED_LIBS) +else() + unset(BUILD_SHARED_LIBS) +endif() + +if(NOT Boost_FOUND) + # Boost was not found + # clear out return variables, just in case + unset(Boost_VERSION) + unset(Boost_INCLUDE_DIRS) + unset(Boost_LIBRARY_DIRS) + unset(Boost_LIBRARIES) +else() + # Boost was found; do fixups and related tests / checks + + # fix the Boost_VERSION to be X.Y.Z if CMake version < 3.15 + if(CMAKE_VERSION VERSION_LESS 3.15) + set(Boost_VERSION "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") + endif() + + # generic fix for some linking issues with Boost 1.68.0 or newer. + if(NOT ${Boost_VERSION} VERSION_LESS 1.68.0) + message(STATUS " Enabling Boost Error Code Header Only") + add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY) + endif() + + # test for std::string_view in boost::asio only if we're using + # c++17 or later and Boost 1.68.0 or later. The default is to not + # use this feature. Boost 1.67.0 and earlier at best checked for + # and used std::experimental::string_view, which causes issues for + # some Boost & C++ versions ... so, just don't use it! + set(USE_STD_STRING_VIEW_IN_BOOST_ASIO FALSE) + if((NOT ${CMAKE_CXX_STANDARD} VERSION_LESS 17) AND + (NOT ${Boost_VERSION} VERSION_LESS 1.68.0)) + # boost::asio::string_view can fail in compiling or linking simple + # c++. This situation generally happens on for Boost 1.66 - 1.68 + # and macOS using Clang and -std=c++14 ... but it can occur in + # other situations, so just do a generic check. This issue seems + # to be fixed in Boost 1.70.0. + message(STATUS " Checking whether std::string_view works in boost::asio") + # unset the return variable, otherwise the compile doesn't take place! + unset(USE_STD_STRING_VIEW_IN_BOOST_ASIO) + # set various CheckCXXSourceCompiles variables + include(CheckCXXSourceCompiles) + # FindBoost compatibility variables: Boost_INCLUDE_DIRS + if(NOT Boost_INCLUDE_DIRS OR "${Boost_INCLUDE_DIRS}" STREQUAL "") + get_target_property(Boost_INCLUDE_DIRS Boost::headers INTERFACE_INCLUDE_DIRECTORIES) + endif() + # set the c++ standard to test using + set(CMAKE_REQUIRED_FLAGS "-std=c++${CMAKE_CXX_STANDARD} -I${Boost_INCLUDE_DIRS}") + # make this compile quite + set(CMAKE_REQUIRED_QUIET TRUE) + # disable Boost's use of std::experimental::string_view + set(CMAKE_REQUIRED_DEFINITIONS -DBOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW) + # Check if std::string_view works in boost::asio + check_cxx_source_compiles( + "#include <boost/asio/detail/string_view.hpp> + int main() + { boost::asio::string_view sv; }" + USE_STD_STRING_VIEW_IN_BOOST_ASIO + ) + # clear the various CheckCXXSourceCompiles variables + unset(CMAKE_REQUIRED_FLAGS) + unset(CMAKE_REQUIRED_QUIET) + unset(CMAKE_REQUIRED_DEFINITIONS) + endif() + # use std::string_view in boost::asio? + if(USE_STD_STRING_VIEW_IN_BOOST_ASIO) + message(STATUS " Enabling boost::asio use of std::string_view") + add_definitions(-DBOOST_ASIO_HAS_STD_STRING_VIEW) + else() + message(STATUS " Disabling boost::asio use of std::string_view") + add_definitions(-DBOOST_ASIO_DISABLE_STD_STRING_VIEW) + endif() + unset(USE_STD_STRING_VIEW_IN_BOOST_ASIO) + + # disable Boost's use of std::experimental::string_view + # works for Boost 1.67.0 and newer & doesn't hurt older + add_definitions(-DBOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW) + + # Boost 1.70.0's find cmake scripts don't always set the expected + # return variables. Replicate the commit that fixes that issue here: + # https://github.com/boostorg/boost_install/commit/cfa8d55250dfc2635e907e42da423e4eb540dee5 + if(Boost_FOUND AND (${Boost_VERSION} VERSION_EQUAL 1.70.0)) + message(STATUS " Enabling possible Boost 1.70.0 Fixes") + + # FindBoost compatibility variables: Boost_LIBRARIES, Boost_<C>_LIBRARY + if(NOT Boost_LIBRARIES OR "${Boost_LIBRARIES}" STREQUAL "") + set(Boost_LIBRARIES "") + foreach(dep IN LISTS UHD_BOOST_REQUIRED_COMPONENTS UHD_BOOST_OPTIONAL_COMPONENTS) + string(TOUPPER ${dep} _BOOST_DEP) + if(NOT Boost_${_BOOST_DEP}_FOUND) + status(WARNING " Boost component '${dep}' should have been found but somehow isn't listed as found. Ignoring and hoping for the best!") + endif() + list(APPEND Boost_LIBRARIES Boost::${dep}) + set(Boost_${_BOOST_DEP}_LIBRARY Boost::${dep}) + endforeach() + endif() + + # FindBoost compatibility variables: Boost_INCLUDE_DIRS + if(NOT Boost_INCLUDE_DIRS OR "${Boost_INCLUDE_DIRS}" STREQUAL "") + get_target_property(Boost_INCLUDE_DIRS Boost::headers INTERFACE_INCLUDE_DIRECTORIES) + endif() + + # FindBoost compatibility variables: Boost_LIBRARY_DIRS + if(NOT Boost_LIBRARY_DIRS OR "${Boost_LIBRARY_DIRS}" STREQUAL "") + set(Boost_LIBRARY_DIRS "") + foreach(dep IN LISTS UHD_BOOST_REQUIRED_COMPONENTS UHD_BOOST_OPTIONAL_COMPONENTS) + string(TOUPPER ${dep} _BOOST_DEP) + if(NOT Boost_${_BOOST_DEP}_FOUND) + status(WARNING " Boost component '${dep}' should have been found but somehow isn't listed as found. Ignoring and hoping for the best!") + endif() + if(Boost_USE_DEBUG_LIBS) + get_target_property(Boost_${dep}_LIBRARY Boost::${dep} IMPORTED_LOCATION_DEBUG) + else() + get_target_property(Boost_${dep}_LIBRARY Boost::${dep} IMPORTED_LOCATION_RELEASE) + endif() + get_filename_component(Boost_${dep}_LIBRARY_DIR ${Boost_${dep}_LIBRARY} DIRECTORY ABSOLUTE) + list(FIND Boost_LIBRARY_DIRS ${Boost_${dep}_LIBRARY_DIR} Boost_${dep}_LIBRARY_DIR_FOUND) + if(${Boost_${dep}_LIBRARY_DIR_FOUND} EQUAL -1) + list(APPEND Boost_LIBRARY_DIRS ${Boost_${dep}_LIBRARY_DIR}) + endif() + endforeach() + endif() + list(SORT Boost_LIBRARY_DIRS) + endif() + + message(STATUS " Boost version: ${Boost_VERSION}") + message(STATUS " Boost include directories: ${Boost_INCLUDE_DIRS}") + message(STATUS " Boost library directories: ${Boost_LIBRARY_DIRS}") + message(STATUS " Boost libraries: ${Boost_LIBRARIES}") +endif() + +if(Boost_FOUND) + message(STATUS "Looking for Boost version ${BOOST_MIN_VERSION} or greater - found") +else() + message(STATUS "Looking for Boost version ${BOOST_MIN_VERSION} or greater - not found") +endif() + +# unset some internal variables, if set +unset(Boost_LIBRARY_DIR) +unset(Boost_INCLUDE_DIR) diff --git a/host/cmake/Modules/UHDConfig.cmake.in b/host/cmake/Modules/UHDConfig.cmake.in index 30b0d92ff..299a8ef48 100644 --- a/host/cmake/Modules/UHDConfig.cmake.in +++ b/host/cmake/Modules/UHDConfig.cmake.in @@ -18,6 +18,9 @@ # ######################################################################## +# Allows us to use all .cmake files in this directory +list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}") + # set that this file was found, for use in GNU Radio's FindUHD.cmake. # Have to use the ENV, since this file might not allow CACHE changes. @@ -51,7 +54,6 @@ endif() list(APPEND UHD_INCLUDE_HINTS ${CMAKE_INSTALL_PREFIX}/include) list(APPEND UHD_LIBDIR_HINTS ${CMAKE_INSTALL_PREFIX}/lib) - # Search for static libs if so required if( UHD_USE_STATIC_LIBS ) set( _UHD_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) |