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

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