Skip to content

Commit 22ba4f2

Browse files
got3nksmrjimenez
authored andcommitted
cmake: drop atomic-probe heuristic, find libatomic directly on 32-bit
PR #648's cmake/atomic.cmake uses check_cxx_source_compiles to decide whether linking libatomic is required for std::atomic<int64_t>. The probe runs a tiny main() that stores / loads / fetch_adds / compare_exchanges a std::atomic<int64_t>, then links it. On 32-bit targets the compiler can inline the entire lock-free expansion of those operations end-to-end -- no __atomic_*_8 library-call symbols are emitted, the link succeeds, and the probe reports 'native 64-bit atomics work, no -latomic needed'. The real codebase's atomics live in CDownloadBandwidthThrottler member functions called across translation-unit boundaries. GCC can't inline those, emits __atomic_compare_exchange_8 / __atomic_load_8 / __atomic_store_8 / __atomic_fetch_add_8 references, and the link fails with the original Undefined Symbols errors the probe was supposed to detect. Reported by @barracuda156 on PPC32 MacPorts -- amule_HAVE_NATIVE_ATOMIC64 = Success at configure, link failure at build. The probe heuristic is fundamentally fragile (any in-TU inlining hides the library-call references) so drop it. 32-bit CPUs lack a hardware 8-byte CAS -- the answer is always 'libatomic required'. Just look up the library with find_library(NAMES atomic) and link it; 64-bit targets stay a no-op. Move the new logic to the top of the root CMakeLists.txt where the include statement used to be. cmake/atomic.cmake is deleted. The hard-fail message preserves the per-distro install hint the previous FATAL_ERROR carried. Closes #643 properly.
1 parent 8ce30f9 commit 22ba4f2

3 files changed

Lines changed: 37 additions & 61 deletions

File tree

CMakeLists.txt

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,39 @@ if (NOT DEFINED CACHE{SVNDATE})
245245
endif()
246246

247247
include (cmake/bfd.cmake)
248-
include (cmake/atomic.cmake)
248+
249+
# DownloadBandwidthThrottler holds the shared byte budget as
250+
# std::atomic<int64_t>. On 64-bit targets the compiler emits native
251+
# 8-byte CAS / load / store and no library is needed. On 32-bit targets
252+
# (PPC32, ARMv5/v6, MIPS32, some old x86 toolchains) the atomic ops
253+
# expand to __atomic_{load,store,compare_exchange,fetch_add}_8 calls
254+
# that live in libatomic; the link fails with
255+
# "Undefined symbols: ___atomic_compare_exchange_8" without -latomic.
256+
#
257+
# We don't probe with check_cxx_source_compiles -- a tiny probe lets
258+
# the compiler inline the lock-free expansion end-to-end and reports
259+
# "native works" even on targets where the real codebase's cross-TU
260+
# atomic references actually do need the library (see #643). Just
261+
# require libatomic unconditionally on 32-bit builds.
262+
set (LIBATOMIC "")
263+
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
264+
find_library (LIBATOMIC_LIBRARY NAMES atomic)
265+
if (LIBATOMIC_LIBRARY)
266+
set (LIBATOMIC atomic)
267+
message (STATUS "32-bit target: linking libatomic for std::atomic<int64_t>")
268+
else()
269+
message (FATAL_ERROR
270+
"32-bit target detected (sizeof(void*) == 4). aMule's "
271+
"download bandwidth throttler holds the byte budget as "
272+
"std::atomic<int64_t>; 32-bit CPUs lack a native 8-byte "
273+
"atomic and the operations expand to library calls "
274+
"(__atomic_*_8) that live in libatomic. libatomic was "
275+
"not found on this system. Install it and re-run cmake:\n"
276+
" Debian/Ubuntu/Mint: libatomic1-dev\n"
277+
" Fedora/RHEL/Rocky/Arch: libatomic\n"
278+
" macOS/MacPorts: bundled with gcc; install gcc14+")
279+
endif()
280+
endif()
249281

250282
# glib-2.0 headers — needed for the Wayland wl_app_id / X11 WM_CLASS
251283
# binding via g_set_prgname() (called from amule.cpp on the monolithic

cmake/atomic.cmake

Lines changed: 0 additions & 56 deletions
This file was deleted.

src/CMakeLists.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -655,10 +655,10 @@ if (NEED_LIB_MULEAPPCORE)
655655

656656
# DownloadBandwidthThrottler's std::atomic<int64_t> byte budget
657657
# needs libatomic on 32-bit targets without a hardware 8-byte
658-
# CAS (PPC32, ARMv5/v6, MIPS32). LIBATOMIC is set in
659-
# cmake/atomic.cmake — empty on 64-bit, "atomic" on 32-bit.
660-
# Linked PUBLIC so amule / amuled / amulegui pick it up
661-
# transitively.
658+
# CAS (PPC32, ARMv5/v6, MIPS32). LIBATOMIC is set at the top
659+
# of the root CMakeLists.txt — empty on 64-bit, "atomic" on
660+
# 32-bit. Linked PUBLIC so amule / amuled / amulegui pick it
661+
# up transitively.
662662
if (LIBATOMIC)
663663
target_link_libraries (muleappcore PUBLIC ${LIBATOMIC})
664664
endif()

0 commit comments

Comments
 (0)