FindAtomics.cmake (1699B)
1 # Original issue: 2 # * https://gitlab.kitware.com/cmake/cmake/-/issues/23021#note_1098733 3 # 4 # For reference: 5 # * https://gcc.gnu.org/wiki/Atomic/GCCMM 6 # 7 # riscv64 specific: 8 # * https://lists.debian.org/debian-riscv/2022/01/msg00009.html 9 # 10 # ATOMICS_FOUND - system has c++ atomics 11 # ATOMICS_LIBRARIES - libraries needed to use c++ atomics 12 13 include(CheckCXXSourceCompiles) 14 15 # RISC-V only has 32-bit and 64-bit atomic instructions. GCC is supposed 16 # to convert smaller atomics to those larger ones via masking and 17 # shifting like LLVM, but it’s a known bug that it does not. This means 18 # anything that wants to use atomics on 1-byte or 2-byte types needs 19 # -latomic, but not 4-byte or 8-byte (though it does no harm). 20 set(atomic_code 21 " 22 #include <atomic> 23 #include <cstdint> 24 std::atomic<uint8_t> n8 (0); // riscv64 25 std::atomic<uint64_t> n64 (0); // armel, mipsel, powerpc 26 int main() { 27 ++n8; 28 ++n64; 29 return 0; 30 }") 31 32 check_cxx_source_compiles("${atomic_code}" ATOMICS_LOCK_FREE_INSTRUCTIONS) 33 34 if(ATOMICS_LOCK_FREE_INSTRUCTIONS) 35 set(ATOMICS_FOUND TRUE) 36 set(ATOMICS_LIBRARIES) 37 else() 38 set(CMAKE_REQUIRED_LIBRARIES "-latomic") 39 check_cxx_source_compiles("${atomic_code}" ATOMICS_IN_LIBRARY) 40 set(CMAKE_REQUIRED_LIBRARIES) 41 if(ATOMICS_IN_LIBRARY) 42 set(ATOMICS_LIBRARY atomic) 43 include(FindPackageHandleStandardArgs) 44 find_package_handle_standard_args(Atomics DEFAULT_MSG ATOMICS_LIBRARY) 45 set(ATOMICS_LIBRARIES ${ATOMICS_LIBRARY}) 46 unset(ATOMICS_LIBRARY) 47 else() 48 if(Atomics_FIND_REQUIRED) 49 message(FATAL_ERROR "Neither lock free instructions nor -latomic found.") 50 endif() 51 endif() 52 endif() 53 unset(atomic_code)