diff --git a/CMakeLists.txt b/CMakeLists.txt index 815c5c4..a6b2e38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,10 @@ if(PTL_USE_TBB) find_package(TBB 2017 REQUIRED) endif() +# Check if compiler provides std::atomic as a library +# Sets CXX_ATOMIC_WITH_LINK to TRUE if so +include(CheckAtomic) + # -------------------------------------------------------------------------------------- # # PTL Primary Build add_subdirectory(source) diff --git a/cmake/Modules/CheckAtomic.cmake b/cmake/Modules/CheckAtomic.cmake new file mode 100644 index 0000000..44d919e --- /dev/null +++ b/cmake/Modules/CheckAtomic.cmake @@ -0,0 +1,75 @@ +# SPDX-FileCopyrightText: 2003-2018 University of Illinois at Urbana-Champaign. +# +# SPDX-License-Identifier: BSD-3-Clause + +#[=======================================================================[.rst: +CheckAtomic +----------- + +Check if the compiler supports std:atomic out of the box or if libatomic is +needed for atomic support. If it is needed libatomicis added to +``CMAKE_REQUIRED_LIBRARIES``. So after running CheckAtomic you can use +std:atomic. + +Since 5.75.0. +#]=======================================================================] + +include(CMakePushCheckState) +include(CheckCXXSourceCompiles) + +cmake_push_check_state() + +# Sometimes linking against libatomic is required for atomic ops, if the platform doesn't +# support lock-free atomics. + +# 64-bit target test code +if(CMAKE_SIZE_OF_VOID_P EQUAL 8) + set(ATOMIC_CODE_64 + " + std::atomic x(0); + uint64_t i = x.load(std::memory_order_relaxed); + ") +endif() + +# Test code +string( + CONFIGURE + [[ + #include + #include + int main() { + std::atomic a; + std::atomic b; + std::atomic c; + ++c; + ++b; + ++a; + @ATOMIC_CODE_64@ + return a; + } + ]] + ATOMIC_CODE + @ONLY) + +set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11") +check_cxx_source_compiles("${ATOMIC_CODE}" CXX_ATOMIC_NO_LINK) + +set(ATOMIC_FOUND ${CXX_ATOMIC_NO_LINK}) + +if(NOT CXX_ATOMIC_NO_LINK) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} atomic) + check_cxx_source_compiles("${ATOMIC_CODE}" CXX_ATOMIC_WITH_LINK) + set(ATOMIC_FOUND ${CXX_ATOMIC_WITH_LINK}) +endif() + +cmake_pop_check_state() + +if(ATOMIC_FOUND) + if(CXX_ATOMIC_NO_LINK) + message(VERBOSE "Found std::atomic with no linking") + elseif(CXX_ATOMIC_WITH_LINK) + message(VERBOSE "Found std::atomic with linking") + endif() +else() + message(WARNING "std::atomic not found with compilation checks") +endif() diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 26c3038..4f8fef6 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -37,6 +37,9 @@ if(BUILD_OBJECT_LIBS) if(PTL_USE_TBB) target_link_libraries(ptl-object PUBLIC TBB::tbb) endif() + if(CXX_ATOMIC_WITH_LINK) + target_link_libraries(ptl-object PUBLIC atomic) + endif() target_include_directories( ptl-object PUBLIC $ @@ -55,6 +58,9 @@ if(BUILD_SHARED_LIBS) if(PTL_USE_TBB) target_link_libraries(ptl-shared PUBLIC TBB::tbb) endif() + if(CXX_ATOMIC_WITH_LINK) + target_link_libraries(ptl-shared PUBLIC atomic) + endif() target_compile_definitions(ptl-shared PUBLIC PTL_BUILD_DLL) @@ -88,6 +94,9 @@ if(BUILD_STATIC_LIBS) if(PTL_USE_TBB) target_link_libraries(ptl-static PUBLIC TBB::tbb) endif() + if(CXX_ATOMIC_WITH_LINK) + target_link_libraries(ptl-static PUBLIC atomic) + endif() target_include_directories( ptl-static