如何与GCC进行弱连接工作?
似乎有3种方式告诉GCC弱连接符号:
__attribute__((weak_import))
-
__attribute__((weak))
-
#pragma weak symbol_name
这些都不适合我:
#pragma weak asdf extern void asdf(void) __attribute__((weak_import, weak)); ... { if(asdf != NULL) asdf(); }
我总是得到这样的链接错误:
未定义的符号: “_asdf”,引自: _asdf $ non_lazy_ptr在ccFA05kN.o中 ld:找不到符号 collect2:ld返回1退出状态
我在OS X 10.5.5上使用GCC 4.0.1。 我究竟做错了什么?
我只是调查了一下,并认为其他人可能会对我的发现感兴趣。
与weak_import的弱连接实际上只适用于动态库。 您可以使用静态链接(通过如上所述指定-undefined dynamic_lookup),但这不是一个好主意。 这意味着在运行时之前不会检测到任何未定义的符号。 我个人会在生产代码中避免这种情况。
这是一个Mac OS X终端会话,展示了如何使其工作:
这是fc
int f(int n) { return n * 7; }
这是什么
#include #include extern int f (int) __attribute__((weak_import)); int main() { if(f == NULL) printf("what, no f?\n"); else printf("f(8) is %d\n", f(8)); exit(0); }
从fc创建一个动态库:
$ cc -dynamiclib -o f.dylib fc
编译并链接动态库,列出动态库。
$ cc -o whatnof whatnof.c f.dylib $ otool -L whatnof whatnof: f.dylib (compatibility version 0.0.0, current version 0.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
运行whatnof看看会发生什么:
$ whatnof f(8) is 56
现在将f.dylib替换为空库(无符号):
$ mv f.dylib f.dylib.real $ touch null.c $ cc -dynamiclib -o f.dylib null.c
运行相同的whatnof看看会发生什么:
$ whatnof what, no f?
weak_import的基本思想(或“用例”)是它允许您链接一组动态(共享)库,但是然后针对相同库的早期版本运行相同的代码。 您可以检查函数是否为NULL,以查看它们是否在代码当前运行的特定动态库中受支持。 这似乎是Xcode支持的基本开发模型的一部分。 我希望这个例子很有用; 它帮助我放松了对Xcode设计的这一部分。
将-Wl,-flat_namespace,-undefined,dynamic_lookup
添加到用于执行最终链接的gcc编译器行。
您需要将MACOSX_DEPLOYMENT_TARGET变量设置为10.2或更高版本。 请参阅Apple的文档及其关于弱链接的技术说明。
从gcc doc手册:
弱
weak属性导致声明作为弱符号而不是全局符号发出。 这主要用于定义可以在用户代码中重写的库函数,尽管它也可以与非函数声明一起使用。 ELF目标支持弱符号,并且在使用GNU汇编器和链接器时也支持a.out目标。
这意味着对象合法化以覆盖弱符号(在另一个对象/库中定义)而不会在链接时获得错误。 不清楚的是你是否用弱符号链接库。 似乎您没有定义符号,并且库没有正确链接。