目前我在 Mac OS X 10.6.7 和 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)
正如文档http://developer.apple.com/library/mac/#technotes/tn2064/_index.html所说,我们可以使用 gcc属性((weak_import)) 作为弱链接符号。但是,以下示例代码总是会引发编译错误。如下:
弱.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@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
即使使用 option -undefined dynamic_lookup
,它仍然在运行时抛出错误:
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
“a.out”的nm -m
消息如下:
robin@chameleon:/tmp/o$ nm -m a.out | grep Hello
(undefined) external _SayHello (dynamically looked up)
预期如下:
(undefined) weak external _SayHello (dynamically looked up)
但是,当我使用 gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 在 Ubuntu 上编译时,它按预期工作:
弱.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 不存在!
SayHello 的二进制符号为:
robin@robinz:/tmp/o$ nm a.out | grep Hello
w SayHello
"w" 该符号是一个弱符号,没有被专门标记为弱对象符号。
我测试了旧的 xcode 3.2,它按预期工作。
有人可以帮我吗?是ld的bug吗?
我发现了更多感兴趣的东西。当我创建一个虚拟库以在动态库中导出 SayHello 符号时,它按预期工作。
假人.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!
如果“libdummy.dylib”不存在:
robin@chameleon:/tmp/o$ rm libdummy.dylib
robin@chameleon:/tmp/o$ ./a.out
SayHello is not present!
按预期工作!弱符号现在在 nm 消息中,如预期的那样:
robin@chameleon:/tmp/o$ nm -m a.out | grep Hello
(undefined) weak external _SayHello (from libdummy)