剥线工具的正确使用
Correct usage of strip tool
解压后的 Linaro GCC 6.2-2016.11 工具链占用将近 3.4 GB 的磁盘空间 space,我想缩小它。我的目标是 armv7-a+vfpv3+hard_float 所以我已经删除了不需要的东西(比如 ld.gold
,Thumb
的库,v8-a
、v7ve
等)但它仍然占用将近 1 GB。
所以我想使用strip
工具从它的二进制文件中删除冗余信息。
我的主要问题是如何在这种情况下安全、正确、高效地使用strip?
一般来说,我们可以在工具链中应用不同的二进制文件 strip
:*.exe
、*.a
、*.o
.
据我判断,我只能将 strip -s
(删除所有符号)应用于 *.exe
文件(i.g。arm-eabi-gcc.exe)。 我说的对吗?
是否可以将strip
应用于库(i.g。libgcc.a)?
据我了解(参见上面的示例),可能需要进一步处理库中的符号。
如果是,我应该改用 --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);
一般来说,我们只是分别编译每个文件以获得可以link一起编译的目标文件:
$ ./arm-eabi-gcc.exe main.c -c
$ ./arm-eabi-gcc.exe libgcc_test.c -c
通过分析目标文件可以看出,do_something符号在libgcc_test.o中定义,在libgcc_test.o中未定义main.o,符合预期:
$ ./arm-eabi-nm.exe main.o
U do_something
00000000 T main
$ ./arm-eabi-nm.exe libgcc_test.o
00000000 T do_something
如果我们将 strip -s
应用于两个文件或仅应用于 main.o 并尝试 link 它们,它有效:
$ ./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
但是,如果我们仅将 strip -s
应用于 libgcc_test.o,linker 会产生错误消息:
$ ./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'
据我所知,目标文件中存在未解析的符号会迫使 linker 解析它。 如果我在 linking 之前从目标文件中删除这个符号会怎样?
在 link将它们组合在一起之前从目标文件中删除符号是否正确且安全?如果是,哪些符号可以去掉?
在实际项目中,如果我们将strip -s
应用于工具链库(libgcc.a,libc.a, libm.a, librdimon.a 等)它同样在 linking阶段。
但是如果我们使用 --strip-debug
选项,linker 会为 skipping incompatible libgcc.a when searching for -lgcc
这样的库生成消息。如果我们还原库,它会 link 成功。
在这种情况下,skipping incompatible...
消息是什么意思?
感谢您的帮助。
只是总结一下我是怎么做到的。也许对某人有用。
我刚刚删除了不必要的 libraries/executables 并仅将 strip -s
应用于 *.exe
个文件。
在那之后所有的工具链似乎都是 ~230 MB。
解压后的 Linaro GCC 6.2-2016.11 工具链占用将近 3.4 GB 的磁盘空间 space,我想缩小它。我的目标是 armv7-a+vfpv3+hard_float 所以我已经删除了不需要的东西(比如 ld.gold
,Thumb
的库,v8-a
、v7ve
等)但它仍然占用将近 1 GB。
所以我想使用strip
工具从它的二进制文件中删除冗余信息。
我的主要问题是如何在这种情况下安全、正确、高效地使用strip?
一般来说,我们可以在工具链中应用不同的二进制文件 strip
:*.exe
、*.a
、*.o
.
据我判断,我只能将 strip -s
(删除所有符号)应用于 *.exe
文件(i.g。arm-eabi-gcc.exe)。 我说的对吗?
是否可以将strip
应用于库(i.g。libgcc.a)?
据我了解(参见上面的示例),可能需要进一步处理库中的符号。
如果是,我应该改用 --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);
一般来说,我们只是分别编译每个文件以获得可以link一起编译的目标文件:
$ ./arm-eabi-gcc.exe main.c -c
$ ./arm-eabi-gcc.exe libgcc_test.c -c
通过分析目标文件可以看出,do_something符号在libgcc_test.o中定义,在libgcc_test.o中未定义main.o,符合预期:
$ ./arm-eabi-nm.exe main.o
U do_something
00000000 T main
$ ./arm-eabi-nm.exe libgcc_test.o
00000000 T do_something
如果我们将 strip -s
应用于两个文件或仅应用于 main.o 并尝试 link 它们,它有效:
$ ./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
但是,如果我们仅将 strip -s
应用于 libgcc_test.o,linker 会产生错误消息:
$ ./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'
据我所知,目标文件中存在未解析的符号会迫使 linker 解析它。 如果我在 linking 之前从目标文件中删除这个符号会怎样?
在 link将它们组合在一起之前从目标文件中删除符号是否正确且安全?如果是,哪些符号可以去掉?
在实际项目中,如果我们将strip -s
应用于工具链库(libgcc.a,libc.a, libm.a, librdimon.a 等)它同样在 linking阶段。
但是如果我们使用 --strip-debug
选项,linker 会为 skipping incompatible libgcc.a when searching for -lgcc
这样的库生成消息。如果我们还原库,它会 link 成功。
在这种情况下,skipping incompatible...
消息是什么意思?
感谢您的帮助。
只是总结一下我是怎么做到的。也许对某人有用。
我刚刚删除了不必要的 libraries/executables 并仅将 strip -s
应用于 *.exe
个文件。
在那之后所有的工具链似乎都是 ~230 MB。