aboutsummaryrefslogtreecommitdiffstats
path: root/host/cmake/Modules/UHDAtomics.cmake
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2021-08-25 11:14:30 +0200
committerAaron Rossetto <aaron.rossetto@ni.com>2021-08-27 15:28:20 -0500
commit2680025c1b8ac51812931d78b2e0a4777f8e1774 (patch)
tree67cb7ba42d2220fbf175ae791269e9977d454a7f /host/cmake/Modules/UHDAtomics.cmake
parent34b51b40f59412ae42e99246a60dd70de53ee180 (diff)
downloaduhd-2680025c1b8ac51812931d78b2e0a4777f8e1774.tar.gz
uhd-2680025c1b8ac51812931d78b2e0a4777f8e1774.tar.bz2
uhd-2680025c1b8ac51812931d78b2e0a4777f8e1774.zip
cmake: Add check for libatomic linking requirement
Some archs require linking against libatomic, others don't. We add some CMake code that checks for libatomic.so requirement if: - We are not on MSVC, AND - Compiling std::atomics code would cause a linker error. We then check for the existence of libatomic.so, and fail if we can't find it.
Diffstat (limited to 'host/cmake/Modules/UHDAtomics.cmake')
-rw-r--r--host/cmake/Modules/UHDAtomics.cmake80
1 files changed, 80 insertions, 0 deletions
diff --git a/host/cmake/Modules/UHDAtomics.cmake b/host/cmake/Modules/UHDAtomics.cmake
new file mode 100644
index 000000000..4d53a2d0b
--- /dev/null
+++ b/host/cmake/Modules/UHDAtomics.cmake
@@ -0,0 +1,80 @@
+#
+# This file is mostly inspired by
+# https://github.com/llvm-mirror/llvm/blob/master/cmake/modules/CheckAtomic.cmake
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+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)
+ CHECK_CXX_SOURCE_COMPILES("
+ #include <atomic>
+ std::atomic<int> x;
+ int main() {
+ return x;
+ }
+ " ${varname})
+endfunction(CHECK_WORKING_CXX_ATOMICS)
+
+function(CHECK_WORKING_CXX_ATOMICS64 varname)
+ 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 0;
+ }
+ " ${varname})
+endfunction(CHECK_WORKING_CXX_ATOMICS64)
+
+macro(CHECK_ATOMICS_LIB_REQUIRED required_var)
+ set(${required_var} FALSE)
+ if(MSVC)
+ set(${required_var} FALSE)
+ else()
+ # 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)
+ set(${required_var} TRUE)
+ set(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()
+ unset(CMAKE_REQUIRED_LIBRARIES)
+ else()
+ message(
+ FATAL_ERROR
+ "Host compiler appears to require libatomic, but cannot find it.")
+ endif()
+ endif()
+ # Same check, but for 64-bit atomics.
+ CHECK_WORKING_CXX_ATOMICS64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+ # 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)
+ set(${required_var} TRUE)
+ set(CMAKE_REQUIRED_LIBRARIES "atomic")
+ CHECK_WORKING_CXX_ATOMICS64(HAVE_CXX_ATOMICS64_WITH_LIB)
+ unset(CMAKE_REQUIRED_LIBRARIES)
+ if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
+ message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
+ endif()
+ else()
+ message(
+ FATAL_ERROR
+ "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
+ endif()
+ endif()
+ endif()
+endmacro(CHECK_ATOMICS_LIB_REQUIRED)