Skip to content

Commit

Permalink
[build] Automatically link libatomic if needed. (#2116)
Browse files Browse the repository at this point in the history
  • Loading branch information
jlsantiago0 committed Sep 3, 2021
1 parent 2243388 commit e8f4057
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 4 deletions.
25 changes: 21 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,20 @@ else() # Compiler altered by WITH_COMPILER_TYPE/PREFIX - can't rely on CMAKE_CXX
message(STATUS "COMPILER CHANGED TO: ${COMPILER_TYPE} - forcing C++11 standard for apps")
endif()

# Check for GCC Atomic Intrinsics and C++11 Atomics.
# Sets:
# HAVE_LIBATOMIC
# HAVE_GCCATOMIC_INTRINSICS
# HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC
# HAVE_GCCATOMIC_INTRINSICS_STATIC
# HAVE_GCCATOMIC_INTRINSICS_STATIC_REQUIRES_LIBATOMIC
include(CheckGCCAtomicIntrinsics)
CheckGCCAtomicIntrinsics()
# HAVE_CXX_ATOMIC
# HAVE_CXX_ATOMIC_STATIC
include(CheckCXXAtomic)
CheckCXXAtomic()

if (DISABLE_CXX11)
set (ENABLE_CXX11 0)
elseif( DEFINED ENABLE_CXX11 )
Expand Down Expand Up @@ -877,8 +891,6 @@ if (srt_libspec_shared)
target_link_libraries(${TARGET_srt}_shared PRIVATE wsock32.lib ws2_32.lib)
elseif (APPLE)
set_property(TARGET ${TARGET_srt}_shared PROPERTY MACOSX_RPATH ON)
elseif (ANDROID)
target_link_libraries(${TARGET_srt}_shared PRIVATE atomic)
endif()
if (USE_GNUSTL)
target_link_libraries(${TARGET_srt}_shared PRIVATE ${GNUSTL_LIBRARIES} ${GNUSTL_LDFLAGS})
Expand Down Expand Up @@ -913,8 +925,6 @@ if (srt_libspec_static)
endif()
elseif (MINGW)
target_link_libraries(${TARGET_srt}_static PRIVATE wsock32 ws2_32)
elseif (ANDROID)
target_link_libraries(${TARGET_srt}_static PUBLIC atomic)
endif()
if (USE_GNUSTL)
target_link_libraries(${TARGET_srt}_static PRIVATE ${GNUSTL_LIBRARIES} ${GNUSTL_LDFLAGS})
Expand Down Expand Up @@ -966,6 +976,13 @@ if (srt_libspec_shared)
endif()
endif()

# Required by some toolchains when statically linking this library if the
# GCC Atomic Intrinsics are being used.
if (HAVE_GCCATOMIC_INTRINSICS
AND HAVE_LIBATOMIC)
target_link_libraries(${TARGET_srt}_static PUBLIC atomic)
endif()

# Cygwin installs the *.dll libraries in bin directory and uses PATH.

set (INSTALL_SHARED_DIR ${CMAKE_INSTALL_LIBDIR})
Expand Down
62 changes: 62 additions & 0 deletions scripts/CheckCXXAtomic.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#
# 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/.
#

# Check for c++11 std::atomic.
#
# Sets:
# HAVE_CXX_ATOMIC
# HAVE_CXX_ATOMIC_STATIC

include(CheckCXXSourceCompiles)
include(CheckLibraryExists)

function(CheckCXXAtomic)

unset(HAVE_CXX_ATOMIC)
unset(HAVE_CXX_ATOMIC PARENT_SCOPE)
unset(HAVE_CXX_ATOMIC CACHE)

unset(HAVE_CXX_ATOMIC_STATIC)
unset(HAVE_CXX_ATOMIC_STATIC PARENT_SCOPE)
unset(HAVE_CXX_ATOMIC_STATIC CACHE)

unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_LINK_OPTIONS)

