在每个符号的基础上模拟 --whole-archive 行为

simulating --whole-archive behavior on per symbol basis

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

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

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

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

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

谢谢。

您可以为此使用选项 -u

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

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

来自 ld 的联机帮助页:

-u symbol

--undefined=symbol

Force symbol to be entered in the output file as an undefined symbol. Doing this may, for example, trigger linking of additional modules from standard libraries. `-u' may be repeated with different option arguments to enter additional undefined symbols.

恐怕您需要修改您的 link年龄才能达到此目的。

您应该清楚存档中的实体 (.a) 可以 linked,或不 linked,你的可执行文件不是 个别符号定义但个别 存档成员 , 是目标文件,每一个都可以任意定义 许多符号。如果你想 link 档案中的一个符号,你 link 整个 定义它的存档成员。1

link归档文件 (.a) 之间的最大区别 与您的可执行文件和 linking 目标文件 (.o) 是 目标文件 无条件地 linked,而存档成员 仅当它为至少一个符号提供定义时才会被 linked 在检查存档时已被引用但未定义。

因此确保符号 foo 被 linked 的普通的、非迂回的方式 无条件地是 link 定义它的 object 文件。没有 将存档成员 foo.o 标记为 的方法必须 linked 因为,如果你 必须 link foo.o,你可以通过 linking foo.o 来完成。

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

ar x libthing.a foo.o

并将 foo.o 添加到您的 link 年龄,即使您没有 foo 来源 从中编译 foo.o.

如果有很多功能你要link无条件 那么您可以将它们全部从源代码编译成一个对象 文件,如果你有源代码,或者你可以收集所有的目标文件 将它们定义到您 link 和 --whole-archive.

的单个存档中

I was hoping to find a way to advertise the public nature of the symbol in the library itself

出于 link年龄的目的,图书馆中只有 public 符号:作者 定义 linker 可以看到的任何符号都是 public。


[1] 如果您能够编译进入的目标文件 您的 link 年龄,然后通过使用适当的编译器和 linker 标记您 可以确保它可能贡献的冗余符号最终被丢弃 link 呃。参见 this answer

以下似乎对我有用。

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

static volatile auto var = &foo

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