我想从多个来源为我的项目创建一个静态.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
但是在libhandler中现在有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
答案 0 :(得分:9)
这是.a
库工作方式的副产品 - 它们只是.o
个文件的集合。
在编译链接时发生的事情是,对名称的第一次引用被解析为弱引用,并且强名称永远不会被查看。
您可以通过实际制作相同的名称和强大来自己测试,并且您将看到完全相同的行为。
如果您希望首先解析强引用,然后将它们放在存档中,或者在链接行中创建一个单独的强存档和链接。
虽然不能直接适用于您的情况,但由于您使用的是嵌入式环境,因此在创建/使用.so
动态库而不是.a
存档时,弱引用和强引用会正常生效。当您创建.so时,构成库的所有弱引用都不会生成错误,并且只有其中一个将用于最终产品;如果在任何地方有一个强大的定义,那么它会被使用而不是任何弱的(如果你在创建一个.so
时,你只能链接所有.o
文件如果链接到--whole-archive
,则在创建.so
时单独使用.a
。