解压后的Linaro GCC 6.2-2016.11工具链占用了近3.4 GB的磁盘空间,我希望将其缩小。我的目标是 armv7-a + vfpv3 + hard_float 所以我已经删除了我不需要的内容(例如ld.gold
,Thumb
的库,v8-a
,{ {1}}等)但它仍占据近1 GB。
所以我想使用strip
工具从其二进制文件中删除多余的信息。
我的主要问题是如何在这种情况下正确有效地使用 strip 安全?
一般情况下,我们在工具链中有不同的二进制文件,我们可以应用v7ve
:strip
,*.exe
,*.a
。
我可以判断我可以将*.o
(删除所有符号)仅应用于strip -s
个文件(例如 arm-eabi-gcc.exe )。 我是对的吗?
是否可以将*.exe
应用于库(例如 libgcc.a )?
据我所知(参见上面的示例),可能需要库中的符号进行进一步处理。
如果是,我应该使用strip
代替(仅删除调试符号)吗?
下面的例子说明了这些问题,并揭示了更多。
假设我们有三个文件:
--strip-debug
通常我们只是单独编译每个文件以获取可以链接在一起的目标文件:
// main.c:
#include "libgcc_test.h"
int main(void)
{
do_something();
return 0;
}
// libgcc_test.c:
void do_something(void)
{
return;
}
// libgcc_test.h:
void do_something(void);
通过分析目标文件,我们可以看到 do_something 符号在 libgcc_test.o 中定义,并在 main.o 中未定义,如预期:
$ ./arm-eabi-gcc.exe main.c -c
$ ./arm-eabi-gcc.exe libgcc_test.c -c
如果我们将$ ./arm-eabi-nm.exe main.o
U do_something
00000000 T main
$ ./arm-eabi-nm.exe libgcc_test.o
00000000 T do_something
应用于这两个文件或仅应用于 main.o 并尝试将它们链接起来,那就可以了:
strip -s
但如果我们仅将$ ./arm-eabi-nm.exe main.o
arm-eabi-nm.exe: main.o: no symbols
$ ./arm-eabi-nm.exe libgcc_test.o
arm-eabi-nm.exe: libgcc_test.o: no symbols
$ ./arm-eabi-ld.exe libgcc_test.o main.o -o main
arm-eabi-ld.exe: warning: cannot find entry symbol _start; defaulting to 00008000
应用于 libgcc_test.o ,则链接器会生成错误消息:
strip -s
据我所知,目标文件中存在未解析的符号会强制链接器解析它。 如果我在链接之前从目标文件中删除此符号会发生什么?
在将符号链接在一起之前从目标文件中删除符号是否正确和安全?如果是,可以删除哪些符号?
在实际项目中,如果我们将$ ./arm-eabi-strip.exe -s libgcc_test.o
$ ./arm-eabi-ld.exe libgcc_test.o main.o -o main
arm-eabi-ld.exe: warning: cannot find entry symbol _start; defaulting to 00008000
main.o: In function `main':
main.c:(.text+0x8): undefined reference to `do_something'
应用于工具链库( libgcc.a , libc.a , libm.a , librdimon.a 等)它在链接阶段同样产生了很多strip -s
个消息。
但是如果我们使用"undefined reference to..."
选项,链接器会为--strip-debug
之类的库生成消息。如果我们还原图书馆,它就会成功地联系起来。
在这种情况下skipping incompatible libgcc.a when searching for -lgcc
消息的含义是什么?
感谢您的帮助。
答案 0 :(得分:1)
总结一下我是怎么做到的。也许对某人有用。
我刚删除了不必要的库/可执行文件,并仅将strip -s
应用于*.exe
个文件。
之后,所有工具链似乎都是 ~230 MB 。