TestAppendRequiredLibraries.cmake raw
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 include_guard(GLOBAL)
6
7 # Illumos/SmartOS requires linking with -lsocket if
8 # using getifaddrs & freeifaddrs.
9 # See:
10 # - https://github.com/bitcoin/bitcoin/pull/21486
11 # - https://smartos.org/man/3socket/getifaddrs
12 function(test_append_socket_library target)
13 if (NOT TARGET ${target})
14 message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}() called with non-existent target \"${target}\".")
15 endif()
16
17 set(check_socket_source "
18 #include <ifaddrs.h>
19
20 int main() {
21 struct ifaddrs* ifaddr;
22 getifaddrs(&ifaddr);
23 freeifaddrs(ifaddr);
24 }
25 ")
26
27 include(CheckCXXSourceCompiles)
28 check_cxx_source_compiles("${check_socket_source}" IFADDR_LINKS_WITHOUT_LIBSOCKET)
29 if(NOT IFADDR_LINKS_WITHOUT_LIBSOCKET)
30 include(CheckSourceCompilesWithFlags)
31 check_cxx_source_compiles_with_flags("${check_socket_source}" IFADDR_NEEDS_LINK_TO_LIBSOCKET
32 LINK_LIBRARIES socket
33 )
34 if(IFADDR_NEEDS_LINK_TO_LIBSOCKET)
35 target_link_libraries(${target} INTERFACE socket)
36 else()
37 message(FATAL_ERROR "Cannot figure out how to use getifaddrs/freeifaddrs.")
38 endif()
39 endif()
40 set(HAVE_IFADDRS TRUE PARENT_SCOPE)
41 endfunction()
42
43 # Clang, when building for 32-bit,
44 # and linking against libstdc++, requires linking with
45 # -latomic if using the C++ atomic library.
46 # Can be tested with: clang++ -std=c++20 test.cpp -m32
47 #
48 # Sourced from http://bugs.debian.org/797228
49 function(test_append_atomic_library target)
50 if (NOT TARGET ${target})
51 message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}() called with non-existent target \"${target}\".")
52 endif()
53
54 set(check_atomic_source "
55 #include <atomic>
56 #include <cstdint>
57 #include <chrono>
58
59 using namespace std::chrono_literals;
60
61 int main() {
62 std::atomic<bool> lock{true};
63 lock.exchange(false);
64
65 std::atomic<std::chrono::seconds> t{0s};
66 t.store(2s);
67 auto t1 = t.load();
68 t.compare_exchange_strong(t1, 3s);
69
70 std::atomic<double> d{};
71 d.store(3.14);
72 auto d1 = d.load();
73
74 std::atomic<int64_t> a{};
75 int64_t v = 5;
76 int64_t r = a.fetch_add(v);
77 return static_cast<int>(r);
78 }
79 ")
80
81 include(CheckCXXSourceCompiles)
82 check_cxx_source_compiles("${check_atomic_source}" STD_ATOMIC_LINKS_WITHOUT_LIBATOMIC)
83 if(NOT STD_ATOMIC_LINKS_WITHOUT_LIBATOMIC)
84 include(CheckSourceCompilesWithFlags)
85 check_cxx_source_compiles_with_flags("${check_atomic_source}" STD_ATOMIC_NEEDS_LINK_TO_LIBATOMIC
86 LINK_LIBRARIES atomic
87 )
88 if(STD_ATOMIC_NEEDS_LINK_TO_LIBATOMIC)
89 target_link_libraries(${target} INTERFACE atomic)
90 else()
91 message(FATAL_ERROR "Cannot figure out how to use std::atomic.")
92 endif()
93 endif()
94 endfunction()
95