【问题标题】:Can GNU ld be instructed to print which .o files are needed during a link?是否可以指示 GNU ld 打印链接期间需要哪些 .o 文件?
【发布时间】:2024-01-02 08:39:01
【问题描述】:

一点背景知识: 我正在尝试为嵌入式传感器系统构建 AVR 二进制文件,并且我正在运行接近我的大小限制。我使用了一些外部库来帮助我,但是当每个库编译成一个对象时它们相当大。我想把它们拉成更小的对象,这样只有我需要的功能才链接到我的程序中。通过拆分一个大型库,我已经设法将二进制大小减少了 2k。

知道在游戏的每个阶段使用了哪些对象会很有帮助,这样我就可以更有效地拆分它们。有没有办法让ld 打印它正在链接的对象?

【问题讨论】:

  • AFAIK ld 应该只链接实际有用的函数。旁注:你在使用 -Os 优化吗?
  • 是的,现在它一直上升到 -O3。我不明白为什么 ld 会引入额外的代码,但是当我拆分其中一个较大的库时,它显着减小了二进制大小。
  • 对生成的可执行文件使用nm -a。这将列出调试符号,包括 source 文件的名称。
  • 太棒了,非常有用。谢谢你的提示!编辑:它似乎也适用于关闭调试符号,所以我不必构建单独的二进制文件。
  • 不要使用-O3。使用-Os。第一个是性能,第二个是尺寸。

标签: c++ ld avr avr-gcc


【解决方案1】:

我不确定object 级别,但我相信您可以使用CFLAGS="-fdata-sections -ffunction-sections"LDFLAGS="-Wl,--gc-sections -Wl,--print-gc-sections"symbol 级别解决这个问题。这应该摆脱所有未引用符号的代码,并向您显示已删除的符号,如果由于某种原因您决定返回目标文件级别并想要识别仅包含已删除符号的目标文件,这可能会很有用。

更准确地说,我引用的编译器标志将要求编译器将每个函数或全局变量放在一个部分中,然后--gc-sections 链接器标志将删除所有未使用的部分。可能每个目标文件都包含自己的部分,即使其中的函数都共享一个部分。在这种情况下,单独的链接器标志应该满足您的要求:消除未使用的整个对象。 gcc 手册指出编译器标志会增加对象大小,虽然我希望最终的可执行文件不会受此影响,但我不确定,所以你应该自己尝试一下 LDFLAGS="-Wl,--gc-sections任何情况。

列出的选项名称可能是有用的关键字,可用于在 * 上搜索有关如何减小二进制文件大小的其他建议。 gc-sections 例如目前产生 62 场比赛。

【讨论】:

    最近更新 更多