From: Sergey Sharybin 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 + #include + int main(int argc, char **argv) { + std::atomic 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()