【问题标题】:LD: does --export-dynamic imply --whole-archive for a static lib if any of it's symbols are referenced?LD:如果引用了静态库中的任何符号, --export-dynamic 是否暗示 --whole-archive ?
【发布时间】:2022-01-20 04:35:01
【问题描述】:

我的主要可执行文件链接到一个静态库,其符号需要可用于通过 dlopen() 加载的动态库。我知道我需要使用-Wl,--export-dynamic,--whole-archive 标志才能使其工作。但是,在链接命令中指定了许多库,其中一些可能未使用,并且我在当前构建基础架构中通过 cmake 选择性地将 --whole-archive 应用到所需的库时遇到了困难。我所看到的是,如果只使用 -Wl,--export-dynamic 并且可执行文件调用感兴趣的静态库中的函数,那么整个库将被包含到为它指定 --whole-archive 的相同效果,这正是我需要。我可以依靠这种行为来隐式地将 --whole-archive 强加于可执行文件引用其符号的库吗?

【问题讨论】:

    标签: gcc linker


    【解决方案1】:

    我看到的是,如果只使用 -Wl,--export-dynamic 并且可执行文件调用感兴趣的静态库中的函数,那么整个库将被包含到与指定 --whole 相同的效果-存档,这正是我需要的。

    这不应该发生,而且很可能您误解了所看到的内容。

    例子:

    // foo.c
    int foo() { return 42; }
    
    // bar.c
    int bar() { return 24; }
    
    // main.c
    int main() { return foo() - 42; }
    
    gcc -w -c foo.c bar.c main.c
    ar ruv libfoobar.a foo.o bar.o
    
    gcc -Wl,--export-dynamic main.o -L. -lfoobar
    
    nm a.out | egrep ' (foo|bar)'
    000000000000113c T foo
    

    如您所见,整个libfoobar.a没有包含在可执行文件中。对比:

    gcc -Wl,--export-dynamic main.o -L. -Wl,--whole-archive -lfoobar -Wl,--no-whole-archive
    
    nm a.out | egrep ' (foo|bar)'
    0000000000001147 T bar
    000000000000113c T foo
    

    更新:

    如果我将函数 foo1() 添加到 foo.c,它会被拉入,但无论是否提供 --export-dynamic,它也会发生。

    这是意料之中的:链接器不会“拆分”单个 .o 文件——要么得到全部,要么什么都没有。

    您可以通过在编译时使用 -ffunction-sections(和 -fdata-sections 更好地衡量)和在链接时使用 -Wl,--gc-sections 来更改此行为。

    成本增加.o 大小和更长的链接时间。好处是可执行文件更小。

    【讨论】:

    • 谢谢,你的例子我也看到了。但是,如果我向 foo.c 添加一个函数 foo1() ,它将被拉入,但无论是否提供 --export-dynamic 都会发生这种情况。这让我觉得我观察到的误报可能与我们使用统一构建的事实有关。
    • @VladG 我更新了答案。
    • 我检查了有问题的 .a ,它实际上是由一个融合的 .cpp 文件构建的,所以我想根据你所说的,我很幸运,它很脆弱,但作为乐队也许可以接受帮助修复我的目的,需要考虑......
    • @VladG 如果答案完全回答了您的问题,请接受。我们在这里为布朗尼点工作:-)
    猜你喜欢
    • 1970-01-01
    • 2010-10-22
    • 2015-08-06
    • 2019-02-25
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    相关资源
    最近更新 更多