【问题标题】:How to remove *ALL* unused symbols from a shared library?如何从共享库中删除 *ALL* 未使用的符号?
【发布时间】:2013-08-07 23:40:02
【问题描述】:

我有一个代码需要编译到共享库并从中删除所有未使用的代码,但我找不到合适的解决方案。这是一个简单的例子:

// test.cpp, compiled with GCC -fPIC -shared -fvisibility=hidden
#include <stdio.h>
class Foo {
    void bar();
};
void Foo::bar() { printf("hello"); } // unused and should be removed
// I'm using printf("hello") so I can detect the symbols with `strings`

__attribute__((visibility("default"))) void test() {} // this function is "used"

-fvisibility=hidden 使其默认隐藏所有功能,我手动使用__attribute__((visibility("default"))) 标记公共功能。但是,除非标记为static,否则隐藏函数不会被删除(显然,我不能对 C++ 方法执行此操作)。

无论我做什么,GCC 都会一直保留void Foo::bar()hello。有没有办法在不破解编译器的情况下删除这些符号? (是的,我正在考虑这一点!)

谢谢!

【问题讨论】:

  • 请解释为什么你想这样做。
  • 呃,把所有的函数都声明为静态的?
  • @MatsPetersson:这不适用于 C++ 成员函数。
  • @bmargulies:有很多似是而非的解释。它可能是一个受约束的环境,或者它可以链接到它使用一小部分的第三方静态库等。剥离未使用的符号也可能导致 dylib 依赖项消失,因此您实际上可以获得很多里程有时会这样。
  • 你能解释一下你想要达到的目标吗?这闻起来像 XY 问题:meta.stackexchange.com/questions/66377/what-is-the-xy-problem

标签: c++ c shared-libraries


【解决方案1】:

使用标志-ffunction-sections 编译。然后链接-Wl,--gc-sections。我认为这也可以通过 LTO 实现,我不确定细节。

请注意,dylib 中的所有公共符号都被认为是活动的。这种方式只会去除隐藏的符号。

【讨论】:

  • 这也有效,但我还发现了 GCC 的 -fwhole-program 标志,它基本上将每个函数都标记为静态,从而允许积极的代码删除 (gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html)
  • @user2662514:仅当您的库的源代码包含在单个文件中时才有效。
  • @user2662514:这个解决方案背后的解释是链接器不在符号级别而是在节级别(可能包含许多符号的节)进行检查。通过将-ffunction-sections 传递给gcc,您可以指示编译器在其自己的部分中发出每个函数;您应该期望它显着减慢链接阶段,但另一方面,链接器现在可以从库中剥离更多代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
  • 2014-01-09
  • 1970-01-01
  • 2011-07-19
相关资源
最近更新 更多