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