分享

linux下使用strip如何对库和可执行文件进行裁减

 昵称17268421 2014-05-09

如果生成的可执行文件或库比较大,这时候就可以使用strip命令进行裁减,在嵌入式开发中,如果使用的交叉编译工具是arm-linux,则命令 是arm-linux-strip,如果是arm-uclibc-linux,则命令是arm-uclibc-linux-strip.

因为开发板上的空间本来就很少,使用这个命令可以进一步减少可执行文件的大小,从而可以在开发板上可以存放更过的可执行文件。下面简单介绍一下这个命令:

主要是把编译的库文件或者可执行文件里的一些调试信息和符号信息去除。

使用strip对库文件、可执行文件进行操作,库文件、可执行文件中的一些与正常运行无关的调试信息和符号信息会被剔除掉,而且操作前和操作后文件的大小 变化特别明显,一般可以减少1/3或更多,所以在嵌入式的平台上是非常有用的。但是在开发过程并不提倡这一做法,因为使用strip后,使用gdb时就无 法获得调试信息了

其支持的选项如下:
strip -h
用法:strip <选项> 输入文件
从文件中删除符号和节
 选项为:

-I --input-target= 假定输入文件的格式为
-O --output-target= 以格式创建输出文件
-F --target= 设置输入、输出的文件格式为
-p --preserve-dates 复制上次修改或者操作的时间到输出文件中
-R --remove-section= 删除输出文件中段信息
-s --strip-all 删除所有符号信息和重定位信息
-g -S -d --strip-debug 删除所有调试信息和段信息
--strip-unneeded 删除所有重定位中不需要的符号信息
--only-keep-debug 删除调试信息以外的其他所有信息
-N --strip-symbol= 不拷贝符号信息
-K --keep-symbol= 不去除符号信息
-w --wildcard 在符号中使用通配符
-x --discard-all 去除所有非全局符号
-X --discard-locals 去除所有编译产生的符号
-v --verbose 列出所有修改过的所有目标文件
-V --version 显示版本号
-h --help 显示帮助
-o 把输出的文件名修改成

为了减少运行时库的大小,我们应该使用交叉编译版本即arm-linux-gcc 的strip工具来处理根文件系统的库文件,把二进制文件中的包含的符号表和调试信息删除掉。

例:

#arm-linux-strip /home/su/rootfs/lib/*.so


strip: 支持的目标: elf32-i386 a.out-i386-linux efi-app-ia32 elf32-little elf32-big elf64-alpha ecoff-littlealpha elf64-little elf64-big elf32-littlearm elf32-bigarm elf32-hppa-linux elf32-hppa elf64-ia64-little elf64-ia64-big efi-app-ia64 elf32-m68k a.out-m68k-linux elf32-powerpc aixcoff-rs6000 elf32-powerpcle ppcboot elf64-powerpc elf64-powerpcle aixcoff64-rs6000 elf32-s390 elf64-s390 elf32-sparc a.out-sparc-linux elf64-sparc a.out-sunos-big elf64-x86-64 pe-i386 pei-i386 srec symbolsrec tekhex binary ihex trad-core

目标文件分为:可重定位文件、可执行文件、共享文件
strip的默认选项会去除.symbol节的内容以及.debug节的内容,因此尽量只对可执行文件执行strip而不要对静态库或动态库等目标文件strip。

测试代码如下:


int max(int val1, int val2)
{
int iVal = (val1 > val2) ? val1 : val2;
return iVal;
}

int min(int val1, int val2)
{
int iVal = (val1 < val2) ? val1 : val2;
return iVal;
}


#include <stdio.h>

extern int max(int val1, int val2);
extern int min(int val1, int val2);

int main()
{
int val1, val2;

scanf("%d %d", &val1, &val2);
printf("%d\n", max(val1, val2));
printf("%d\n", min(val1, val2));
}
>gcc -c max.c min.c
>ar rcs libcmp.a max.o min.o
>gcc -o test main.c libcmp.a
>gcc -share -fPIC -o libcmp.so max.c min.c

>cp libcmp.a libcmp.a.bak
>cp libcmp.so libcmp.so.bak
>cp test test.orig
>strip libcmp.a libcmp.so
>strip test
>ll -h
总计 92K
-rwxr-xr-x 1 6.9K a.out
-rw-r--r-- 1 1.1K libcmp.a
-rw-r--r-- 1 1.6K libcmp.a.bak
-rwxr-xr-x 1 2.9K libcmp.so
-rwxr-xr-x 1 5.3K libcmp.so.bak
-rw-r--r-- 1  237 main.c
-rw-r--r-- 1   89 max.c
-rw-r--r-- 1  695 max.o
-rw-r--r-- 1   89 min.c
-rw-r--r-- 1  695 min.o
-rwxr-xr-x 1 3.2K test
-rwxr-xr-x 1 6.8K test.orig

选项简释:
The -fPIC flag directs the compiler to generate position independent code section).
The -shared flag directs the linker to create a shared object file.

可 见无论是静态库(libcmp.a)还是动态库(libcmp.so)还是可执行文件(test),去掉一些符号信息后都减小了很多,但如果这时再链接这 两个库的话是编不过的,因此,如果不是指定特殊的strip选项的话,还是尽量不要对库文件strip,只对链接后的可执行文件strip就可以了(如果 也不调试)。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多