1# 2# SRT - Secure, Reliable, Transport Copyright (c) 2021 Haivision Systems Inc. 3# 4# This Source Code Form is subject to the terms of the Mozilla Public License, 5# v. 2.0. If a copy of the MPL was not distributed with this file, You can 6# obtain one at http://mozilla.org/MPL/2.0/. 7# 8 9# Check for GCC Atomic Intrinsics and whether libatomic is required. 10# 11# Sets: 12# HAVE_LIBATOMIC 13# HAVE_LIBATOMIC_COMPILES 14# HAVE_LIBATOMIC_COMPILES_STATIC 15# HAVE_GCCATOMIC_INTRINSICS 16# HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC 17# 18# See 19# https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html 20# https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync 21 22include(CheckCSourceCompiles) 23include(CheckLibraryExists) 24 25function(CheckGCCAtomicIntrinsics) 26 27 unset(HAVE_LIBATOMIC CACHE) 28 unset(HAVE_LIBATOMIC_COMPILES CACHE) 29 unset(HAVE_LIBATOMIC_COMPILES_STATIC CACHE) 30 unset(HAVE_GCCATOMIC_INTRINSICS CACHE) 31 unset(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC CACHE) 32 33 set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) # CMake 3.6 34 35 unset(CMAKE_REQUIRED_FLAGS) 36 unset(CMAKE_REQUIRED_LIBRARIES) 37 unset(CMAKE_REQUIRED_LINK_OPTIONS) 38 39 # Check for existance of libatomic and whether this symbol is present. 40 check_library_exists(atomic __atomic_fetch_add_8 "" HAVE_LIBATOMIC) 41 42 set(CheckLibAtomicCompiles_CODE 43 " 44 int main(void) 45 { 46 const int result = 0; 47 return result; 48 } 49 ") 50 51 set(CMAKE_REQUIRED_LIBRARIES "atomic") 52 53 # Check that the compiler can build a simple application and link with 54 # libatomic. 55 check_c_source_compiles("${CheckLibAtomicCompiles_CODE}" 56 HAVE_LIBATOMIC_COMPILES) 57 if(NOT HAVE_LIBATOMIC_COMPILES) 58 set(HAVE_LIBATOMIC 59 0 60 CACHE INTERNAL "" FORCE) 61 endif() 62 if(HAVE_LIBATOMIC AND HAVE_LIBATOMIC_COMPILES) 63 # CMAKE_REQUIRED_LINK_OPTIONS was introduced in CMake 3.14. 64 if(CMAKE_VERSION VERSION_LESS "3.14") 65 set(CMAKE_REQUIRED_LINK_OPTIONS "-static") 66 else() 67 set(CMAKE_REQUIRED_FLAGS "-static") 68 endif() 69 # Check that the compiler can build a simple application and statically link 70 # with libatomic. 71 check_c_source_compiles("${CheckLibAtomicCompiles_CODE}" 72 HAVE_LIBATOMIC_COMPILES_STATIC) 73 else() 74 set(HAVE_LIBATOMIC_COMPILES_STATIC 75 0 76 CACHE INTERNAL "" FORCE) 77 endif() 78 79 unset(CMAKE_REQUIRED_FLAGS) 80 unset(CMAKE_REQUIRED_LIBRARIES) 81 unset(CMAKE_REQUIRED_LINK_OPTIONS) 82 83 set(CheckGCCAtomicIntrinsics_CODE 84 " 85 #include<stddef.h> 86 #include<stdint.h> 87 int main(void) 88 { 89 ptrdiff_t x = 0; 90 intmax_t y = 0; 91 __atomic_add_fetch(&x, 1, __ATOMIC_SEQ_CST); 92 __atomic_add_fetch(&y, 1, __ATOMIC_SEQ_CST); 93 return __atomic_sub_fetch(&x, 1, __ATOMIC_SEQ_CST) 94 + __atomic_sub_fetch(&y, 1, __ATOMIC_SEQ_CST); 95 } 96 ") 97 98 set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) # CMake 3.6 99 check_c_source_compiles("${CheckGCCAtomicIntrinsics_CODE}" 100 HAVE_GCCATOMIC_INTRINSICS) 101 102 if(NOT HAVE_GCCATOMIC_INTRINSICS AND HAVE_LIBATOMIC) 103 set(CMAKE_REQUIRED_LIBRARIES "atomic") 104 check_c_source_compiles("${CheckGCCAtomicIntrinsics_CODE}" 105 HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC) 106 if(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC) 107 set(HAVE_GCCATOMIC_INTRINSICS 108 1 109 CACHE INTERNAL "" FORCE) 110 endif() 111 endif() 112 113endfunction(CheckGCCAtomicIntrinsics) 114