TestAppendRequiredLibraries.cmake raw

   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  include_guard(GLOBAL)
   6  
   7  # Illumos/SmartOS requires linking with -lsocket if
   8  # using getifaddrs & freeifaddrs.
   9  # See:
  10  # - https://github.com/limenka/limenka/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_DECL_GETIFADDRS TRUE PARENT_SCOPE)
  42    set(HAVE_DECL_FREEIFADDRS TRUE PARENT_SCOPE)
  43  endfunction()
  44  
  45  # Clang, when building for 32-bit,
  46  # and linking against libstdc++, requires linking with
  47  # -latomic if using the C++ atomic library.
  48  # Can be tested with: clang++ -std=c++20 test.cpp -m32
  49  #
  50  # Sourced from http://bugs.debian.org/797228
  51  function(test_append_atomic_library target)
  52    if (NOT TARGET ${target})
  53      message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}() called with non-existent target \"${target}\".")
  54    endif()
  55  
  56    set(check_atomic_source "
  57      #include <atomic>
  58      #include <cstdint>
  59      #include <chrono>
  60  
  61      using namespace std::chrono_literals;
  62  
  63      int main() {
  64        std::atomic<bool> lock{true};
  65        lock.exchange(false);
  66  
  67        std::atomic<std::chrono::seconds> t{0s};
  68        t.store(2s);
  69        auto t1 = t.load();
  70        t.compare_exchange_strong(t1, 3s);
  71  
  72        std::atomic<double> d{};
  73        d.store(3.14);
  74        auto d1 = d.load();
  75  
  76        std::atomic<int64_t> a{};
  77        int64_t v = 5;
  78        int64_t r = a.fetch_add(v);
  79        return static_cast<int>(r);
  80      }
  81    ")
  82  
  83    include(CheckCXXSourceCompiles)
  84    check_cxx_source_compiles("${check_atomic_source}" STD_ATOMIC_LINKS_WITHOUT_LIBATOMIC)
  85    if(NOT STD_ATOMIC_LINKS_WITHOUT_LIBATOMIC)
  86      include(CheckSourceCompilesWithFlags)
  87      check_cxx_source_compiles_with_flags("${check_atomic_source}" STD_ATOMIC_NEEDS_LINK_TO_LIBATOMIC
  88        LINK_LIBRARIES atomic
  89      )
  90      if(STD_ATOMIC_NEEDS_LINK_TO_LIBATOMIC)
  91        target_link_libraries(${target} INTERFACE atomic)
  92      else()
  93        message(FATAL_ERROR "Cannot figure out how to use std::atomic.")
  94      endif()
  95    endif()
  96  endfunction()
  97