我发现了很多与消除死代码相反的问题,但是我找不到答案:
给出类似的类层次结构:
BaseView
+- Base2DView
+- Concrete2DView
+- Specialised2DView
我将所有文件链接到view_classes.a
中,然后添加实例化Concrete2DView
并生成view_renderer.so
的代码。接下来,我创建另一个实例化specialised_view_renderer.so
并列出Specialised2DView
作为依赖项的库view_renderer.so
。
但是,生成view_renderer.so
的过程已将Specialised2DView.cpp.o
文件作为未使用的代码删除,因为当我使用nm view_renderer.so
时什么都没出现。
[我知道链接到view_classes.a
或将Specialised2DView.cpp
移至specialised_view_renderer.so
项目都可以解决此问题,但这是传统的第三方代码,我可能不应该花太多时间。
因此,在构建Specialised2DView.cpp.o
时是否有简单的方法将view_renderer.so
或其中的类标记为不消除?如果有标准cmake
target_link_libraries()
行的选项,则加分。
因此,在构建view_renderer.so时,是否有一种简单的方法可以将Specialized2DView.cpp.o或其中的类标记为不消除?
是:
g++ -shared -o view_renderer.so ... \
-Wl,--whole-archive view_classes.a -Wl,--no-whole-archive
要了解为什么会发生这种情况以及解决方案为何起作用,您需要了解链接器用来选择要在链接中包括哪些对象的规则。一个很好的描述是here。
BaseView
+-- virtual void foo() = 0;
+- Base2DView
+-- virtual void foo() {...}
+- Concrete2DView
+-- virtual void foo() {...}
+- Specialised2DView
+-- void bar() {foo();}
如果我将叶子调用更改为:
+-- void bar() {Concrete2DView::foo();}
该代码已链接并正常运行。