覆盖静态库中的弱符号

Que*_*tin 8 c gcc ld unix-ar

我想从多个来源为我的项目创建一个静态.a库,其中一些定义弱函数,另一些实现它们.比方说我有:

lib1.c:

void defaultHandler()
{
    for(;;);
}
void myHandler() __attribute__((weak, alias ("defaultHandler")));
Run Code Online (Sandbox Code Playgroud)

lib2.c:

void myHandler()
{
    /* do my stuff here */
}
Run Code Online (Sandbox Code Playgroud)

然后我想把它们放到一个单独的库中,这样它对于最终应用程序来说似乎是透明的

$ ar -r libhandlers.a lib1.o lib2.o
Run Code Online (Sandbox Code Playgroud)

但是myHandler在libhandler中现在有2个符号:

$ nm libhandlers.a | grep "myHandler"
00000001 W myHandler
00000581 T myHandler
Run Code Online (Sandbox Code Playgroud)

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

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

有没有办法编译库,以便弱符号消失,如果提供强大的符号?

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

Pet*_*esh 11

这是.a图书馆工作方式的副产品- 它们只是.o文件的集合.

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

你可以通过实际制作相同的名称和强大来自己测试,你会看到完全相同的行为.

如果您希望首先解析强引用,然后将它们放在存档中,或者先创建一个单独的强存档,并在链接行中首先进行链接.

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

  • @Quentin当弱/强分辨率发生时,最后一段是短暂的.我会改写段落 (2认同)