5

我有一个 C++ 库,可以生成更大的代码,这是我真正期望的。从不到 50K 行的源代码中,我得到几乎 4 MB 的共享对象和推送 9 的静态存档。这是有问题的,因为库二进制文件非常大,而且更糟糕的是,即使是简单的应用程序链接到它通常也会获得 500 到 1000 KB 的代码大小。使用 -Os 之类的标志编译库在一定程度上有所帮助,但不是非常有用。

我还尝试了 GCC 的 -frepo 命令(尽管我看到的所有文档都表明在 Linux collect2 上无论如何都会合并重复的模板)和对似乎“可能”重复很多的模板进行显式模板实例化,但没有两种情况下的实际效果。当然,我说“可能”是因为,与任何类型的分析一样,这样的盲目猜测几乎总是错误的。

是否有一些工具可以轻松分析代码大小,或者我可以通过其他方式找出占用这么多空间的原因,或者更一般地说,我应该尝试的任何其他事情?在 Linux 下工作的东西是理想的,但我会尽我所能。

4

3 回答 3

7

如果您想找出可执行文件中的内容,请询问您的工具。打开 ld 链接器的 --print-map(或 -M)选项以生成一个映射文件,显示它在内存中的内容和位置。为静态链接示例执行此操作可能会提供更多信息。

如果您不直接调用 ld,而仅通过 gcc 命令行调用,则可以通过在它们前面加上-Wl,.

于 2009-10-13T17:56:48.493 回答
2

在 Linux 上,链接器肯定会合并多个模板实例。

确保您没有测量调试二进制文件(调试信息可能占最终二进制文件大小的 75% 以上)。

减少最终二进制大小的一种技术是使用-ffunction-sectionsand进行编译-fdata-sections,然后使用-Wl,--gc-sections.

如果您使用[gold][1](新的 ELF-only 链接器,binutils 的一部分)的开发版本,并与-Wl,--icf

另一种有用的技术是减少共享库“导出”的符号集(默认情况下所有内容都导出),通过__attribute__((visibility(...)))或使用链接器脚本。详细信息在这里(参见“出口控制”)。

于 2009-10-14T03:12:30.373 回答
1

一种非常粗略但非常快速的方法是查看目标文件的大小。并非目标文件中的所有代码都会编译成最终的二进制文件,因此可能会出现一些误报,但它可以很好地了解热点的位置。一旦你找到了最大的目标文件,你就可以使用objdumpnm.

于 2009-10-13T20:51:57.600 回答