11

我想从多个来源为我的项目制作一个静态 .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

但是现在myHandlerlibhandlers 中有 2 个符号:

$ nm libhandlers.a | grep "myHandler"
00000001 W myHandler
00000581 T myHandler

然后在使用lib时,链接弱引用。我目前唯一的解决方案是不包含在库中,lib2.c而是将其作为源添加到应用程序的 Makefile 中……这并不令人满意,因为我只想提供几个库来使用而不是一大堆文件。

--whole-archive选项也不令人满意,因为我在嵌入式系统上工作并且我不想包含所有我不需要的东西。

有没有办法编译库,以便在提供强符号时弱符号消失?

注意:我正在使用 arm-none-eabi-gcc v4.8

4

1 回答 1

12

这是.a库工作方式的副产品——它们只是.o文件的集合。

在编译链接时发生的情况是,对名称的第一次引用被解析为弱引用,而强名称永远不会被查看。

您可以通过实际创建相同的名称和强大的名称来自己测试,您会看到完全相同的行为。

如果您希望首先解决强引用,则将它们更早地放在存档中,或者创建一个单独的强存档并首先在链接行中链接。

.so虽然不直接适用于您的情况,但当您使用嵌入式环境时,弱引用与强引用在创建/使用动态库而不是.a存档时会正确生效。创建 .so 时,构成库的所有弱引用都不会产生错误,最终产品只会使用其中的一个;如果在任何地方都有一个强定义,那么它会被使用而不是任何弱定义(这只有在你创建 a 时才能正常工作,.so你单独链接所有.o组成它的文件,或者--whole-archive在创建时使用.so如果链接到 a .a)。

于 2014-04-15T12:36:51.563 回答