1From cf168ae0b7bceab8432d096719b331f18428fe39 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]
21Signed-off-by: Khem Raj <raj.khem@gmail.com>
22---
23 CMakeLists.txt                  |  5 +++
24 cmake/modules/CheckAtomic.cmake | 69 +++++++++++++++++++++++++++++++++
25 2 files changed, 74 insertions(+)
26 create mode 100644 cmake/modules/CheckAtomic.cmake
27
28--- a/CMakeLists.txt
29+++ b/CMakeLists.txt
30@@ -935,7 +935,12 @@ endif()
31 if(WIN32)
32   set(SYSTEM_LIBS ${SYSTEM_LIBS} shlwapi.lib rpcrt4.lib)
33 else()
34+  # check if linking against libatomic is necessary
35+  include(CheckAtomic)
36   set(SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT})
37+  if(HAVE_CXX_ATOMIC_WITH_LIB OR HAVE_CXX_ATOMICS64_WITH_LIB)
38+    set(SYSTEM_LIBS ${SYSTEM_LIBS} atomic)
39+  endif()
40 endif()
41
42 add_library(${ROCKSDB_STATIC_LIB} STATIC ${SOURCES} ${BUILD_VERSION_CC})
43--- /dev/null
44+++ b/cmake/modules/CheckAtomic.cmake
45@@ -0,0 +1,69 @@
46+# Checks if atomic operations are supported natively or if linking against
47+# libatomic is needed.
48+
49+# Check inspired by LLVMs cmake/modules/CheckAtomic.cmake
50+
51+INCLUDE(CheckCXXSourceCompiles)
52+INCLUDE(CheckLibraryExists)
53+
54+function(check_working_cxx_atomics varname)
55+  set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
56+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
57+  CHECK_CXX_SOURCE_COMPILES("
58+#include <atomic>
59+std::atomic<int> x;
60+int main() {
61+  return x;
62+}
63+" ${varname})
64+  set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
65+endfunction(check_working_cxx_atomics)
66+
67+function(check_working_cxx_atomics64 varname)
68+  set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
69+  set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
70+  CHECK_CXX_SOURCE_COMPILES("
71+#include <atomic>
72+#include <cstdint>
73+std::atomic<uint64_t> x (0);
74+std::atomic<double> y (0);
75+int main() {
76+  uint64_t i = x.load(std::memory_order_relaxed);
77+  return int(y);
78+}
79+" ${varname})
80+  set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
81+endfunction(check_working_cxx_atomics64)
82+
83+# Check if atomics work without libatomic
84+check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
85+
86+if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
87+  check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
88+  if( HAVE_LIBATOMIC )
89+    list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
90+    check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
91+    if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
92+      message(FATAL_ERROR "Host compiler must support std::atomic!")
93+    endif()
94+  else()
95+    message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
96+  endif()
97+endif()
98+
99+# Check if 64bit atomics work without libatomic
100+check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
101+
102+if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
103+  check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
104+  if(HAVE_CXX_LIBATOMICS64)
105+    list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
106+    check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
107+    if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
108+      message(FATAL_ERROR "Host compiler must support std::atomic!")
109+    endif()
110+  else()
111+    message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
112+  endif()
113+endif()
114+
115