From: Sergey Sharybin <sergey@blender.org>
Date: Fri, 11 Feb 2022 11:10:53 +0100
Subject: fix_compilation_on_certain_platforms

Atomic operations performed by the C++ standard library might require
libatomic on platforms which do not have hardware support for those
operations.

This change makes it that such configurations are automatically detected
and -latomic is added when needed.
---
 build_files/cmake/platform/platform_unix.cmake | 42 ++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake
index fc0c37e..e7c6509 100644
--- a/build_files/cmake/platform/platform_unix.cmake
+++ b/build_files/cmake/platform/platform_unix.cmake
@@ -741,3 +741,45 @@ if(WITH_COMPILER_CCACHE)
     set(WITH_COMPILER_CCACHE OFF)
   endif()
 endif()
+
+# On some platforms certain atomic operations are not possible with assembly and/or intrinsics and
+# they are emulated in software with locks. For example, on armel there is no intrinsics to grant
+# 64 bit atomic operations and STL library uses libatomic to offload software emulation of atomics
+# to.
+# This function will check whether libatomic is required and if so will configure linker flags.
+# If atomic operations are possible without libatomic then linker flags are left as-is.
+function(CONFIGURE_ATOMIC_LIB_IF_NEEDED)
+  # Source which is used to enforce situation when software emulation of atomics is required.
+  # Assume that using 64bit integer gives a definitive asnwer (as in, if 64bit atomic operations
+  # are possible using assembly/intrinsics 8, 16, and 32 bit operations will also be possible.
+  set(_source
+      "#include <atomic>
+      #include <cstdint>
+      int main(int argc, char **argv) {
+        std::atomic<uint64_t> uint64; uint64++;
+        return 0;
+      }")
+
+  include(CheckCXXSourceCompiles)
+  check_cxx_source_compiles("${_source}" ATOMIC_OPS_WITHOUT_LIBATOMIC)
+
+  if(NOT ATOMIC_OPS_WITHOUT_LIBATOMIC)
+    # Compilation of the test program has failed.
+    # Try it again with -latomic to see if this is what is needed, or whether something else is
+    # going on.
+
+    set(CMAKE_REQUIRED_LIBRARIES atomic)
+    check_cxx_source_compiles("${_source}" ATOMIC_OPS_WITH_LIBATOMIC)
+
+    if(ATOMIC_OPS_WITH_LIBATOMIC)
+      set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -latomic" PARENT_SCOPE)
+    else()
+      # Atomic operations are required part of Blender and it is not possible to process forward.
+      # We expect that either standard library or libatomic will make atomics to work. If both
+      # cases has failed something fishy o na bigger scope is going on.
+      message(FATAL_ERROR "Failed to detect required configuration for atomic operations")
+    endif()
+  endif()
+endfunction()
+
+CONFIGURE_ATOMIC_LIB_IF_NEEDED()
