c - 覆盖静态库中的弱符号

标签 c gcc ld unix-ar

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

相关文章:

c - TCP C 程序自动重新连接到客户端

c - 如何使用 GCC 编译器强制执行结构位顺序?

c - argv : Sanitizing wildcards

c - Valgrind 读取大小无效

gcc - 无法编译: unrecognized relocation 0x2a in section text

c - 向结构体传递 null

c - 指针分配后错误的结构成员值

c - 数组定义 - 表达式必须有常量值

Eclipse:LD_LIBRARY_PATH、OpenJDK 和 libjpeg

linux - ld 在将 .asm 文件汇编和链接到 64 位可执行文件后找不到符号 _start 错误