c3c icon indicating copy to clipboard operation
c3c copied to clipboard

`@weak` attribute does not appear to work for `--target windows-x64`

Open NotsoanoNimus opened this issue 4 months ago • 2 comments

Repro:

module component::weak_module;
import std::io;
fn void do_thing() @weak @extern("do_thing") @nostrip => io::printn("weak");

module component::strong_module;
import std::io;
fn void do_thing() @export("do_thing") @nostrip => io::printn("strong");

module main;
extern fn void do_thing();
fn void main() => do_thing();

Build command: c3c compile-only main4.c3 --obj --link-libc=no --no-entry --target windows-x64

Inspecting the resulting COFF object file does not show a weak symbol as it should. And attempting to link creates a duplicate symbol error.

~$ nm ./obj/windows-x64/component.weak_module.obj | grep do_thing
0000000000000000 T do_thing
~$
~$  # now try linking it
~$ c3c compile-run main4.c3 --link-libc=no --target windows-x64
lld-link: error: duplicate symbol: do_thing
>>> defined at /path/main4.c3:7
>>>            /tmp/c3cXIZoBZU/obj/windows-x64/component.strong_module.obj
>>> defined at /tmp/c3cXIZoBZU/obj/windows-x64/component.weak_module.obj
Failed to create an executable: (null)

NotsoanoNimus avatar Aug 12 '25 14:08 NotsoanoNimus

I'm still working on this. Basically Windows does not have proper weak symbols. Instead they have linkonce and emulating weak using comdat. Unfortunately, if you have a regular symbol it doesn't have comdat and so it won't be merged with the weak symbol that doesn't have comdat. The solution might be linkonce, but in that case any linkonce will not be in the binary unless referenced, which is not what weak does. So... problematic.

lerno avatar Aug 18 '25 12:08 lerno

We can set all functions to use comdat on Windows? That wouldn't necessarily work with other C functions though.

lerno avatar Oct 10 '25 12:10 lerno