/ cmake / module / AddBoostIfNeeded.cmake
AddBoostIfNeeded.cmake
 1  # Copyright (c) 2023-present The Bitcoin Core developers
 2  # Distributed under the MIT software license, see the accompanying
 3  # file COPYING or https://opensource.org/license/mit/.
 4  
 5  function(add_boost_if_needed)
 6    #[=[
 7    TODO: Not all targets, which will be added in the future, require
 8          Boost. Therefore, a proper check will be appropriate here.
 9  
10    Implementation notes:
11    Although only Boost headers are used to build Bitcoin Core,
12    we still leverage a standard CMake's approach to handle
13    dependencies, i.e., the Boost::headers "library".
14    A command target_link_libraries(target PRIVATE Boost::headers)
15    will propagate Boost::headers usage requirements to the target.
16    For Boost::headers such usage requirements is an include
17    directory and other added INTERFACE properties.
18    ]=]
19  
20    if(CMAKE_HOST_APPLE)
21      find_program(HOMEBREW_EXECUTABLE brew)
22      if(HOMEBREW_EXECUTABLE)
23        execute_process(
24          COMMAND ${HOMEBREW_EXECUTABLE} --prefix boost
25          OUTPUT_VARIABLE Boost_ROOT
26          ERROR_QUIET
27          OUTPUT_STRIP_TRAILING_WHITESPACE
28        )
29      endif()
30    endif()
31  
32    find_package(Boost 1.74.0 REQUIRED CONFIG)
33    mark_as_advanced(Boost_INCLUDE_DIR boost_headers_DIR)
34    # Workaround for a bug in NetBSD pkgsrc.
35    # See https://gnats.netbsd.org/59856.
36    if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
37      get_filename_component(_boost_include_dir "${boost_headers_DIR}/../../../include/" ABSOLUTE)
38      if(_boost_include_dir MATCHES "^/usr/pkg/")
39        set_target_properties(Boost::headers PROPERTIES
40          INTERFACE_INCLUDE_DIRECTORIES ${_boost_include_dir}
41        )
42      endif()
43      unset(_boost_include_dir)
44    endif()
45    set_target_properties(Boost::headers PROPERTIES IMPORTED_GLOBAL TRUE)
46    target_compile_definitions(Boost::headers INTERFACE
47      # We don't use multi_index serialization.
48      BOOST_MULTI_INDEX_DISABLE_SERIALIZATION
49    )
50    if(DEFINED VCPKG_TARGET_TRIPLET)
51      # Workaround for https://github.com/microsoft/vcpkg/issues/36955.
52      target_compile_definitions(Boost::headers INTERFACE
53        BOOST_NO_USER_CONFIG
54      )
55    endif()
56  
57    # Prevent use of std::unary_function, which was removed in C++17,
58    # and will generate warnings with newer compilers for Boost
59    # older than 1.80.
60    # See: https://github.com/boostorg/config/pull/430.
61    set(CMAKE_REQUIRED_DEFINITIONS -DBOOST_NO_CXX98_FUNCTION_BASE)
62    get_target_property(CMAKE_REQUIRED_INCLUDES Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
63    set(CMAKE_REQUIRED_FLAGS ${working_compiler_werror_flag})
64    set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
65    include(CheckCXXSourceCompiles)
66    check_cxx_source_compiles("
67      #include <boost/config.hpp>
68      " NO_DIAGNOSTICS_BOOST_NO_CXX98_FUNCTION_BASE
69    )
70    if(NO_DIAGNOSTICS_BOOST_NO_CXX98_FUNCTION_BASE)
71      target_compile_definitions(Boost::headers INTERFACE
72        BOOST_NO_CXX98_FUNCTION_BASE
73      )
74    endif()
75  
76    # Some package managers, such as vcpkg, vendor Boost.Test separately
77    # from the rest of the headers, so we have to check for it individually.
78    if(BUILD_TESTS AND DEFINED VCPKG_TARGET_TRIPLET)
79      find_package(boost_included_unit_test_framework ${Boost_VERSION} EXACT REQUIRED CONFIG)
80    endif()
81  
82  endfunction()