aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Haase <kh@beingmeta.com>2020-02-14 10:18:53 -0500
committerGitHub <noreply@github.com>2020-02-14 07:18:53 -0800
commita18bfe9c156be16f231e0bb380fc70fad22da20c (patch)
treef7b84df11b9114ad1a32cfb2263e5c7678a09e32
parent0a315e4e5f7d90789babba312079462953114e0d (diff)
downloadnng-a18bfe9c156be16f231e0bb380fc70fad22da20c.tar.gz
nng-a18bfe9c156be16f231e0bb380fc70fad22da20c.tar.bz2
nng-a18bfe9c156be16f231e0bb380fc70fad22da20c.zip
Added atomic check for building on ARMs (#1196)
-rw-r--r--CMakeLists.txt7
-rw-r--r--cmake/CheckAtomicLib.cmake70
2 files changed, 77 insertions, 0 deletions
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 <kh@beingmeta.com>
+#
+# 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 <stdatomic.h>
+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 <stdatomic.h>
+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)