diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake index bb5d9cbee7b20..c4d4c9a24a139 100644 --- a/cmake/introspection.cmake +++ b/cmake/introspection.cmake @@ -81,6 +81,9 @@ if(HAVE_SYS_TYPES_H AND HAVE_IFADDRS_H) endif() endif() +include(TestAppendRequiredLibraries) +test_append_atomic_library(core) + # Check for gmtime_r(), fallback to gmtime_s() if that is unavailable. # Fail if neither are available. check_cxx_source_compiles(" diff --git a/cmake/module/TestAppendRequiredLibraries.cmake b/cmake/module/TestAppendRequiredLibraries.cmake index 936e55b662ca8..c6dc93742a519 100644 --- a/cmake/module/TestAppendRequiredLibraries.cmake +++ b/cmake/module/TestAppendRequiredLibraries.cmake @@ -32,3 +32,46 @@ function(test_append_socket_library target) message(FATAL_ERROR "Cannot figure out how to use getifaddrs/freeifaddrs.") endif() endfunction() + +# Clang prior to version 15, when building for 32-bit, +# and linking against libstdc++, requires linking with +# -latomic if using the C++ atomic library. +# Can be tested with: clang++ test.cpp -m32 +# +# Sourced from http://bugs.debian.org/797228 +function(test_append_atomic_library target) + set(check_atomic_source " + #include + #include + #include + + using namespace std::chrono_literals; + + int main() { + std::atomic lock{true}; + lock.exchange(false); + + std::atomic t{0s}; + t.store(2s); + + std::atomic a{}; + + int64_t v = 5; + int64_t r = a.fetch_add(v); + return static_cast(r); + } + ") + + include(CheckSourceCompilesAndLinks) + check_cxx_source_links("${check_atomic_source}" STD_ATOMIC_LINKS_WITHOUT_LIBATOMIC) + if(STD_ATOMIC_LINKS_WITHOUT_LIBATOMIC) + return() + endif() + + check_cxx_source_links_with_libs(atomic "${check_atomic_source}" STD_ATOMIC_NEEDS_LINK_TO_LIBATOMIC) + if(STD_ATOMIC_NEEDS_LINK_TO_LIBATOMIC) + target_link_libraries(${target} INTERFACE atomic) + else() + message(FATAL_ERROR "Cannot figure out how to use std::atomic.") + endif() +endfunction()