我有很多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