From 7df9b88bdbd8440af75dea3c22f8cabfa7482001 Mon Sep 17 00:00:00 2001 From: Brian Bockelman Date: Thu, 30 Jan 2025 13:54:01 -0600 Subject: [PATCH] Check if we need to link against libatomic On some 32-bit platforms, explicit linking against libatomic is required for atomics to be utilized. Test that at the CMake level, adding an import target as we did for `std::filesystem` that can be used. Based on the suggestion from: https://github.com/PelicanPlatform/xrootd-s3-http/pull/81 --- CMakeLists.txt | 4 ++- cmake/FindAtomic.cmake | 57 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 cmake/FindAtomic.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index da3970c..a56a288 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,8 @@ endif() # Our custom Filesystem module creates the std::filesystem library target for # any special dependencies needed for using std::filesystem. find_package( Filesystem REQUIRED ) +# Similar setup for libatomic; required only on 32-bit systems +find_package( Atomic REQUIRED ) if( NOT XROOTD_EXTERNAL_TINYXML2 ) include(FetchContent) @@ -77,7 +79,7 @@ add_definitions( -D_FILE_OFFSET_BITS=64 ) add_library(XrdS3Obj OBJECT src/CurlUtil.cc src/S3File.cc src/S3Directory.cc src/S3AccessInfo.cc src/S3FileSystem.cc src/AWSv4-impl.cc src/S3Commands.cc src/HTTPCommands.cc src/TokenFile.cc src/stl_string_utils.cc src/shortfile.cc src/logging.cc) set_target_properties(XrdS3Obj PROPERTIES POSITION_INDEPENDENT_CODE ON) target_include_directories(XrdS3Obj PRIVATE ${XRootD_INCLUDE_DIRS}) -target_link_libraries(XrdS3Obj ${XRootD_UTILS_LIBRARIES} ${XRootD_SERVER_LIBRARIES} CURL::libcurl OpenSSL::Crypto tinyxml2::tinyxml2 Threads::Threads std::filesystem) +target_link_libraries( XrdS3Obj ${XRootD_UTILS_LIBRARIES} ${XRootD_SERVER_LIBRARIES} CURL::libcurl OpenSSL::Crypto tinyxml2::tinyxml2 Threads::Threads std::filesystem std::atomic ) add_library(XrdS3 MODULE "$") target_link_libraries(XrdS3 XrdS3Obj) diff --git a/cmake/FindAtomic.cmake b/cmake/FindAtomic.cmake new file mode 100644 index 0000000..c74b5b5 --- /dev/null +++ b/cmake/FindAtomic.cmake @@ -0,0 +1,57 @@ + +# Ideas come from +# +# https://gitlab.kitware.com/cmake/cmake/-/issues/17834 +# +# But applied to the use of libatomic instead of libstdc++fs. +# The need to do this was highlighted as part of: +# https://github.com/PelicanPlatform/xrootd-s3-http/pull/81 +# The original driving use case was 32-bit builds; if we +# decide to drop those, we can rip out the target + +include(CheckSourceCompiles) + +function( check_working_cxx_atomics varname ) + CHECK_SOURCE_COMPILES( CXX " + #include + #include + #include + + int main() { + std::atomic a1; + std::atomic a2; + std::atomic a3; + std::atomic a4; + return a1++ + a2++ + a3++ + a4++; + }" ${varname} + ) +endfunction( check_working_cxx_atomics varname ) + + +check_working_cxx_atomics( CXX_ATOMIC_NO_LINK_NEEDED ) + +set( _found FALSE ) +if( CXX_ATOMIC_NO_LINK_NEEDED ) + set( _found TRUE ) +else() + check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC) + if (HAVE_LIBATOMIC) + set( OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ) + list( APPEND CMAKE_REQUIRED_LIBRARIES "atomic" ) + check_working_cxx_atomics( HAVE_CXX_ATOMICS_WITH_LIB ) + set( CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES} ) + set( HAVE_CXX_ATOMICS_WITH_LIB TRUE ) + set( _found TRUE ) + endif() +endif() + +add_library( std::atomic INTERFACE IMPORTED ) + +if( HAVE_CXX_ATOMICS_WITH_LIB ) + set_property( TARGET std::atomic APPEND PROPERTY INTERFACE_LINK_LIBRARIES atomic ) +endif() + +set( Atomic_FOUND ${_found} CACHE BOOL "TRUE if we can run a program using std::atomic" FORCE ) +if( Atomic_FIND_REQUIRED AND NOT Atomic_FOUND ) + message( FATAL_ERROR "Cannot run simple program using std::atomic" ) +endif()