剥离C++库中的应用程序不需要的代码
Stripping C++ library of not required code for an application
我有一个依赖于许多库的应用程序。我正在从 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中,我发现跳转到定义和快速简便的"书签"是关键功能。
- 我可以在 iOS 或 mac 应用程序中使用C++代码吗?
- 从运行服务的应用程序代码中提取窗口句柄
- 使用本机 C++ 应用程序中的 C# 代码
- 使用代码在 AWS 开发工具包C++控制台应用程序上设置凭证
- 使用全局 IP 地址时,C++ winsock 2 应用程序中的代码是否必须更改?
- 我在哪里编写在退出 C++ 窗口窗体应用程序之前执行的代码部分
- 为什么在Visual Studio中用c ++编写GUI应用程序的代码与控制台应用程序的代码不同?
- 剥离C++库中的应用程序不需要的代码
- OpenGL 应用程序退出,退出代码为 -1073741515 (0xC0000135)
- DoModal 主应用程序随机返回 -1 代码
- 我可以将C++代码(或用C++编写的库)与混合移动应用程序代码混合使用吗
- 用GCC编译FreeRTOS,用G++编译应用程序代码
- 对于高度优化的矩阵多应用程序代码,MSVC和GCC之间的性能差异
- 与GLSL相关的OpenGL应用程序代码
- 仅使用 DLL *.h 头文件构建(compile.link)应用程序代码,并在运行时加载 DLL 实现(显式链接)
- Qt-正确设计应用程序代码
- 无法编译和执行控制台应用程序代码块
- OpenGL应用程序代码在不同操作系统之间的可移植性
- 将MFnParticleSystem添加到代码中时,Maya应用程序代码将不会编译
- GUI /控制台应用程序代码管理(c++ /Qt)