|
|
|
在网上,有好多绿色软件,不仅功能强大,而且软件本身的体积非常小。有的通常
- L% y o; O- {* ^只在几十K左右。那他们是怎么做到把软件做的怎么小的呢?现在我手把手的告诉$ L4 ^ ~6 Y2 V3 l& w; m- c8 m$ D
你如何通过修改程序的编译选项来瘦身你的执行文件
8 D+ L& J/ o& k' D/ ^7 I% [先看一个最典型的程序: ' q: X' z. p8 V
#include<stdio.h>" X, w! x1 o: _/ Q( e
int main()
) w% p7 W) q% ]' [9 e{6 o) ~$ ?, R8 I3 u( K
printf("Hello,World");
8 i; u% l6 B- j2 T% b; h return 0;- O+ {( `: ~0 i$ x' ]; R2 M/ B! ^
} Z9 U3 s- k8 C! o9 w0 B/ a
- h! K; ~: ^4 `! B* N& y( e! _
上面的程序之所以被称之为典型,是因为他有如下的内容:4 L. N$ c+ Q& N9 r( H
1、系统函数调用:printf' V$ f5 A# J* p$ p S- Z
2、有静态数据段% t+ Q1 n; _& h: ]& J5 k9 i7 g
( @3 S) s4 @) O* B; }好,现在把此文件放到VisualStudio6.0中进行编译,看看文件有多大。
9 t$ ^; q% U/ N0 V( y6 g" J1、用VisualStudio6.0打开HelloWorld.cpp文件,直接按F7。然后点击OK,生成
1 w5 V$ o* H3 t$ lProject文件,然后进行编译。编译完成了以后,看看Debug目录下的执行文件的大8 q) M; _" @% R3 J( D
小,为172,096Bytes。
) h& f$ s* I: R! Y0 n( e) g, T1 l# t( M, \! G) X, A3 o
2、刚才编译的Debug文件,现在修改成Release文件看看。选择Win32 Release,再
% i) t1 E" ? S0 A% s9 S编译。察看执行文件大小,现在成了40,960Bytes。看来Debug版本的要比Release, L; @: r& k4 C) F- t) A
的小。
8 {* U0 j% c, \- k% F) m
) ]; e8 d$ b7 P3、检查代码优化:发现执行文件的优化是Maximize Speed。那么修改成Minimize
; L) E( l$ e, s6 F @- e: |$ ~' dSize看看。重新编译,得到执行文件的大小为:40,960Bytes。看来大小没什么变0 r4 _( \ W7 l( D; q5 K
化。其实这是由于我们的代码本身太小的缘故,导致即使变化了也看不出来。" M5 p' z1 q0 [" {
; O/ ~! |; n" F3 [7 }$ ]
4、想想我们程序的main函数是由CRT类库进行引导的。在我们现在的设定当中,由
1 b, V2 I6 e% c2 _2 u于采取的是系统缺省的编译连接方式(缺省为编译为Single Thread,Static
+ g" q4 q) B! qLibrary),所以,在我们的执行文件当中,包含了CRT的二进制代码。好,修改编, m7 n% S3 W8 h4 \. I
译选项:C/C++ => Category:Code Generation => Use run-time
) b Y; g, d/ [+ Q5 N ?library:MutiThreaded Dll。编译看看:执行文件大小变成了16,384Bytes。* x( u' e# w$ y: K
! k$ o7 O( Q7 o/ l5、刚才的设定确实不错,一下子把执行文件大小减小到了16K。现在用UltraEdit: Z* O8 d0 r6 \ \/ n
看看执行文件都是些什么内容。结果大吃一惊:基本上都是0。看来这个有减小的! [+ }# r% j+ O0 e3 F* C
必要了。都知道,执行文件都有自己的代码段,数据段等等,每个段的大小也是采
8 c6 z+ f" X' S& i% I用编译器缺省设定的。好,我们来修改一下段的大小看看:
& f! T/ I( R. Z/ Y5.1 连接选项中有一个是/opt:nowin98,意思是将段的大小设定成为Win2000适应
' ?! O* ~% j: Z' A" d2 n( _的。编译看看:哇塞,变成了2,560byte。看来这个选项确实把文件变小了N多。) C: ]8 R/ {( [8 @
5.2 在查察连接选项中还有没有什么特别的。发现/align:xx还可以将段大小缩0 V( [; Q7 w5 v8 B) [$ u
小。通过UltraEdit察看刚才/opt:nowin98编译出来的文件,发现每个段的大小都
7 y% O+ Z6 R, |2 O是4K的整数倍。看来/align:xx还有减小的趋势。试一把再说:添加连接选项:
9 Y0 r5 B+ G( N1 z+ P# @/align:16(这个大小已经是能够设定的最小的了)。看看结果:1,408Bytes。厉
. ? [3 N! l$ _# H+ W0 n9 K害,现在代码更小了。/ B8 B7 t( J4 H3 O( {9 o, r# {$ z
5.3 现在回想起来,执行文件大小有数据段,执行代码段等等,如果把这些段都合
`2 i# ]( H( ~3 `/ r并起来,是不是就会把段之间的冗余有减小了呢?再试试看:添加选项:
# T9 H8 i1 ^$ b& Q( i+ b/merge:.data=.text /merge:.rdata=.text。再看看文件大小:1,328bytes。真的. P' Y: S" E9 ]0 C& V' L
很不错了。
9 F+ K1 A! G/ c# B' h9 y8 E- V! L- C
- u: I' K# J3 t6、刚才的设定确实不错,似乎达到了我们想要的极限了。但是回头想一下,如果
) k6 i, v: o, w8 }没有CRT库的话,会不会更小了?实际上确实这样。添加连接选项: /entry:0 y( n4 I1 a1 b4 x; x
main,把入口地址直接指向我们的main函数看看。得到592Bytes。
4 {7 O; s4 u3 r4 B! ^( ^4 w
* L3 w3 _' R" H% B- T- z最终我们得到我们最后的大小592Bytes了。我想这也许是我们通过编译器能够编译' \8 `' x; ? ]- ?6 r. w; c
出来的最小的代码了。
$ a3 l: l, _' W' D k5 a# L& Y) i: i* g' W% X
结论:8 _, { T3 W- Q% c0 d8 n# X9 w9 v9 h
通过上述的步骤,我们了解了如何修改那些编译连接选项来达到执行文件瘦身的目
) r# v* m3 S7 M的。但是,通常来讲,在我们的Release文件当中,并不需要如此小的执行文件。: J9 e6 H1 A: Z. Y, B3 j) j3 u
如果想达到瘦身的目的,修改为library:MutiThreaded Dll和添加/opt:nowin98已
h1 x3 z* m, c- m* P经是很好的选择了。其他别的选项在编译的时候或多或少的有警告出现,而且,带/ e0 T! ^; J/ s: A. u: K
有那些编译选项编出来的执行文件也不一定在各个平台上能够适用。
1 @3 D, G5 q9 G0 P' G8 U
8 u% y- X D7 s8 V另外:如果你的执行文件即使通过了这些设定还是比较大的话,也可以通过一些, T7 a) s' ~0 s0 F, a. O3 Z8 f$ y
EXE文件压缩工具来进行压缩。比如UPX等等。在此不再细说了。
: v8 U5 d9 q' K+ _' ?
6 _& m$ G/ a$ p- b) T! g& @以上部分的不足之处,还请多多指正。 |
|