]> sigrok.org Git - pulseview.git/commitdiff
cmake: add check for explicit linking against libatomic
authorSamuel Martin <redacted>
Thu, 26 May 2016 21:46:40 +0000 (23:46 +0200)
committerUwe Hermann <redacted>
Sun, 12 Jun 2016 18:20:29 +0000 (20:20 +0200)
To use atomics functions, some toolchains requires to explicitly add
-latomic to the linker flags (because they are not provided by libc,
but libatomic).

This change adds a helper function trying to build/link a test program
using atomics, then calls it to:
* first check if atomics are directly available in the libc;
* if not and libatomic has been found, then run the same test with
  "-latomic" added to the linker flags.
The pulseview link library list is updated according to the results of
these tests.

This issue was triggered by the Buildroot farms:
  http://autobuild.buildroot.org/results/1e3/1e3101261252d5f30fdf842cc99604e4f4c25eef/build-end.log

Notes:
1- CMAKE_REQUIRED_* variables are only used in check functions. They
   are not automatically forwarded to/handled by the target commands
   (such as target_link_library), because the check functions are
   implemented as macro in CMake code, whereas many target commands
   are native.
2- Because of note #1, CMAKE_REQUIRED_LIBRARIES (or its value) must be
   explicitly passed to the target_link_library command when this is
   needed.
3- In this implementation, LIBATOMIC_LIBRARY is only set when it is
   needed; so, unconditionally appending it to PULSEVIEW_LINK_LIBS
   will produce the expected behavior.

This fixes bug #810.

Signed-off-by: Samuel Martin <redacted>
CMakeLists.txt

index 9dac69f2b08155200bf9bd49bcd78a99c74f9a08..44f810e3c5fec71a299a166ee546a705ceb22ef8 100644 (file)
@@ -107,6 +107,55 @@ endif()
 # This will set ${CMAKE_THREAD_LIBS_INIT} to the correct, OS-specific value.
 find_package(Threads REQUIRED)
 
+
+# Check for explicit link against libatomic
+#
+# Depending on the toolchain, linking a program using atomic functions may need
+# "-latomic" explicitly passed to the linker
+#
+# This check first tests if atomics are available in the C-library, if not and
+# libatomic exists, then it runs the same test with -latomic added to the
+# linker flags.
+
+# Helper for checking for atomics
+function(check_working_cxx_atomics varname additional_lib)
+  include(CheckCXXSourceCompiles)
+  include(CMakePushCheckState)
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_FLAGS "-std=c++11")
+  set(CMAKE_REQUIRED_LIBRARIES "${additional_lib}")
+  set(CMAKE_REQUIRED_QUIET 1)
+  CHECK_CXX_SOURCE_COMPILES("
+#include <atomic>
+std::atomic<int> x;
+int main() {
+  return std::atomic_fetch_add_explicit(&x, 1, std::memory_order_seq_cst);
+}
+" ${varname})
+  cmake_pop_check_state()
+endfunction(check_working_cxx_atomics)
+
+# First check if atomics work without the library.
+# If not, check if the library exists, and atomics work with it.
+check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB "")
+if(HAVE_CXX_ATOMICS_WITHOUT_LIB)
+  message(STATUS "Atomics provided by the C-library - yes")
+else()
+  message(STATUS "Atomics provided by the C-library - no")
+  find_library(LIBATOMIC_LIBRARY NAMES atomic PATH_SUFFIXES lib)
+  if(LIBATOMIC_LIBRARY)
+    check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB "${LIBATOMIC_LIBRARY}")
+    if (HAVE_CXX_ATOMICS_WITH_LIB)
+      message(STATUS "Atomics provided by libatomic - yes")
+    else()
+      message(STATUS "Atomics provided by libatomic - no")
+      message(FATAL_ERROR "Compiler must support std::atomic!")
+    endif()
+  else()
+    message(FATAL_ERROR "Compiler appears to require libatomic, but cannot find it.")
+  endif()
+endif()
+
 #===============================================================================
 #= System Introspection
 #-------------------------------------------------------------------------------
@@ -387,6 +436,7 @@ set(PULSEVIEW_LINK_LIBS
        ${Boost_LIBRARIES}
        ${QT_LIBRARIES}
        ${CMAKE_THREAD_LIBS_INIT}
+       ${LIBATOMIC_LIBRARY}
 )
 
 if(STATIC_PKGDEPS_LIBS)