gnustep / libobjc2

Objective-C runtime library intended for use with Clang.
http://www.gnustep.org/
MIT License
434 stars 118 forks source link

Can't build with -fno-common (default with llvm 11 and GCC 10) #171

Closed zeising closed 4 years ago

zeising commented 4 years ago

Hi! I'm unable to get libobjc2 to build with -fno-common, which is the default with llvm 11 and GCC 10. When building on FreeBSD 13-CURRENT with llvm 11, I'm getting the following error on linking:

: && /usr/bin/cc -fPIC -O2 -pipe  -fno-strict-aliasing -Xclang -fexceptions -Xclang -fobjc-exceptions -O3 -O2 -pipe  -fno-strict-aliasing  -pthread -shared -Wl,-soname,libobjc.so.4.6 -o libobjc.so.4.6 CMakeFiles/objc.dir/alias_table.c.o CMakeFiles/objc.dir/block_to_imp.c.o CMakeFiles/objc.dir/caps.c.o CMakeFiles/objc.dir/category_loader.c.o CMakeFiles/objc.dir/class_table.c.o CMakeFiles/objc.dir/dtable.c.o CMakeFiles/objc.dir/encoding2.c.o CMakeFiles/objc.dir/hooks.c.o CMakeFiles/objc.dir/ivar.c.o CMakeFiles/objc.dir/loader.c.o CMakeFiles/objc.dir/mutation.m.o CMakeFiles/objc.dir/protocol.c.o CMakeFiles/objc.dir/runtime.c.o CMakeFiles/objc.dir/sarray2.c.o CMakeFiles/objc.dir/selector_table.c.o CMakeFiles/objc.dir/sendmsg2.c.o CMakeFiles/objc.dir/eh_personality.c.o CMakeFiles/objc.dir/legacy.c.o CMakeFiles/objc.dir/abi_version.c.o CMakeFiles/objc.dir/statics_loader.c.o CMakeFiles/objc.dir/block_trampolines.S.o CMakeFiles/objc.dir/objc_msgSend.S.o CMakeFiles/objc.dir/eh_trampoline.s.o CMakeFiles/objc.dir/NSBlocks.m.o CMakeFiles/objc.dir/Protocol2.m.o CMakeFiles/objc.dir/associate.m.o CMakeFiles/objc.dir/blocks_runtime.m.o CMakeFiles/objc.dir/properties.m.o CMakeFiles/objc.dir/gc_none.c.o CMakeFiles/objc.dir/arc.mm.o CMakeFiles/objc.dir/objcxx_eh.cc.o  -lcxxrt && :
ld: error: duplicate symbol: __objc_msg_forward2
>>> defined at hooks.c
>>>            CMakeFiles/objc.dir/hooks.c.o:(__objc_msg_forward2)
>>> defined at sendmsg2.c
>>>            CMakeFiles/objc.dir/sendmsg2.c.o:(.data+0x10)

ld: error: duplicate symbol: __objc_msg_forward3
>>> defined at hooks.c
>>>            CMakeFiles/objc.dir/hooks.c.o:(__objc_msg_forward3)
>>> defined at sendmsg2.c
>>>            CMakeFiles/objc.dir/sendmsg2.c.o:(.data+0x8)

ld: error: duplicate symbol: _objc_selector_type_mismatch
>>> defined at hooks.c
>>>            CMakeFiles/objc.dir/hooks.c.o:(_objc_selector_type_mismatch)
>>> defined at sendmsg2.c
>>>            CMakeFiles/objc.dir/sendmsg2.c.o:(.bss+0x0)

ld: error: duplicate symbol: _objc_selector_type_mismatch2
>>> defined at hooks.c
>>>            CMakeFiles/objc.dir/hooks.c.o:(_objc_selector_type_mismatch2)
>>> defined at sendmsg2.c
>>>            CMakeFiles/objc.dir/sendmsg2.c.o:(.data+0x18)

ld: error: duplicate symbol: objc_proxy_lookup
>>> defined at hooks.c
>>>            CMakeFiles/objc.dir/hooks.c.o:(objc_proxy_lookup)
>>> defined at sendmsg2.c
>>>            CMakeFiles/objc.dir/sendmsg2.c.o:(.data+0x0)
cc: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

I've tried to dig through the source code, but I'm unable to figure out exactly how to fix it. All of these are in objc/hooks.h, where they are prefixed with OBJC_HOOK, which is defined to OBJC_PUBLIC extern. However, when hooks.h is included in hooks.c, OBJC_HOOK is defined to nothing, meaning that the symbols are no longer extern. These symbols are also defined in sendmsg2.c as IMP (*__objc_msg_forward2)(id, SEL) = forward2; (as an example), and I believe this is causing the duplicate symbols. It might be that it is enough to declare them extern in sendmsg2.c as well, but I can't figure out what IMP is in the definition above, and I'm unsure what the implication of having extern IMP or IMP extern would be.

davidchisnall commented 4 years ago

We probably have to remove the automatic bit in hooks.c, since that’s the one with common linkage. All of these are a bit ugly, we should add an api for registering callbacks and deprecate the exported globals.