summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tdlib/td/CMake/FindAtomics.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tdlib/td/CMake/FindAtomics.cmake')
-rw-r--r--protocols/Telegram/tdlib/td/CMake/FindAtomics.cmake62
1 files changed, 62 insertions, 0 deletions
diff --git a/protocols/Telegram/tdlib/td/CMake/FindAtomics.cmake b/protocols/Telegram/tdlib/td/CMake/FindAtomics.cmake
new file mode 100644
index 0000000000..a855132581
--- /dev/null
+++ b/protocols/Telegram/tdlib/td/CMake/FindAtomics.cmake
@@ -0,0 +1,62 @@
+# Original issue:
+# * https://gitlab.kitware.com/cmake/cmake/-/issues/23021#note_1098733
+#
+# For reference:
+# * https://gcc.gnu.org/wiki/Atomic/GCCMM
+#
+# riscv64 specific:
+# * https://lists.debian.org/debian-riscv/2022/01/msg00009.html
+#
+# ATOMICS_FOUND - system has C++ atomics
+# ATOMICS_LIBRARIES - libraries needed to use C++ atomics
+
+if (ATOMICS_FOUND)
+ return()
+endif()
+
+include(CheckCXXSourceCompiles)
+
+# RISC-V only has 32-bit and 64-bit atomic instructions. GCC is supposed
+# to convert smaller atomics to those larger ones via masking and
+# shifting like LLVM, but it's a known bug that it does not. This means
+# anything that wants to use atomics on 1-byte or 2-byte types needs
+# to link atomic library, but not 4-byte or 8-byte (though it does no harm).
+set(ATOMIC_CODE
+ "
+ #include <atomic>
+ #include <cstdint>
+ std::atomic<std::uint8_t> n8{0}; // riscv64
+ std::atomic<std::uint64_t> n64{0}; // armel, mipsel, powerpc
+ int main() {
+ ++n8;
+ ++n64;
+ }")
+
+set(ATOMICS_LIBS " " "-latomic")
+if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
+ set(ATOMICS_LIBS "${ATOMICS_LIBS}" /usr/pkg/gcc12/x86_64--netbsd/lib/libatomic.so /usr/pkg/gcc12/i486--netbsdelf/lib/libatomic.so)
+endif()
+
+foreach (ATOMICS_LIBRARY ${ATOMICS_LIBS})
+ unset(ATOMICS_FOUND CACHE)
+ set(CMAKE_REQUIRED_LIBRARIES "${ATOMICS_LIBRARY}")
+ check_cxx_source_compiles("${ATOMIC_CODE}" ATOMICS_FOUND)
+ unset(CMAKE_REQUIRED_LIBRARIES)
+ if (ATOMICS_FOUND)
+ if (NOT ATOMICS_LIBRARY STREQUAL " ")
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Atomics DEFAULT_MSG ATOMICS_LIBRARY)
+ set(ATOMICS_LIBRARIES "${ATOMICS_LIBRARY}" CACHE STRING "Atomic library" FORCE)
+ else()
+ set(ATOMICS_LIBRARIES "" CACHE STRING "Atomic operations library" FORCE)
+ endif()
+ break()
+ endif()
+endforeach()
+if (Atomics_FIND_REQUIRED AND NOT ATOMICS_FOUND)
+ message(FATAL_ERROR "Atomic operations library isn't found.")
+endif()
+
+unset(ATOMICS_LIBRARY)
+unset(ATOMICS_LIBS)
+unset(ATOMIC_CODE)