1From 034a9c4ce2ae61cfcffa977f1eb8e6f68947f480 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2020 15:10:37 -0700
4Subject: [PATCH] cmake: Add check for atomic support
5
6Detect if libatomic should be linked in or compiler and platform can
7provide the needed atomic instrinsics, this helps build on certain
8platforms like mips or clang/i386
9
10Fixes
11
12| /mnt/b/yoe/build/tmp/work/mips32r2-yoe-linux/rocksdb/6.6.4-r0/recipe-sysroot-native/usr/bin/mips-yoe-linux/mips-yoe-linux-ld: librocksdb.so.6.6.4: undefined reference to `__atomic_exchange_8'
13| /mnt/b/yoe/build/tmp/work/mips32r2-yoe-linux/rocksdb/6.6.4-r0/recipe-sysroot-native/usr/bin/mips-yoe-linux/mips-yoe-linux-ld: librocksdb.so.6.6.4: undefined reference to `__atomic_fetch_or_8'
14| /mnt/b/yoe/build/tmp/work/mips32r2-yoe-linux/rocksdb/6.6.4-r0/recipe-sysroot-native/usr/bin/mips-yoe-linux/mips-yoe-linux-ld: librocksdb.so.6.6.4: undefined reference to `__atomic_compare_exchange_8'
15| /mnt/b/yoe/build/tmp/work/mips32r2-yoe-linux/rocksdb/6.6.4-r0/recipe-sysroot-native/usr/bin/mips-yoe-linux/mips-yoe-linux-ld: librocksdb.so.6.6.4: undefined reference to `__atomic_fetch_sub_8'
16| /mnt/b/yoe/build/tmp/work/mips32r2-yoe-linux/rocksdb/6.6.4-r0/recipe-sysroot-native/usr/bin/mips-yoe-linux/mips-yoe-linux-ld: librocksdb.so.6.6.4: undefined reference to `__atomic_load_8'
17| /mnt/b/yoe/build/tmp/work/mips32r2-yoe-linux/rocksdb/6.6.4-r0/recipe-sysroot-native/usr/bin/mips-yoe-linux/mips-yoe-linux-ld: librocksdb.so.6.6.4: undefined reference to `__atomic_store_8'
18| /mnt/b/yoe/build/tmp/work/mips32r2-yoe-linux/rocksdb/6.6.4-r0/recipe-sysroot-native/usr/bin/mips-yoe-linux/mips-yoe-linux-ld: librocksdb.so.6.6.4: undefined reference to `__atomic_fetch_add_8'
19
20Upstream-Status: Submitted [https://github.com/facebook/rocksdb/pull/6555]
21
22Signed-off-by: Khem Raj <raj.khem@gmail.com>
23---
24 CMakeLists.txt                  |  5 +++
25 cmake/modules/CheckAtomic.cmake | 69 +++++++++++++++++++++++++++++++++
26 2 files changed, 74 insertions(+)
27 create mode 100644 cmake/modules/CheckAtomic.cmake
28
29diff --git a/CMakeLists.txt b/CMakeLists.txt
30index 5cfc1b4803..0a7f820a22 100644
31--- a/CMakeLists.txt
32+++ b/CMakeLists.txt
33@@ -1038,7 +1038,12 @@ set(ROCKSDB_SHARED_LIB rocksdb-shared${ARTIFACT_SUFFIX})
34 if(WIN32)
35   set(SYSTEM_LIBS ${SYSTEM_LIBS} shlwapi.lib rpcrt4.lib)
36 else()
37+  # check if linking against libatomic is necessary
38+  include(CheckAtomic)
39   set(SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT})
40+  if(HAVE_CXX_ATOMIC_WITH_LIB OR HAVE_CXX_ATOMICS64_WITH_LIB)
41+    set(SYSTEM_LIBS ${SYSTEM_LIBS} atomic)
42+  endif()
43 endif()
44
45 set(ROCKSDB_PLUGIN_EXTERNS "")
46diff --git a/cmake/modules/CheckAtomic.cmake b/cmake/modules/CheckAtomic.cmake
47new file mode 100644
48index 0000000000..8b7dc8a377
49--- /dev/null
50+++ b/cmake/modules/CheckAtomic.cmake
51@@ -0,0 +1,69 @@
52+# Checks if atomic operations are supported natively or if linking against
53+# libatomic is needed.
54+
55+# Check inspired by LLVMs cmake/modules/CheckAtomic.cmake
56+
57+INCLUDE(CheckCXXSourceCompiles)
58+INCLUDE(CheckLibraryExists)
59+
60+function(check_working_cxx_atomics varname)
61+  set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
62+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
63+  CHECK_CXX_SOURCE_COMPILES("
64+#include <atomic>
65+std::atomic<int> x;
66+int main() {
67+  return x;
68+}
69+" ${varname})
70+  set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
71+endfunction(check_working_cxx_atomics)
72+
73+function(check_working_cxx_atomics64 varname)
74+  set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
75+  set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
76+  CHECK_CXX_SOURCE_COMPILES("
77+#include <atomic>
78+#include <cstdint>
79+std::atomic<uint64_t> x (0);
80+std::atomic<double> y (0);
81+int main() {
82+  uint64_t i = x.load(std::memory_order_relaxed);
83+  return int(y);
84+}
85+" ${varname})
86+  set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
87+endfunction(check_working_cxx_atomics64)
88+
89+# Check if atomics work without libatomic
90+check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
91+
92+if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
93+  check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
94+  if( HAVE_LIBATOMIC )
95+    list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
96+    check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
97+    if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
98+      message(FATAL_ERROR "Host compiler must support std::atomic!")
99+    endif()
100+  else()
101+    message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
102+  endif()
103+endif()
104+
105+# Check if 64bit atomics work without libatomic
106+check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
107+
108+if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
109+  check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
110+  if(HAVE_CXX_LIBATOMICS64)
111+    list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
112+    check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
113+    if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
114+      message(FATAL_ERROR "Host compiler must support std::atomic!")
115+    endif()
116+  else()
117+    message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
118+  endif()
119+endif()
120+
121--
1222.25.1
123
124