有选择地禁用库中的死代码消除

selectively disable dead code elimination in a library

本文关键字:代码 选择地      更新时间:2023-10-16

我有很多cpp文件,其中一些具有自行订阅事件的函数。不幸的是,如果没有明显的函数调用,大多数链接器将从编译单元中删除所有符号。有没有办法强制链接这些订阅功能?我不想完全禁用死代码剥离,因为我可能会错过其他翻译单元的很多机会。

订户.cpp:

Event &someEvent();
void doSomething()
{
printf("doing somethingn");
}
class Initializer
{
public: Initializer()
{
// I need this function to be kept
someEvent().subscribe(&doSomething);
}
} initializer;

主.cpp:

Event &someEvent();
int main()
{
someEvent().dispatch();
}

谢谢

编辑:

下面是一个重现版本:https://github.com/malytomas/deadCodeElimination (感谢 Ayjay 的帮助,即使他/她的示例没有重现该问题。

此问题仅发生在库中。 (感谢俄语提出这个问题。

不幸的是,如果没有明显的函数调用,大多数链接器将从编译单元中删除所有符号。

你错了:一个可以做到这一点的链接器将是一个损坏的链接器。链接器不会对注册全局构造函数或析构函数的代码进行垃圾回收。

最有可能发生的事情是,您的目标文件甚至没有被选中到链接中(而不是从存档库中提取(。这篇文章很好地解释了许多链接器用来确定选择和未选择的算法。

更新:

现在我们可以看到一个重现,您的实际问题与死代码消除无关。正如我所怀疑的,subscriber.o根本没有从libsubscriber.a拉入,因为链接器找不到这样做的理由。

这是实际的链接命令:

/usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cpp.o  -o main libsubscriber.a

这是您想要的命令:

/usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cpp.o  -o main 
-Wl,--whole-archive libsubscriber.a -Wl,--nowhole-archive

我不知道如何使用CMake实现这一目标,对不起。

或者,您也可以通过以下方式达到预期效果:

/usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cpp.o  -o main 
-u _Z19forceLinkSubscriberv libsubscriber.a