uhd/host/cmake/Modules/UHDBoost.cmake
Martin Anderseck 1af4625e84 cmake: Enable Ubuntu 26.04
These changes are required to build on Ubuntu 26.04 cleanly while still
maintaining backwards compatibility until Ubuntu 22.04.

- Set CMP0167 to NEW in UHD CMake paths that resolve Boost
- Scope policy changes with guard checks so older CMake versions remain
  compatible
- Ensure dependency resolution order applies policy before Boost
  discovery in package config
- Reduce CMake 3.30+ FindBoost policy warnings without breaking Ubuntu
  22.04-era toolchains
2026-08-03 12:55:00 +02:00

257 lines
11 KiB
CMake

#
# 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.
#
# Boost_*: Check the FindBoost CMake documentation. For example,
# Boost_USE_STATIC_LIBS can be set to require static libraries.
#
# 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 ${UHD_BOOST_MIN_VERSION} or greater")
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_GREATER_EQUAL "3.30")
# Policy automatically set to NEW in CMake 3.30 and later; not need to set it here again.
message(WARNING "Unnecessary policy check, remove this!")
elseif(POLICY CMP0167) # CMP0167 is available in CMake 3.30 and later
# Use upstream BoostConfig.cmake implementations instead of deprecated FindBoost module.
cmake_policy(SET CMP0167 NEW)
endif()
# 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 DEFINED 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 ${UHD_BOOST_MIN_VERSION} QUIET ${UHD_BOOST_REQUIRED})
if(Boost_FOUND)
message(STATUS "Boost version ${UHD_BOOST_MIN_VERSION} or greater - found")
else()
message(STATUS "Boost version ${UHD_BOOST_MIN_VERSION} or greater - not found")
endif()
return()
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)
if(VCPKG_TARGET_TRIPLET)
message(STATUS " VCPKG Libs")
string(FIND ${VCPKG_TARGET_TRIPLET} "static" vcpkg_check_static)
string(FIND ${VCPKG_TARGET_TRIPLET} "static-md" vcpkg_check_static_md)
if((NOT vcpkg_check_static EQUAL -1) AND vcpkg_check_static_md EQUAL -1)
# Statically linked CRT
message(STATUS " VCPKG static CRT triplet found. Configuring compiler flags.")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif((NOT vcpkg_check_static EQUAL -1) AND vcpkg_check_static_md EQUAL -1)
else(VCPKG_TARGET_TRIPLET)
set(BOOST_ALL_DYN_LINK "${BOOST_ALL_DYN_LINK}" CACHE BOOL "boost enable dynamic linking")
if(BOOST_ALL_DYN_LINK)
message(STATUS " Dynamic Libs")
add_definitions(-DBOOST_ALL_DYN_LINK) #setup boost auto-linking in msvc
else(BOOST_ALL_DYN_LINK)
message(STATUS " Static Libs")
endif(BOOST_ALL_DYN_LINK)
endif(VCPKG_TARGET_TRIPLET)
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++20
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 20)
message(WARNING "\nC++ standard not yet set; setting to C++20.\n")
endif()
if(${UHD_BOOST_OPTIONAL_COMPONENTS_LEN} GREATER 0)
message(STATUS " Looking for optional Boost components...")
find_package(Boost ${UHD_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 ${UHD_BOOST_MIN_VERSION} QUIET
COMPONENTS ${UHD_BOOST_REQUIRED_COMPONENTS} ${UHD_BOOST_REQUIRED})
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()
# 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)
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 ${UHD_BOOST_MIN_VERSION} or greater - found")
else()
message(STATUS "Looking for Boost version ${UHD_BOOST_MIN_VERSION} or greater - not found")
endif()
# Prefer the modern header-only Boost imported target when available, but keep
# the legacy alias for older FindBoost/CMake combinations.
if(TARGET Boost::headers AND NOT TARGET Boost::boost)
add_library(Boost::boost INTERFACE IMPORTED)
set_target_properties(Boost::boost PROPERTIES
INTERFACE_LINK_LIBRARIES Boost::headers
)
endif()
# unset some internal variables, if set
unset(Boost_LIBRARY_DIR)
unset(Boost_INCLUDE_DIR)