我想从多个来源为我的项目创建一个静态 .a 库,其中一些定义了弱函数,而另一些实现了它们。比方说我有:
lib1.c :
void defaultHandler()
{
for(;;);
}
void myHandler() __attribute__((weak, alias ("defaultHandler")));
lib2.c :
void myHandler()
{
/* do my stuff here */
}
然后我想把它们放在一个单独的库中,这样它对最终应用程序来说似乎是透明的
$ ar -r libhandlers.a lib1.o lib2.o
但是现在 libhandlers 中有 2 个符号 myHandler
:
$ nm libhandlers.a | grep "myHandler"
00000001 W myHandler
00000581 T myHandler
然后在使用lib的时候,链接了弱引用。目前我唯一的解决方案是不将其包含在库 lib2.c
中,而是将其作为源代码添加到应用程序的 Makefile 中……这并不令人满意,因为我只想提供几个库来使用而不是一大堆文件。
--whole-archive
选项也不令人满意,因为我在嵌入式系统上工作,我不想包含所有我不需要的东西。
有没有办法编译库,以便在提供强符号时弱符号消失?
注意:我使用的是 arm-none-eabi-gcc v4.8
最佳答案
这是 .a
库工作方式的副产品 - 它们只是 .o
文件的集合。
在编译链接时发生的是,对名称的第一个引用被解析为弱引用,而强名称永远不会被查看。
您可以通过实际创建相同的名称和强名称来自行测试,您会看到完全相同的行为。
如果您希望先解决强引用,则将它们放在存档的较早位置,或者创建一个单独的强存档并在链接行中首先链接它。
虽然不能直接适用于您的情况,但由于您使用的是嵌入式环境,因此在创建/使用 .so
动态库而不是 时,弱引用和强引用会正确生效。一个
文件。当你创建.so时,所有组成库的弱引用都不会产生错误,最终产品只会使用其中的一个;如果在任何地方都有强定义,那么它会被使用,而不是任何弱定义(这只有在您创建 .so
时链接所有 时才能正常工作。 o
文件单独组成,或者在创建 .so
时使用 --whole-archive
如果链接到 .a
).
关于c - 覆盖静态库中的弱符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23079997/