Export a thread-local variable as a weak symbol

Hi!

I’m trying to export a thread-local variable as a weak symbol. In GNU C, this can be accomplished like so:

#include <stdint.h>
__thread  uint32_t __attribute__((weak)) weak_threadlocal = 1;
$ zig build-obj weakthreadlocal.c
$ nm weakthreadlocal.o
0000000000000000 W weak_threadlocal

In Zig, @export would be the obvious choice:

threadlocal var weak_threadlocal: u32 = 1;
comptime {
    @export(&weak_threadlocal, .{
        .linkage = .weak,
        .name = "weak_threadlocal",
    });
}

But this can’t work, because pointers to thread-local variables cannot be comptime-known since they vary for each thread. And the obvious way of using export can’t work because it doesn’t support weak symbols. How can I resolve this?

2 Likes

I am oof so can not check but if it hard achieve in zig possibly use result of C

for access to this var add to c helper function returning address of weak_threadlocal

I could not figure out a sane way to do this either. A workaround that also @g41797 mentioned, is declaring the variable in C and externing it in Zig.

__thread int __attribute__((weak)) weak_threadlocal = 1;
extern threadlocal var weak_threadlocal: c_int;
ali@nixos ~/d/zig (spirv)> zig build-obj weak.c weak.zig
ali@nixos ~/d/zig (spirv)> nm weak.o
0000000000000000 d builtin.output_mode
0000000000000000 W weak_threadlocal

Or you can patch it later via objcopy --weaken-symbol=weak_threadlocal weak.o. None are acceptable as a solution IMO so perhaps you should open an issue in codeberg.