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