aboutsummaryrefslogtreecommitdiff
path: root/modules/CheckAtomic.cmake
diff options
context:
space:
mode:
authorSandro Knauß <sknauss@kde.org>2020-05-27 12:04:05 +0200
committerChristophe Giboudeaux <christophe@krop.fr>2020-09-24 19:02:22 +0000
commitec06322de7dab19a11fb649d0d1a7dc128b5f962 (patch)
tree2070c26e310d9b755229b65bc51a62c16e4a5374 /modules/CheckAtomic.cmake
parentfbc00bf4b570d7ec02c0855d5133dde38c5b91eb (diff)
downloadextra-cmake-modules-ec06322de7dab19a11fb649d0d1a7dc128b5f962.tar.gz
extra-cmake-modules-ec06322de7dab19a11fb649d0d1a7dc128b5f962.tar.bz2
Add CheckAtomic.cmake
Application need to test, if they need to build against atomic libray. In order to not duplicate the code over and over again, let's have one version in ecm.
Diffstat (limited to 'modules/CheckAtomic.cmake')
-rw-r--r--modules/CheckAtomic.cmake92
1 files changed, 92 insertions, 0 deletions
diff --git a/modules/CheckAtomic.cmake b/modules/CheckAtomic.cmake
new file mode 100644
index 00000000..900ae7e0
--- /dev/null
+++ b/modules/CheckAtomic.cmake
@@ -0,0 +1,92 @@
+#.rst:
+# CheckAtomic
+# -----------
+#
+# Check if the compiler supports std:atomic out of the box or if libatomic is
+# needed for atomic support. If it is needed libatomicis added to
+# CMAKE_REQUIRED_LIBRARIES. So after running CheckAtomic you can use
+# std:atomic.
+#
+# Since 5.XX.0.
+
+#=============================================================================
+# SPDX-FileCopyrightText: 2003-2018 University of Illinois at Urbana-Champaign.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#=============================================================================
+
+include(CheckCXXSourceCompiles)
+include(CheckLibraryExists)
+
+# Sometimes linking against libatomic is required for atomic ops, if
+# the platform doesn't support lock-free atomics.
+
+function(check_working_cxx_atomics varname)
+ set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
+ check_cxx_source_compiles("
+ #include <atomic>
+ std::atomic<int> x;
+ int main() {
+ return std::atomic_is_lock_free(&x);
+ }
+ " ${varname})
+ set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
+endfunction()
+
+function(check_working_cxx_atomics64 varname)
+ set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
+ check_cxx_source_compiles("
+ #include <atomic>
+ #include <cstdint>
+ std::atomic<uint64_t> x (0);
+ int main() {
+ uint64_t i = x.load(std::memory_order_relaxed);
+ return std::atomic_is_lock_free(&x);
+ }
+ " ${varname})
+ set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
+endfunction()
+
+
+# This isn't necessary on MSVC, so avoid command-line switch annoyance
+# by only running on GCC-like hosts.
+if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
+ # First check if atomics work without the library.
+ check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
+ # If not, check if the library exists, and atomics work with it.
+ if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
+ check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
+ if(HAVE_LIBATOMIC)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
+ check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
+ if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
+ message(FATAL_ERROR "Host compiler must support std::atomic!")
+ endif()
+ else()
+ message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
+ endif()
+ endif()
+endif()
+
+# Check for 64 bit atomic operations.
+if(MSVC)
+ set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
+else()
+ check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+endif()
+
+# If not, check if the library exists, and atomics work with it.
+if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+ check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
+ if(HAVE_CXX_LIBATOMICS64)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
+ check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
+ if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
+ message(FATAL_ERROR "Host compiler must support std::atomic!")
+ endif()
+ else()
+ message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
+ endif()
+endif()