剥离C++库中的应用程序不需要的代码

Stripping C++ library of not required code for an application

本文关键字:应用程序 代码 不需要 C++ 剥离      更新时间:2023-10-16

我有一个依赖于许多库的应用程序。我正在从 ubuntu 机器上的源代码构建所有内容。我想删除应用程序不需要的任何函数/类。有什么工具可以帮助解决这个问题吗?

附言我想从库中删除源代码,而不仅仅是从目标文件中删除符号。

标准条带实用程序正是为此而创建的。

我现在在我自己的项目中对此进行了一些研究,并认为这值得一个完整的答案,而不仅仅是一个评论。 这个答案是基于苹果在macOS上的工具链(它使用clang,而不是gcc(,但我认为两者的工作方式大致相同。

这样做的关键是在构建库和可执行文件时启用"链接时间优化"。 这样做的机制实际上非常简单 - 只需在命令行上-flto传递给 gcc 和 ld。 这有两个效果:

  • 目标文件或存档中从未调用的代码(函数/方法(在最终可执行文件中被省略。
  • 链接器执行编译器可以执行的优化类型(例如函数内联(,但具有跨编译单元边界扩展的知识。

如果要链接到共享库,则不会有所帮助,但如果该共享库与其他(静态(库链接,这些库包含共享库从不调用的代码,则可能会有所帮助。

从好的方面来说,这使我的最终可执行文件的大小减少了大约 5%,我很高兴。 扬子晚报.

不利的一面是,我的对象文件的大小大约翻了一番,有时链接时间急剧增加(大约 100 倍(。 然后,如果我重新链接,它会快得多。 然而,这种行为可能是苹果工具链的一个特点。 也许它正在第一个链接的某个地方藏匿一些构建中间体。 在任何情况下,如果仅为发布版本启用此选项,则不应成为主要问题。

此处提供了有关控制优化的全套 gcc 命令行选项的更多详细信息:https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html。 在该页面中搜索flto以缩小搜索范围。

有关幕后花絮,请参阅:https://gcc.gnu.org/onlinedocs/gccint/LTO-Overview.html

编辑:

有关链接时间的更多信息。 当你链接时,Apple的链接器会在一个名为LTOCache的目录中创建一些文件。 我今天之前没有见过这些,所以这些看起来是第二次加速链接的构建中间体。 至于我的初始链接如此缓慢,这可能部分是由于,就我而言,这些链接是在SMB服务器上创建的。 但话又说回来,CPU已经用尽了,所以也许没有。

好的,现在我更好地理解了 OP 的要求,我有另一个答案,我认为可能更适合他的需求。 我认为解决这个问题的方法是使用代码覆盖率工具。 毕竟,问题是确定您可以安全地摆脱它。 实际上剥离它很容易。

我的IDE(Visual Studio(内置了其中一个,但我认为OP使用的是gcc,所以第一个调用端口似乎是gcov。 有许多商业选择,但它们很昂贵。 这里还有一个可能有用的帖子。

当然,您需要的另一件事是一个程序,该程序可以练习您想要保留的库的所有部分,以便为您提供覆盖率报告,但听起来 OP 已经有了。 一个好的 IDE 也会有所帮助,因为它使代码导航变得更加容易。 在Visual Studio中,我发现跳转到定义和快速简便的"书签"是关键功能。