1 # Copyright (c) 2023-present The Limenka 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 if(BUILD_DAEMON)
7 elseif(BUILD_CLI)
8 # BUILD_LIMENKACONSENSUS_LIB does NOT require boost
9 elseif(BUILD_TX)
10 elseif(BUILD_UTIL)
11 elseif(BUILD_UTIL_CHAINSTATE)
12 elseif(BUILD_KERNEL_LIB)
13 elseif(BUILD_WALLET_TOOL)
14 elseif(BUILD_GUI)
15 elseif(BUILD_TESTS)
16 elseif(BUILD_GUI_TESTS)
17 elseif(BUILD_BENCH)
18 elseif(BUILD_FUZZ_BINARY)
19 else()
20 # No targets that require boost; but we still define them, so make a dummy "library"
21 add_library(Boost::headers INTERFACE IMPORTED)
22 return()
23 endif()
24 25 #[=[
26 TODO: Not all targets, which will be added in the future, require
27 Boost. Therefore, a proper check will be appropriate here.
28 29 Implementation notes:
30 Although only Boost headers are used to build Limenka,
31 we still leverage a standard CMake's approach to handle
32 dependencies, i.e., the Boost::headers "library".
33 A command target_link_libraries(target PRIVATE Boost::headers)
34 will propagate Boost::headers usage requirements to the target.
35 For Boost::headers such usage requirements is an include
36 directory and other added INTERFACE properties.
37 ]=]
38 39 if(CMAKE_HOST_APPLE)
40 find_program(HOMEBREW_EXECUTABLE brew)
41 if(HOMEBREW_EXECUTABLE)
42 execute_process(
43 COMMAND ${HOMEBREW_EXECUTABLE} --prefix boost
44 OUTPUT_VARIABLE Boost_ROOT
45 ERROR_QUIET
46 OUTPUT_STRIP_TRAILING_WHITESPACE
47 )
48 endif()
49 endif()
50 51 # We cannot rely on find_package(Boost ...) to work properly without
52 # Boost_NO_BOOST_CMAKE set until we require a more recent Boost because
53 # upstream did not ship proper CMake files until 1.82.0.
54 # Until then, we rely on CMake's FindBoost module.
55 # See: https://cmake.org/cmake/help/latest/policy/CMP0167.html
56 if(POLICY CMP0167)
57 cmake_policy(SET CMP0167 OLD)
58 endif()
59 set(Boost_NO_BOOST_CMAKE ON)
60 find_package(Boost 1.73.0 REQUIRED)
61 mark_as_advanced(Boost_INCLUDE_DIR)
62 set_target_properties(Boost::headers PROPERTIES IMPORTED_GLOBAL TRUE)
63 target_compile_definitions(Boost::headers INTERFACE
64 # We don't use multi_index serialization.
65 BOOST_MULTI_INDEX_DISABLE_SERIALIZATION
66 )
67 if(DEFINED VCPKG_TARGET_TRIPLET)
68 # Workaround for https://github.com/microsoft/vcpkg/issues/36955.
69 target_compile_definitions(Boost::headers INTERFACE
70 BOOST_NO_USER_CONFIG
71 )
72 endif()
73 74 # Prevent use of std::unary_function, which was removed in C++17,
75 # and will generate warnings with newer compilers for Boost
76 # older than 1.80.
77 # See: https://github.com/boostorg/config/pull/430.
78 set(CMAKE_REQUIRED_DEFINITIONS -DBOOST_NO_CXX98_FUNCTION_BASE)
79 set(CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIR})
80 include(CMakePushCheckState)
81 cmake_push_check_state()
82 include(TryAppendCXXFlags)
83 set(CMAKE_REQUIRED_FLAGS ${working_compiler_werror_flag})
84 set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
85 check_cxx_source_compiles("
86 #include <boost/config.hpp>
87 " NO_DIAGNOSTICS_BOOST_NO_CXX98_FUNCTION_BASE
88 )
89 cmake_pop_check_state()
90 if(NO_DIAGNOSTICS_BOOST_NO_CXX98_FUNCTION_BASE)
91 target_compile_definitions(Boost::headers INTERFACE
92 BOOST_NO_CXX98_FUNCTION_BASE
93 )
94 else()
95 set(CMAKE_REQUIRED_DEFINITIONS)
96 endif()
97 98 # Some package managers, such as vcpkg, vendor Boost.Test separately
99 # from the rest of the headers, so we have to check for it individually.
100 if(BUILD_TESTS AND DEFINED VCPKG_TARGET_TRIPLET)
101 list(APPEND CMAKE_REQUIRED_DEFINITIONS -DBOOST_TEST_NO_MAIN)
102 include(CheckIncludeFileCXX)
103 check_include_file_cxx(boost/test/included/unit_test.hpp HAVE_BOOST_INCLUDED_UNIT_TEST_H)
104 if(NOT HAVE_BOOST_INCLUDED_UNIT_TEST_H)
105 message(FATAL_ERROR "Building test_limenka executable requested but boost/test/included/unit_test.hpp header not available.")
106 endif()
107 endif()
108 109 endfunction()
110