停止共享库链接丢弃未使用的 类

Stop shared library linking dropping unused classes

我发现了很多关于消除死代码的相反问题的问题,但我找不到答案:

给定一个 class 层次结构,例如:

BaseView
 +- Base2DView
     +- Concrete2DView
         +- Specialised2DView

我link将所有文件一起放入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.

时没有任何结果

我知道 link反对 view_classes.a 或将 Specialised2DView.cpp 移动到 specialised_view_renderer.so 项目可以解决这个问题,但这是我遗留的第三方代码可能不应该 fiddle 太多。

那么,有没有一种简单的方法可以在构建view_renderer.so时标记Specialised2DView.cpp.o或其中的class不被淘汰?如果有标准 cmake target_link_libraries() 行的选项,则奖励积分。

So, is there an easy way to mark Specialised2DView.cpp.o or the class within as not to be eliminated when building the view_renderer.so?

是:

g++ -shared -o view_renderer.so ... \
  -Wl,--whole-archive view_classes.a -Wl,--no-whole-archive

要了解发生这种情况的原因以及解决方案为何有效,您需要了解 link 用户使用哪些规则来 select 将哪些对象包含在 link 中。一个好的描述是 here.

我得到的解决方案如下。在我拥有之前:

BaseView
 +-- virtual void foo() = 0;
 +- Base2DView
     +-- virtual void foo() {...}
     +- Concrete2DView
         +-- virtual void foo() {...}
         +- Specialised2DView
             +-- void bar() {foo();}

如果我将叶调用更改为:

             +-- void bar() {Concrete2DView::foo();}

代码已链接且 运行 没有问题。