set(CheckCXXAtomic_CODE
"
#include<cstdint>
#include<atomic>
int main(void)
{
std::atomic<std::ptrdiff_t> x(0);
std::atomic<std::intmax_t> y(0);
return x + y;
}
")

set(CMAKE_REQUIRED_FLAGS "-std=c++11")

check_cxx_source_compiles(
"${CheckCXXAtomic_CODE}"
HAVE_CXX_ATOMIC)

if(HAVE_CXX_ATOMIC)
set(CMAKE_REQUIRED_LINK_OPTIONS "-static")
check_cxx_source_compiles(
"${CheckCXXAtomic_CODE}"
HAVE_CXX_ATOMIC_STATIC)
endif()

unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_LINK_OPTIONS)

endfunction(CheckCXXAtomic)
110 changes: 110 additions & 0 deletions scripts/CheckGCCAtomicIntrinsics.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#
# 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/.
#

# Check for GCC Atomic Intrinsics and whether libatomic is required.
#
# Sets:
# HAVE_LIBATOMIC
# HAVE_GCCATOMIC_INTRINSICS
# HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC
# HAVE_GCCATOMIC_INTRINSICS_STATIC
# HAVE_GCCATOMIC_INTRINSICS_STATIC_REQUIRES_LIBATOMIC
#
# See
# 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)
unset(HAVE_LIBATOMIC PARENT_SCOPE)
unset(HAVE_LIBATOMIC CACHE)

unset(HAVE_GCCATOMIC_INTRINSICS)
unset(HAVE_GCCATOMIC_INTRINSICS PARENT_SCOPE)
unset(HAVE_GCCATOMIC_INTRINSICS CACHE)

unset(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC)
unset(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC PARENT_SCOPE)
unset(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC CACHE)

unset(HAVE_GCCATOMIC_INTRINSICS_STATIC)
unset(HAVE_GCCATOMIC_INTRINSICS_STATIC PARENT_SCOPE)
unset(HAVE_GCCATOMIC_INTRINSICS_STATIC CACHE)

unset(HAVE_GCCATOMIC_INTRINSICS_STATIC_REQUIRES_LIBATOMIC)
unset(HAVE_GCCATOMIC_INTRINSICS_STATIC_REQUIRES_LIBATOMIC PARENT_SCOPE)
unset(HAVE_GCCATOMIC_INTRINSICS_STATIC_REQUIRES_LIBATOMIC CACHE)

unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_LINK_OPTIONS)

set(CheckGCCAtomicIntrinsics_CODE
"
#include<stddef.h>
#include<stdint.h>
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);
}
")

check_library_exists(
atomic __atomic_fetch_add_8 "" HAVE_LIBATOMIC)

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 TRUE PARENT_SCOPE)
endif()
endif()

unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_LINK_OPTIONS)

if (HAVE_GCCATOMIC_INTRINSICS)
set(CMAKE_REQUIRED_LINK_OPTIONS "-static")
check_c_source_compiles(
"${CheckGCCAtomicIntrinsics_CODE}"
HAVE_GCCATOMIC_INTRINSICS_STATIC)
if (NOT HAVE_GCCATOMIC_INTRINSICS_STATIC
AND HAVE_LIBATOMIC)
set(CMAKE_REQUIRED_LIBRARIES "atomic")
check_c_source_compiles(
"${CheckGCCAtomicIntrinsics_CODE}"
HAVE_GCCATOMIC_INTRINSICS_STATIC)
if (HAVE_GCCATOMIC_INTRINSICS_STATIC)
set(HAVE_GCCATOMIC_INTRINSICS_STATIC_REQUIRES_LIBATOMIC TRUE PARENT_SCOPE)
endif()
endif()
endif()

unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_LINK_OPTIONS)

endfunction(CheckGCCAtomicIntrinsics)

0 comments on commit e8f4057

Please sign in to comment.