From a18bfe9c156be16f231e0bb380fc70fad22da20c Mon Sep 17 00:00:00 2001 From: Ken Haase Date: Fri, 14 Feb 2020 10:18:53 -0500 Subject: Added atomic check for building on ARMs (#1196) --- CMakeLists.txt | 7 +++++ cmake/CheckAtomicLib.cmake | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 cmake/CheckAtomicLib.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 70177449..d71e72b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -148,6 +148,13 @@ if (NOT NNG_SANITIZER STREQUAL "none") set(NNG_SANITIZER_FLAGS "-fsanitize=${NNG_SANITIZER}") endif () +include(CheckAtomicLib) +CheckAtomicLib() +if (NOT HAVE_C_ATOMICS_WITHOUT_LIB AND HAVE_C_ATOMICS_WITH_LIB) + list(APPEND NNG_LIBS "atomic") +endif () + + if (NNG_ENABLE_COVERAGE) # NB: This only works for GCC and Clang 3.0 and newer. If your stuff # is older than that, you will need to find something newer. For diff --git a/cmake/CheckAtomicLib.cmake b/cmake/CheckAtomicLib.cmake new file mode 100644 index 00000000..06979305 --- /dev/null +++ b/cmake/CheckAtomicLib.cmake @@ -0,0 +1,70 @@ +# +# Copyright 2020 Kenneth Haase +# +# This software is supplied under the terms of the MIT License, a +# copy of which should be located in the distribution where this +# file was obtained (LICENSE.txt). A copy of the license may also be +# found online at https://opensource.org/licenses/MIT. +# + +# atomic builtins are required for threading support. + +INCLUDE(CheckIncludeFiles) +INCLUDE(CheckCSourceCompiles) +INCLUDE(CheckLibraryExists) + +# Sometimes linking against libatomic is required for atomic ops, if +# the platform doesn't support lock-free atomics. + +function(check_c_atomics_without_lib varname) + CHECK_C_SOURCE_COMPILES(" +#include +int main() { + _Atomic long long x; + atomic_store(&x,3); + long long y = atomic_load(&x); + atomic_fetch_add(&x,12); + long long z = atomic_load(&x); + + return x; +} +" ${varname}) +endfunction(check_c_atomics_without_lib) + +function(check_c_atomics_with_lib varname) + SET(SAVED_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") + CHECK_C_SOURCE_COMPILES(" +#include +int main() { + _Atomic long long x; + atomic_store(&x,3); + long long y = atomic_load(&x); + atomic_fetch_add(&x,12); + long long z = atomic_load(&x); + + return x; +} +" ${varname}) + SET(CMAKE_REQUIRED_LIBRARIES "${SAVED_CMAKE_REQUIRED_LIBRARIES}") +endfunction(check_c_atomics_with_lib) + +macro (CheckAtomicLib) + # First check if atomics work without the library. + if(MSVC) + set(HAVE_C_ATOMICS_WITHOUT_LIB True) + else() + check_c_atomics_without_lib(HAVE_C_ATOMICS_WITHOUT_LIB) + if(NOT HAVE_C_ATOMICS_WITHOUT_LIB) + check_library_exists(atomic __atomic_fetch_add_8 "" HAVE_LIBATOMIC) + if( HAVE_LIBATOMIC ) + check_c_atomics_with_lib(HAVE_C_ATOMICS_WITH_LIB) + if (NOT HAVE_C_ATOMICS_WITH_LIB) + message(FATAL_ERROR "Host compiler must support atomic types!") + endif() + else() + message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.") + endif() + endif() + endif() +endmacro (CheckAtomicLib) -- cgit v1.2.3-70-g09d2