如果生成的可執行文件或庫比較大,這時候就可以使用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 -
總計 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就可以了(如果 也不調試)。