【问题标题】:Override weak symbols in static library覆盖静态库中的弱符号
【发布时间】:2014-05-29 14:06:33
【问题描述】:

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

【问题讨论】:

    标签: c gcc ld unix-ar


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 我认为在嵌入式系统(基本上没有操作系统)上使用共享库是不可能的
    • @Quentin 最后一段是简短的“当弱/强分辨率发生时”。我会改写段落
    • 根据你的解释,应该可以通过从lib1.clib2.c创建一个独特的.o文件来解决这个问题,然后把它放在.a中(连同其他.o文件),对吗?
    • @Quentin 归结为链接排序问题 - 使用 .a 时,如果您确保所有强定义出现在弱定义之前,那么您将获得所需的库行为在弱定义之前采用强定义。这意味着要么在存档中移动它们,要么确保使用按您想要的顺序添加的 .o 文件创建存档 - 所以在这个简单的示例中,当您创建存档时,您将使用:ar rc libhandlers.a lib2.o lib1.o
    • 我不相信您可以从两个 .c 文件创建单个 .o - 如果您使用 -c 编译,编译器将为每个 .c 生成单独的 .o 文件/跨度>
    猜你喜欢
    • 2012-10-16
    • 1970-01-01
    • 2014-01-03
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 2011-11-04
    相关资源
    最近更新 更多