/ 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.73.0 REQUIRED CONFIG)
33    mark_as_advanced(Boost_INCLUDE_DIR boost_headers_DIR)
34    # Workaround for a bug in NetBSD pkgsrc.
35    # See: https://github.com/NetBSD/pkgsrc/issues/167.
36    if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
37      get_filename_component(_boost_include_dir "${boost_headers_DIR}/../../../include/" ABSOLUTE)
38      set_target_properties(Boost::headers PROPERTIES
39        INTERFACE_INCLUDE_DIRECTORIES ${_boost_include_dir}
40      )
41      unset(_boost_include_dir)
42    endif()
43    set_target_properties(Boost::headers PROPERTIES IMPORTED_GLOBAL TRUE)
44    target_compile_definitions(Boost::headers INTERFACE
45      # We don't use multi_index serialization.
46      BOOST_MULTI_INDEX_DISABLE_SERIALIZATION
47    )
48    if(DEFINED VCPKG_TARGET_TRIPLET)
49      # Workaround for https://github.com/microsoft/vcpkg/issues/36955.
50      target_compile_definitions(Boost::headers INTERFACE
51        BOOST_NO_USER_CONFIG
52      )
53    endif()
54  
55    # Prevent use of std::unary_function, which was removed in C++17,
56    # and will generate warnings with newer compilers for Boost
57    # older than 1.80.
58    # See: https://github.com/boostorg/config/pull/430.
59    set(CMAKE_REQUIRED_DEFINITIONS -DBOOST_NO_CXX98_FUNCTION_BASE)
60    get_target_property(CMAKE_REQUIRED_INCLUDES Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
61    set(CMAKE_REQUIRED_FLAGS ${working_compiler_werror_flag})
62    set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
63    include(CheckCXXSourceCompiles)
64    check_cxx_source_compiles("
65      #include <boost/config.hpp>
66      " NO_DIAGNOSTICS_BOOST_NO_CXX98_FUNCTION_BASE
67    )
68    if(NO_DIAGNOSTICS_BOOST_NO_CXX98_FUNCTION_BASE)
69      target_compile_definitions(Boost::headers INTERFACE
70        BOOST_NO_CXX98_FUNCTION_BASE
71      )
72    endif()
73  
74    # Some package managers, such as vcpkg, vendor Boost.Test separately
75    # from the rest of the headers, so we have to check for it individually.
76    if(BUILD_TESTS AND DEFINED VCPKG_TARGET_TRIPLET)
77      find_package(boost_included_unit_test_framework ${Boost_VERSION} EXACT REQUIRED CONFIG)
78    endif()
79  
80  endfunction()