From 26eddd713bdac79382e315b5296d0281ec81a0ab Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 23 Apr 2026 21:49:01 +0300 Subject: [PATCH] thirdparty: fix Cross-compiling from amd64 to arm64 double definition C error (fixes #26534) --- thirdparty/stdatomic/nix/atomic.h | 9 +-------- vlib/sync/stdatomic/1.declarations.c.v | 1 - vlib/v/builder/cc_test.v | 25 +++++++++++++++++++++++++ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/thirdparty/stdatomic/nix/atomic.h b/thirdparty/stdatomic/nix/atomic.h index 3622d85ef..ddd5c1963 100644 --- a/thirdparty/stdatomic/nix/atomic.h +++ b/thirdparty/stdatomic/nix/atomic.h @@ -54,17 +54,10 @@ typedef volatile uintptr_t atomic_uintptr_t; extern void atomic_thread_fence (int memory_order); extern void __atomic_thread_fence (int memory_order); -// workaround for tcc/aarch64; Note: latest prebuilt tcc works, and does not need this hack: +// TinyCC relies on its runtime atomics support for thread fences. #if !defined(__APPLE__) -#if (defined(__aarch64__) || defined(_M_ARM64)) - // `_V_atomic_thread_fence` is defined in `atomic.S` - extern void _V_atomic_thread_fence(int memory_order); - #define atomic_thread_fence(order) _V_atomic_thread_fence(order) - #define __atomic_thread_fence(order) _V_atomic_thread_fence(order) -#else #define atomic_thread_fence(order) __atomic_thread_fence(order) #endif -#endif // use functions for 64, 32 and 8 bit from libatomic directly // since tcc is not capible to use "generic" C functions diff --git a/vlib/sync/stdatomic/1.declarations.c.v b/vlib/sync/stdatomic/1.declarations.c.v index 9a8760c21..a0d39e5ec 100644 --- a/vlib/sync/stdatomic/1.declarations.c.v +++ b/vlib/sync/stdatomic/1.declarations.c.v @@ -63,7 +63,6 @@ $if linux { // Alpine: #flag $when_first_existing('/usr/lib/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/6/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/7/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/8/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/9/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/10/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/11/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/12/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/13/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/14/libatomic.so') } - #flag @VEXEROOT/thirdparty/stdatomic/nix/atomic.S } } } diff --git a/vlib/v/builder/cc_test.v b/vlib/v/builder/cc_test.v index 2c1bb7cfb..0433b9749 100644 --- a/vlib/v/builder/cc_test.v +++ b/vlib/v/builder/cc_test.v @@ -379,6 +379,31 @@ fn test_thirdparty_cross_compile_config_for_freebsd_matches_target() { ] } +fn test_linux_tcc_arm64_stdatomic_does_not_add_atomic_s() { + $if !linux { + return + } + test_dir := os.join_path(os.vtmp_dir(), 'v_builder_stdatomic_tcc_arm64_${os.getpid()}') + os.mkdir_all(test_dir) or { panic(err) } + defer { + os.rmdir_all(test_dir) or {} + } + src_file := os.join_path(test_dir, 'main.v') + os.write_file(src_file, 'import sync.stdatomic +fn main() { + mut x := u64(0) + stdatomic.store_u64(&x, 1) +} +') or { + panic(err) + } + res := + os.execute('${os.quoted_path(@VEXE)} -dump-c-flags - -cc tcc -arch arm64 ${os.quoted_path(src_file)}') + assert res.exit_code == 0, res.output + assert !res.output.contains('thirdparty/stdatomic/nix/atomic.S') + assert res.output.contains('libatomic.so') +} + fn test_live_windows_main_linker_args_export_host_symbols() { linker_args := builder_linker_args([ '-os', -- 2.39.5