From b072c44c08beb00fdcb510e1f2cbb9e73d88327a Mon Sep 17 00:00:00 2001 From: yangfl Date: Sat, 1 Jan 2022 15:25:35 +0800 Subject: [PATCH] Add CheckAtomic.cmake Sometimes linking against libatomic is required for atomic ops, if the platform doesn't support lock-free atomics. This is a fixup for #4556, which does not work as intended. --- CMakeLists.txt | 1 + cmake/CheckAtomic.cmake | 52 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 cmake/CheckAtomic.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 075913ae6..932f8bb69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,7 @@ endif() include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include(CheckSymbolExists) +include(CheckAtomic) check_symbol_exists(__i386 "" TARGET_ARCH_X86_i386) if(TARGET_ARCH_X86_i386) diff --git a/cmake/CheckAtomic.cmake b/cmake/CheckAtomic.cmake new file mode 100644 index 000000000..78c725708 --- /dev/null +++ b/cmake/CheckAtomic.cmake @@ -0,0 +1,52 @@ +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) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11") + check_cxx_source_compiles(" +#include +#include +std::atomic x (0); +int main() { + uint64_t i = x.load(std::memory_order_relaxed); + (void)i; + return 0; +} +" ${varname}) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) +endfunction(check_working_cxx_atomics) + +if(NOT DEFINED COMPILER_IS_GCC_COMPATIBLE) + if(MSVC OR APPLE) + set(COMPILER_IS_GCC_COMPATIBLE OFF) + else() + set(COMPILER_IS_GCC_COMPATIBLE ON) + endif() +endif() + +if(NOT COMPILER_IS_GCC_COMPATIBLE) + set(HAVE_ATOMICS_WITHOUT_LIB ON) +else() + # Check for 64 bit atomic operations. + # First check if atomics work without the library. + check_working_cxx_atomics(HAVE_ATOMICS_WITHOUT_LIB) + # If not, check if the library exists, and atomics work with it. + if(NOT HAVE_ATOMICS_WITHOUT_LIB) + check_library_exists(atomic __atomic_load_8 "" HAVE_LIBATOMICS) + mark_as_advanced(HAVE_LIBATOMICS) + if(NOT HAVE_LIBATOMICS) + message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.") + endif() + list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") + check_working_cxx_atomics(HAVE_ATOMICS_WITH_LIB) + if(NOT HAVE_ATOMICS_WITH_LIB) + message(FATAL_ERROR "Host compiler must support std::atomic!") + endif() + list(APPEND CMAKE_C_STANDARD_LIBRARIES "-latomic") + list(APPEND CMAKE_CXX_STANDARD_LIBRARIES "-latomic") + endif() +endif()