【问题标题】:Is it possible to remove dead code from a static library?是否可以从静态库中删除死代码?
【发布时间】:2019-09-12 07:03:35
【问题描述】:

我想通过指定入口点从静态库中删除死代码。

例如:

lib1.c

int foo() { return 0; }
int bar() { return 0; }

lib2.c

#include "lib1.h"
int entry() {
    return foo();
}

new.a (lib1.a + lib2.a)

libtool -static -o new.a lib1.a lib2.a

我想让new.a包含int bar(),因为它在lib1.a的入口点中没有使用,我不打算直接使用lib2.a

这可能吗?

【问题讨论】:

  • 静态库实际上只不过是目标文件的存档(.a 代表“存档”)。你的libtool 命令正在做的是从档案lib1.alib2.a 中提取目标文件并将它们复制到新的档案new.alibtool 脚本及其运行的命令并没有真正检查(或有可能检查)或修改目标文件本身的内容。要删除未使用的代码,您必须在链接时执行此操作,this old question 显示了如何操作。
  • libtool 不会检查库的内容来识别未使用的函数,因为它的工作前提是new.a 应该导出与lib1.alib2.a 相同的函数。您需要手动从lib1.c 中删除有问题的函数,重建lib1.a,然后重新创建new.a

标签: c linker clang


【解决方案1】:

如果您使用-ffunction-sections(可能还有-fdata-sections)进行编译并使用-Wl,--gc-sections 链接,则未引用的函数将被删除。这与它们一开始不存在略有不同(例如,如果 bar 包含对其他函数或数据的引用,则可能导致包含它们的文件被拉入考虑,可能导致新的全局 ctors 或覆盖弱定义)但对于大多数用途来说足够接近。

另一方面,正确的方法是不要定义可以在同一个翻译单元(源文件)中独立使用的函数。将它们拆分为单独的文件,这会自动运行,无需特殊选项。

【讨论】:

  • 不需要编译链接到这些库的二进制文件吗?我的假设是您不能使用链接器生成另一个静态库。
  • @ldiqual:确实,它不会从库中删除不需要的函数,只会从与其链接的程序中删除。如果您真的需要从库中取出它,请遵循正确的解决方案并分离文件。然后,您可以对lib2.a 中的每个未定义符号进行(即自动化)链接跟踪,以准确确定您想要从lib1.a 中获得哪些.o 文件,并仅从lib1.a 中提取那些.o 文件,而不是复制整个文件事情。
猜你喜欢
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-28
相关资源
最近更新 更多