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