diff --git a/CMakeLists.txt b/CMakeLists.txt index 7200491df..21478c36a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -416,6 +416,8 @@ endif() # Check for GCC Atomic Intrinsics and C++11 Atomics. # Sets: # HAVE_LIBATOMIC +# HAVE_LIBATOMIC_COMPILES +# HAVE_LIBATOMIC_COMPILES_STATIC # HAVE_GCCATOMIC_INTRINSICS # HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC include(CheckGCCAtomicIntrinsics) @@ -973,7 +975,7 @@ endif() if (srt_libspec_shared) if (MICROSOFT) target_link_libraries(${TARGET_srt}_shared PUBLIC Ws2_32.lib) - if (OPENSSL_USE_STATIC_LIBS) + if (OPENSSL_USE_STATIC_LIBS) target_link_libraries(${TARGET_srt}_shared PUBLIC crypt32.lib) endif() endif() @@ -988,6 +990,12 @@ if (HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC AND HAVE_LIBATOMIC) if (srt_libspec_shared) target_link_libraries(${TARGET_srt}_shared PUBLIC atomic) endif() +elseif (HAVE_LIBATOMIC AND HAVE_LIBATOMIC_COMPILES_STATIC) + # This is a workaround for ANDROID NDK<17 builds, which need to link + # to libatomic when linking statically to the SRT library. + if (srt_libspec_static) + target_link_libraries(${TARGET_srt}_static PUBLIC atomic) + endif() endif() # Cygwin installs the *.dll libraries in bin directory and uses PATH. diff --git a/scripts/CheckGCCAtomicIntrinsics.cmake b/scripts/CheckGCCAtomicIntrinsics.cmake index 9429db12f..f47b14d61 100644 --- a/scripts/CheckGCCAtomicIntrinsics.cmake +++ b/scripts/CheckGCCAtomicIntrinsics.cmake @@ -1,67 +1,113 @@ # -# SRT - Secure, Reliable, Transport -# Copyright (c) 2021 Haivision Systems Inc. +# SRT - Secure, Reliable, Transport Copyright (c) 2021 Haivision Systems Inc. # -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# This Source Code Form is subject to the terms of the Mozilla Public License, +# v. 2.0. If a copy of the MPL was not distributed with this file, You can +# obtain one at http://mozilla.org/MPL/2.0/. # # Check for GCC Atomic Intrinsics and whether libatomic is required. # # Sets: -# HAVE_LIBATOMIC -# HAVE_GCCATOMIC_INTRINSICS -# HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC +# HAVE_LIBATOMIC +# HAVE_LIBATOMIC_COMPILES +# HAVE_LIBATOMIC_COMPILES_STATIC +# HAVE_GCCATOMIC_INTRINSICS +# HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC # # See -# https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html -# https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync +# https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html +# https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync include(CheckCSourceCompiles) include(CheckLibraryExists) function(CheckGCCAtomicIntrinsics) - unset(HAVE_LIBATOMIC CACHE) - unset(HAVE_GCCATOMIC_INTRINSICS CACHE) - unset(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC CACHE) + unset(HAVE_LIBATOMIC CACHE) + unset(HAVE_LIBATOMIC_COMPILES CACHE) + unset(HAVE_LIBATOMIC_COMPILES_STATIC CACHE) + unset(HAVE_GCCATOMIC_INTRINSICS CACHE) + unset(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC CACHE) - unset(CMAKE_REQUIRED_FLAGS) - unset(CMAKE_REQUIRED_LIBRARIES) - unset(CMAKE_REQUIRED_LINK_OPTIONS) + set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) # CMake 3.6 - set(CheckGCCAtomicIntrinsics_CODE - " - #include - #include - int main(void) - { - ptrdiff_t x = 0; - intmax_t y = 0; - __atomic_add_fetch(&x, 1, __ATOMIC_SEQ_CST); - __atomic_add_fetch(&y, 1, __ATOMIC_SEQ_CST); - return __atomic_sub_fetch(&x, 1, __ATOMIC_SEQ_CST) - + __atomic_sub_fetch(&y, 1, __ATOMIC_SEQ_CST); - } - ") + unset(CMAKE_REQUIRED_FLAGS) + unset(CMAKE_REQUIRED_LIBRARIES) + unset(CMAKE_REQUIRED_LINK_OPTIONS) - check_library_exists( - atomic __atomic_fetch_add_8 "" HAVE_LIBATOMIC) + # Check for existance of libatomic and whether this symbol is present. + check_library_exists(atomic __atomic_fetch_add_8 "" HAVE_LIBATOMIC) - set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) # CMake 3.6 - check_c_source_compiles( - "${CheckGCCAtomicIntrinsics_CODE}" - HAVE_GCCATOMIC_INTRINSICS) + set(CheckLibAtomicCompiles_CODE + " + int main(void) + { + const int result = 0; + return result; + } + ") - if (NOT HAVE_GCCATOMIC_INTRINSICS AND HAVE_LIBATOMIC) - set(CMAKE_REQUIRED_LIBRARIES "atomic") - check_c_source_compiles( - "${CheckGCCAtomicIntrinsics_CODE}" - HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC) - if (HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC) - set(HAVE_GCCATOMIC_INTRINSICS TRUE PARENT_SCOPE) - endif() - endif() + set(CMAKE_REQUIRED_LIBRARIES "atomic") + + # Check that the compiler can build a simple application and link with + # libatomic. + check_c_source_compiles("${CheckLibAtomicCompiles_CODE}" + HAVE_LIBATOMIC_COMPILES) + if(NOT HAVE_LIBATOMIC_COMPILES) + set(HAVE_LIBATOMIC + 0 + CACHE INTERNAL "" FORCE) + endif() + if(HAVE_LIBATOMIC AND HAVE_LIBATOMIC_COMPILES) + # CMAKE_REQUIRED_LINK_OPTIONS was introduced in CMake 3.14. + if(CMAKE_VERSION VERSION_LESS "3.14") + set(CMAKE_REQUIRED_LINK_OPTIONS "-static") + else() + set(CMAKE_REQUIRED_FLAGS "-static") + endif() + # Check that the compiler can build a simple application and statically link + # with libatomic. + check_c_source_compiles("${CheckLibAtomicCompiles_CODE}" + HAVE_LIBATOMIC_COMPILES_STATIC) + else() + set(HAVE_LIBATOMIC_COMPILES_STATIC + 0 + CACHE INTERNAL "" FORCE) + endif() + + unset(CMAKE_REQUIRED_FLAGS) + unset(CMAKE_REQUIRED_LIBRARIES) + unset(CMAKE_REQUIRED_LINK_OPTIONS) + + set(CheckGCCAtomicIntrinsics_CODE + " + #include + #include + int main(void) + { + ptrdiff_t x = 0; + intmax_t y = 0; + __atomic_add_fetch(&x, 1, __ATOMIC_SEQ_CST); + __atomic_add_fetch(&y, 1, __ATOMIC_SEQ_CST); + return __atomic_sub_fetch(&x, 1, __ATOMIC_SEQ_CST) + + __atomic_sub_fetch(&y, 1, __ATOMIC_SEQ_CST); + } + ") + + set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) # CMake 3.6 + check_c_source_compiles("${CheckGCCAtomicIntrinsics_CODE}" + HAVE_GCCATOMIC_INTRINSICS) + + if(NOT HAVE_GCCATOMIC_INTRINSICS AND HAVE_LIBATOMIC) + set(CMAKE_REQUIRED_LIBRARIES "atomic") + check_c_source_compiles("${CheckGCCAtomicIntrinsics_CODE}" + HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC) + if(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC) + set(HAVE_GCCATOMIC_INTRINSICS + 1 + CACHE INTERNAL "" FORCE) + endif() + endif() endfunction(CheckGCCAtomicIntrinsics)