Fix compilation error 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.

Differential Revision: https://developer.blender.org/D14106
This commit is contained in:
Sergey Sharybin 2022-02-11 11:10:53 +01:00
parent 1d4037645f
commit ca991e3012
1 changed files with 42 additions and 0 deletions

View File

@ -866,3 +866,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()