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