【问题标题】:simulating --whole-archive behavior on per symbol basis基于每个符号模拟 --whole-archive 行为
【发布时间】:2016-02-08 23:05:32
【问题描述】:

我熟悉使用静态存档时 --whole-archive 链接器选项的作用。

有没有办法通过某些符号属性或任何其他技巧在每个符号的基础上实现相同的效果?

为了清楚起见,假设我有一个 .a 有两个功能:

void foo() {}
void bar() {}

我想确保任何通过链接到此存档构建的可执行文件将始终具有 foo() 符号,无论是否使用 foo()。我同样不关心 bar()

谢谢。

【问题讨论】:

  • 也许有链接脚本?
  • sourceware.org/binutils/docs/ld/File-Commands.html INPUT "例如,如果你总是想在任何时候做一个链接时都包含 subr.o,但是你懒得把它放在每个链接命令行上,那么你可以将 `INPUT (subr.o)' 放入链接描述文件中。"

标签: gcc linker static-libraries elf


【解决方案1】:

您可以为此使用选项-u

gcc -O2 foo.c -o foo -umysymbol -lmylib

这会强制链接器将 mysymbol 视为未定义并通过从指定库链接它来解决它。

来自 ld 的手册页:

-u 符号

--undefined=符号

强制符号作为未定义符号输入到输出文件中。例如,这样做可能会触发附加的链接 来自标准库的模块。 `-u' 可以用不同的方式重复 用于输入其他未定义符号的选项参数。

【讨论】:

  • --undefined 看起来不错,但这意味着需要更改最终可执行文件的构建步骤。我希望找到一种方法来宣传图书馆本身的符号的公共性质
  • @MK 我明白,但我担心这几乎不可能。它总是反过来工作,主要的二进制触发符号链接。
【解决方案2】:

恐怕你需要修改你的链接来实现这一点。

您应该清楚存档中的实体 (.a) 可以与您的可执行文件链接或不链接的 单独的符号定义,但单独的存档成员, 是目标文件,每个都可以任意定义 许多符号。如果要链接存档中的符号,则链接整个 定义它的存档成员。1

链接档案的最大区别 (.a) 使用您的可执行文件并链接目标文件(.o)是 目标文件无条件地被链接,而归档成员 只有当它为至少一个符号提供定义时才会被链接 检查档案时已被引用但未定义。

因此,确保符号foo 被链接的普通、非迂回方式 无条件地链接一个定义它的 object 文件。没有 将档案成员 foo.o 标记为必须链接的方法,因为如果你 必须链接foo.o,你可以通过链接foo.o来实现。

因此,如果 foo 驻留在存档成员 foo.o 中,您可以 从存档中提取该成员:

ar x libthing.a foo.o

并将foo.o 添加到您的链接中,即使您没有foo 源 从中编译foo.o

如果有很多函数要无条件链接 那么您可以将它们全部从源代码编译成一个对象 文件,如果你有源文件,或者你可以收集所有的目标文件 将它们定义到您与--whole-archive 链接的单个存档中。

我希望找到一种方法来宣传图书馆本身的符号的公共性质

出于链接目的,库中只有公共符号:by 定义链接器可以看到的任何符号都是公共的。


[1] 如果您能够编译一个目标文件,该目标文件进入 你的链接,然后通过使用适当的编译器和链接器标志你 可以确保它可能贡献的冗余符号最终被丢弃 链接器。见this answer

【讨论】:

    【解决方案3】:

    以下似乎对我有用。

    在我知道总是调用我的库中的一个函数中,我执行以下操作:

    static volatile auto var = &foo
    

    现在,在创建存档或构建可执行文件时,无需更改链接中的任何内容,我看到可执行文件具有 foo 符号。

    【讨论】:

      猜你喜欢
      • 2015-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 2011-04-21
      • 2022-01-20
      • 2019-02-25
      相关资源
      最近更新 更多