【问题标题】:including static libraries with -all_load flag包括带有 -all_load 标志的静态库
【发布时间】:2013-05-31 08:48:29
【问题描述】:

在什么情况下你需要 -all_load 标志?

假设我有类似的东西

g++ source.cpp -o test libA.a libB.a libC.a

据我回忆,如果存在对 source.cpp 中使用的符号的一些引用 在说libB.a 文件中,那么libB.a 将被链接(只是该库中的那个符号或整个代码?)并且libA.a 和libC.a 将被忽略(它们的代码不会出现在最终的可执行文件中)。

  • 当我如下使用 -all_load 标志时其他库会发生什么

    g++ source.cpp -o test -Wl,-all_load libA.a libB.a libC.a

  • 'strip' 命令如何影响带有 all_load 标志的输出?

【问题讨论】:

    标签: macos gcc compiler-construction g++ clang


    【解决方案1】:

    -all_load 用于当您想要链接(到链接器)不必要的编译单元时。例如,也许您将在运行时动态访问静态库中您知道地址但实际上并未进行任何显式函数调用的函数。你会怎么做?好吧,编译器可以通过将一堆函数指针存储在可执行文件中以在运行时读取来帮助您,然后您将构建一个查找系统以使用字符串查找这些函数,然后您将整个事情称为 Objective -C,这可能是-all_load 最常见的用户(至少如果谷歌是任何指南的话)。

    在 ObjC 中最常见的情况是当您在自己的编译单元中有一个类别时。编译器可能无法告诉您引用它,因此不会链接它。所以 ObjC 程序员比其他类 C 程序员更频繁地使用-all_load(或-force_load)。事实上,-all_load 是 gcc 中特定于达尔文的扩展。

    但在某些情况下,人们可能希望在 ObjC 之外使用 -all_load。例如,libA 和 libB 中可能存在一些相互依赖关系。考虑这种情况:

    • source.cpp 需要 A() 和 B()

    • libA 在a.o 中定义A(),在aprime.o 中定义Aprime()

    • libB 在b.o 中定义B() 并需要Aprime()

    这通常不会链接 (*)。编译器将从source.o 开始并列出要求:A() 和B()。然后它会查看 libA 并看到它定义了A(),因此它将链接a.o(但不是aprime.o)。然后它会查看 libB 并看到它定义了B() 并需要Aprime()。它现在已用完库,并且尚未解析 Aprime()。它失败。

    (*) 实际上,clang 会这样,因为 clang 对此非常聪明。但至少在 4.6 之前它不会使用 g++。

    最好的解决方案是重新排序,以便 libB 排在第一位 (**)。但如果依赖关系是循环的,你可能会完全陷入困境。 -all_load 和 -force_load 让您可以通过关闭链接器的优化来解决这些情况。

    (**) 真正最好的解决方案通常是重新设计你的库以避免这种相互依赖,但这可能希望太高了。

    如果你想解决这个问题,请参阅https://gist.github.com/rnapier/5710509。

    strip 只是从可执行文件中删除符号。这与静态链接和-all_load 无关(尽管它确实会影响动态链接)。 strip(1) 对此有很多讨论。

    【讨论】:

    • -force_load 不适用于较新版本的 clang.. 据我所知...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 2015-02-23
    相关资源
    最近更新 更多