I am currently facing a weak connection problem on Mac OS X 10.6.7 with Xcode 4.0.2.
robin@chameleon:/tmp/o$ gcc --version i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
As stated in the document http://developer.apple.com/library/mac/#technotes/tn2064/_index.html , we can use the gcc attribute ((weak_import)) for a weak link symbol. However, the following sample code always throws a compilation error. As below:
weak.c
#include <stdlib.h> #include <stdio.h> extern int SayHello() __attribute__((weak)); int main() { int result; if (SayHello!=NULL) { printf("SayHello is present!\n"); result=SayHello(); } else printf("SayHello is not present!\n"); }
The error message is as follows:
robin@chameleon:/tmp/o$ gcc weak.c Undefined symbols for architecture x86_64: "_f", referenced from: _main in cceOf2wN.o (maybe you meant: __dyld_func_lookup) ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status
Even if the -undefined dynamic_lookup option is used, it still throws an error at runtime:
robin@chameleon:/tmp/o$ gcc -undefined dynamic_lookup weak.c robin@chameleon:/tmp/o$ ./a.out dyld: Symbol not found: _SayHello Referenced from: /private/tmp/o/./a.out Expected in: dynamic lookup Trace/BPT trap
The message nm -m "a.out" is as follows:
robin@chameleon:/tmp/o$ nm -m a.out | grep Hello (undefined) external _SayHello (dynamically looked up)
The following was expected:
(undefined) weak external _SayHello (dynamically looked up)
However, when I compile Ubuntu with gcc (Ubuntu / Linaro 4.4.4-14ubuntu5) 4.4.5, it works as expected:
weak.c
#include <stdlib.h> #include <stdio.h> extern int SayHello() __attribute__((weak)); int main() { int result; if (SayHello!=NULL) { printf("SayHello is present!\n"); result=SayHello(); } else printf("SayHello is not present!\n"); }
robin @robinz: / tmp / o $ gcc weak.c robin @robinz: / tmp / o $. / a.out SayHello no!
SayHello character in binary format:
robin@robinz:/tmp/o$ nm a.out | grep Hello w SayHello
"w" A symbol is a weak symbol that has not been specifically marked as a symbol of a weak object.
And I am testing old xcode 3.2, it works as expected.
Can someone help me with this? Was it an ld error?
And I found more interesting things. When I create a dummy library to export the SayHello symbol to a dynamic lib, it works as expected.
dummy.c
int SayHello() { return; }
robin@chameleon:/tmp/o$ gcc -dynamiclib -o libdummy.dylib dummy.c robin@chameleon:/tmp/o$ gcc weak.c libdummy.dylib robin@chameleon:/tmp/o$ ./a.out SayHello is present!
If "libdummy.dylib" does not exist:
robin@chameleon:/tmp/o$ rm libdummy.dylib robin@chameleon:/tmp/o$ ./a.out SayHello is not present!
Works as expected! The weak character is now in the nm message, as expected:
robin@chameleon:/tmp/o$ nm -m a.out | grep Hello (undefined) weak external _SayHello (from libdummy)