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