有选择地禁用库中的死代码消除
selectively disable dead code elimination in a library
我有很多cpp文件,有的文件有自己订阅事件的功能。不幸的是,如果没有明显的函数调用,大多数链接器将从编译单元中删除所有符号。有没有办法强制链接这些订阅功能?我不想完全禁用死代码剥离,因为我可能会错过其他翻译单元的很多机会。
Subscriber.cpp:
Event &someEvent();
void doSomething()
{
printf("doing something\n");
}
class Initializer
{
public: Initializer()
{
// I need this function to be kept
someEvent().subscribe(&doSomething);
}
} initializer;
Main.cpp:
Event &someEvent();
int main()
{
someEvent().dispatch();
}
谢谢
编辑:
这是一个重现版本:https://github.com/malytomas/deadCodeElimination
(感谢 Ayjay 的帮助,即使 his/her 示例没有重现问题。)
该问题仅发生在库中。
(感谢 Employed Russian 提出这个问题。)
Unfortunately, most linkers will eliminate all symbols from compilation units if there is no apparent function call into them.
你错了:一个 link 会那样做的 link 人将是一个坏的 link 人。链接器不垃圾收集注册全局构造函数或析构函数的代码。
最有可能发生的情况是,您的目标文件根本没有被选入 link(不是从存档库中提取)。这个 post 很好地解释了许多 link 用户用来确定什么被选中和什么没有被选中的算法。
更新:
既然我们可以看到重现,您的实际问题与死代码消除无关。正如我所怀疑的那样,subscriber.o
根本就没有从 libsubscriber.a
拉进来,因为 linker 认为没有理由这样做。
这是实际的 link 命令:
/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
我有很多cpp文件,有的文件有自己订阅事件的功能。不幸的是,如果没有明显的函数调用,大多数链接器将从编译单元中删除所有符号。有没有办法强制链接这些订阅功能?我不想完全禁用死代码剥离,因为我可能会错过其他翻译单元的很多机会。
Subscriber.cpp:
Event &someEvent();
void doSomething()
{
printf("doing something\n");
}
class Initializer
{
public: Initializer()
{
// I need this function to be kept
someEvent().subscribe(&doSomething);
}
} initializer;
Main.cpp:
Event &someEvent();
int main()
{
someEvent().dispatch();
}
谢谢
编辑:
这是一个重现版本:https://github.com/malytomas/deadCodeElimination (感谢 Ayjay 的帮助,即使 his/her 示例没有重现问题。)
该问题仅发生在库中。 (感谢 Employed Russian 提出这个问题。)
Unfortunately, most linkers will eliminate all symbols from compilation units if there is no apparent function call into them.
你错了:一个 link 会那样做的 link 人将是一个坏的 link 人。链接器不垃圾收集注册全局构造函数或析构函数的代码。
最有可能发生的情况是,您的目标文件根本没有被选入 link(不是从存档库中提取)。这个 post 很好地解释了许多 link 用户用来确定什么被选中和什么没有被选中的算法。
更新:
既然我们可以看到重现,您的实际问题与死代码消除无关。正如我所怀疑的那样,subscriber.o
根本就没有从 libsubscriber.a
拉进来,因为 linker 认为没有理由这样做。
这是实际的 link 命令:
/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