打开APP
未登录
开通VIP,畅享免费电子书等14项超值服
开通VIP
首页
好书
留言交流
下载APP
联系客服
Linux程序减肥三步走
cana_xzy
>《LINUX》
2010.06.03
关注
Linux程序减肥三步走
对于设计嵌入式
Linux
系统的研发人员来说,有一个问题是必须要考虑到的,那就是存储器的空间。
我们知道嵌入式
Linux
系统所用的存储器不是软磁盘、硬盘、
ZIP
盘、
CD-ROM
、
DVD
这些众所周知的大容量常规存储器,它使用的是例如
Rom, CompactFlash
,
M-Systems
的
DiskOnChip
,
SONY
的
MemoryStick
,
IBM
的
MicroDrive
等体积极小
,
与主板上的
BIOS
大小相近,存储容量很小的存储器。所以怎样尽可能的节省空间就显的很重要。
嵌入式系统的存储器中放置的无非是内核,文件系统,软件,以及自己开发的程序。本文就从程序入手,以一个非常简单的
C
程序来作为例子,通过三步来让它减肥。
Hello.c:
#include
int main ()
{
printf("hello,world");
return 0;
}
我们先用正常的编译方法来编译,看看生成的程序的大小是多少
#gcc –o hello hello.c
#ls –l hello
-rwxr-xr-x 1 root root 11542 Nov 13 20:07 hello
从结果可以看到正常编译后的程序大小是
11542Byte,
现在开始我们的三步减肥,看看到底效果如何。
步骤一:用
gcc
的代码优化参数
代码优化指的是编译器通过分析源代码,找出其中尚未达到最优的部分,然后对其重新进行组合,目的是改善程序的执行性能。
GCC
提供的代码优化功能非常强大,
它通过编译选项
-On
来控制优化代码的生成,其中
n
是一个代表优化级别的整数。对于不同版本的
GCC
来讲,
n
的取值范围及其对应的优化效果可能并不完全相同,比较典型的范围是从
0
变化到
2
或
3
。
编译时使用选项
-O
可以告诉
GCC
同时减小代码的长度和执行时间,其效果等价于
-O1
。在这一级别上能够进行的优化类型虽然取决于目标处理器,但一般都会包括线程跳转(
Thread Jump
)和延迟退栈(
Deferred Stack Pops
)两种优化。选项
-O2
告诉
GCC
除了完成所有
-O1
级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度等。选项
-O3
则除了完
成所有
-O2
级别的优化之外,还包括循环展开和其它一些与处理器特性相关的优化工作。通常来说,数字越大优化的等级越高,同时也就意味着程序的运行速度越
快。许多
Linux
程序员都喜欢使用
-O2
选项,因为它在优化长度、编译时间和代码大小之间,取得了一个比较理想的平衡点。
#gcc –O2 –o hello hello.c
#ls –l hello
-rwxr-xr-x 1 root root 11534 Nov 13 20:09 hello
优化过的程序的大小是
11534Byte,
比正常编译的结果
11542Byte
似乎没有小多少,不过不用着急,这才是第一步。我们接着往下进行。
步骤二:用
strip
命令
我们知道二进制的程序中包含了大量的符号信息
(symbol table)
,有一部分是用来为
gdb
除错提供必要帮助的。可以通过
readelf–S
查看到这些符号信息。
#readelf -S hello
Section Headers:
[Nr]Name Type
[ 0] NULL
[ 1] .interp PROGBITS
[ 2].note.ABI-tag NOTE
[ 3] .hash HASH
[ 4] .dynsym DYNSYM
[5] .dynstr STRTAB
[ 6] .gnu.version VERSYM
[ 7] .gnu.version_rVERNEED
[ 8] .rel.dyn REL
[ 9] .rel.plt REL
[10] .initPROGBITS
[11] .plt PROGBITS
[12] .text PROGBITS
[13].fini PROGBITS
[14] .rodata PROGBITS
[15] .eh_frame PROGBITS
[16] .data PROGBITS
[17] .dynamic DYNAMIC
[18] .ctorsPROGBITS
[19] .dtors PROGBITS
[20] .jcr PROGBITS
[21].got PROGBITS
[22] .bss NOBITS
[23] .comment PROGBITS
[24] .debug_aranges PROGBITS
[25] .debug_pubnames PROGBITS
[26] .debug_info PROGBITS
[27] .debug_abbrev PROGBITS
[28].debug_line PROGBITS
[29] .debug_frame PROGBITS
[30].debug_str PROGBITS
[31] .shstrtab STRTAB
[32] .symtab SYMTAB
[33] .strtab STRTAB
类似于
.debug_xxxx
的就是用来
gdb
除错的。去掉它们不但不会影响程序的执行还可以减小程序的
size
。这里我们通过
strip
命令拿掉它们。
#strip hello
#ls –l hello
-rwxr-xr-x 1root root 2776 Nov 13 20:11 hello
程序立刻变成
2776Byte
了,效果不错吧。让我们再接再厉
,
进行最后一步。
步骤三:用
objcopy
命令
上一步的
strip
命令只能拿掉一般
symbol table
,有些信息还是没拿掉,而这些信息对于程序的最终执行是没有什幺影响的。如
:.comment; .note.ABI-tag; .gnu.version
就是完全可以去掉的。所以说程序还有简化的余地,我们可以使用
objcopy
命令把它们抽取掉。
#objcopy –R .comment –R .note.ABI-tag –R.gnu.version hello hello1
#ls –l hello1
-rwxr-xr-x 1 root root2316 Nov 13 20:23 hello1
到这一步,程序的减肥就完成了,我们可以看到程序由正常编译的
11542Byte
一下子渐少到
2316Byte,
效果非常明显。
小结
程序容量的减小无疑对嵌入式
Linux
系统的设计有着重要的意义,它为我们节省了大量空间,使得我们可以利用这部分空间来完善我们的系统
,
比如加大内核等等
,
毕竟这才是我们最终的目的。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报
。
打开APP,阅读全文并永久保存
查看更多类似文章
猜你喜欢
类似文章
【热】
打开小程序,算一算2024你的财运
问题:linux下如何调用不同目录下的.h 库文件
Linux下GCC编程四个过程
编译原理 (预处理>编译>汇编>链接)
S-Records介绍+objcopy命令
elf文件格式与动态链接库(非常之好)
Linux下如何编译并运行C程序
更多类似文章 >>
生活服务
热点新闻
留言交流
回顶部
联系我们
分享
收藏
点击这里,查看已保存的文章
导长图
关注
一键复制
下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!
联系客服
微信登录中...
请勿关闭此页面
先别划走!
送你5元优惠券,购买VIP限时立减!
5
元
优惠券
优惠券还有
10:00
过期
马上使用
×