|
|
|
在网上,有好多绿色软件,不仅功能强大,而且软件本身的体积非常小。有的通常 `* t m( A2 l6 _
只在几十K左右。那他们是怎么做到把软件做的怎么小的呢?现在我手把手的告诉
H1 p& F4 w5 ?/ J7 s% k8 k4 }你如何通过修改程序的编译选项来瘦身你的执行文件
4 G) z |0 b0 ~* I5 ?! w8 F( @先看一个最典型的程序:
, w; m+ W) [5 {. N# c8 V: w#include<stdio.h>1 }/ I& `6 o! K; x! ^8 b/ H# ~& V
int main()
) r: j6 F" B# r' o! B{
4 u$ d, F& z9 A7 b9 @- C; V printf("Hello,World");" Z. D' F' U, a' A
return 0;& g& u5 p, ~: S! Q
}) Z1 T" Y5 o; @1 X* L0 u4 R' X
" y+ S! L) @; [# `
上面的程序之所以被称之为典型,是因为他有如下的内容:
# Y2 p% V, \ S4 L. @8 Y1、系统函数调用:printf( }# u, S, V2 X3 l, C
2、有静态数据段: M- ?3 d9 }# T* P0 N
6 d) w2 {8 F5 o4 s
好,现在把此文件放到VisualStudio6.0中进行编译,看看文件有多大。! Y3 F3 r' f" n& h& E/ U
1、用VisualStudio6.0打开HelloWorld.cpp文件,直接按F7。然后点击OK,生成. N& D7 H' M4 r1 F: t- o
Project文件,然后进行编译。编译完成了以后,看看Debug目录下的执行文件的大; d- `. }) _. L5 d# F
小,为172,096Bytes。
0 P/ u- N4 J& L/ e; U; A3 J# M; M7 Z* }0 K6 b
2、刚才编译的Debug文件,现在修改成Release文件看看。选择Win32 Release,再
. p4 p: e$ ]. q编译。察看执行文件大小,现在成了40,960Bytes。看来Debug版本的要比Release3 R. e; v% w% c5 b4 R0 o \0 n4 j
的小。5 S/ C+ \. U# j% h$ f
4 j, o1 j- b+ E: B1 W
3、检查代码优化:发现执行文件的优化是Maximize Speed。那么修改成Minimize! q) w" N! O% g {1 x
Size看看。重新编译,得到执行文件的大小为:40,960Bytes。看来大小没什么变1 r0 c0 `6 ^+ g1 h! E/ v
化。其实这是由于我们的代码本身太小的缘故,导致即使变化了也看不出来。
% N, @9 i0 \! C, q$ r
" C6 d6 {! Y2 m" Y3 e& ?4、想想我们程序的main函数是由CRT类库进行引导的。在我们现在的设定当中,由5 B( x& {7 O7 t2 P! L
于采取的是系统缺省的编译连接方式(缺省为编译为Single Thread,Static
2 N4 r/ \' x1 s# m: j3 d& t; l3 ULibrary),所以,在我们的执行文件当中,包含了CRT的二进制代码。好,修改编
5 V* Z8 X; ^7 o! W K; T9 ^译选项:C/C++ => Category:Code Generation => Use run-time
: K% A( \ G5 Y8 Ylibrary:MutiThreaded Dll。编译看看:执行文件大小变成了16,384Bytes。4 A9 h" C. k- c3 G) r$ w
- l! ^" {+ O; ^5、刚才的设定确实不错,一下子把执行文件大小减小到了16K。现在用UltraEdit
$ e" @* x3 H+ z X( j看看执行文件都是些什么内容。结果大吃一惊:基本上都是0。看来这个有减小的
/ [+ [# v( G+ `5 O必要了。都知道,执行文件都有自己的代码段,数据段等等,每个段的大小也是采+ f3 E. h& x# e% h5 x5 l f) f
用编译器缺省设定的。好,我们来修改一下段的大小看看:- {. w3 w+ g8 x- E7 u2 ^
5.1 连接选项中有一个是/opt:nowin98,意思是将段的大小设定成为Win2000适应( D. O2 t# l: Y9 u
的。编译看看:哇塞,变成了2,560byte。看来这个选项确实把文件变小了N多。
" W/ F! M+ r1 o% g$ Z3 n5.2 在查察连接选项中还有没有什么特别的。发现/align:xx还可以将段大小缩4 v9 ^( n" ^) Z: d
小。通过UltraEdit察看刚才/opt:nowin98编译出来的文件,发现每个段的大小都; e# J0 X4 z P
是4K的整数倍。看来/align:xx还有减小的趋势。试一把再说:添加连接选项:3 h. q9 o3 j( b! @9 \5 e
/align:16(这个大小已经是能够设定的最小的了)。看看结果:1,408Bytes。厉
; a; Q/ M9 \! ^7 {7 O0 b7 x害,现在代码更小了。
. u3 I8 S: C% H- \8 u5.3 现在回想起来,执行文件大小有数据段,执行代码段等等,如果把这些段都合
, k/ f% M0 C6 Q l$ F$ M1 k并起来,是不是就会把段之间的冗余有减小了呢?再试试看:添加选项:3 i7 e$ s5 J. B/ ?2 f
/merge:.data=.text /merge:.rdata=.text。再看看文件大小:1,328bytes。真的
" w0 B) H5 `5 n. T( T很不错了。) c8 D2 ]7 x, M6 J
2 P4 e/ y" \7 R' X7 u3 g- @
6、刚才的设定确实不错,似乎达到了我们想要的极限了。但是回头想一下,如果
; g3 b" W( e/ ~; S# ?& ?没有CRT库的话,会不会更小了?实际上确实这样。添加连接选项: /entry:
4 \" j6 b' n# W$ ^0 u/ j2 ^main,把入口地址直接指向我们的main函数看看。得到592Bytes。
- j2 r' ^0 h# o. X$ t1 U- q! C) o, k
2 F9 G/ x( h7 C; w0 s, M7 J最终我们得到我们最后的大小592Bytes了。我想这也许是我们通过编译器能够编译
8 {, }! b7 H$ F3 O4 t出来的最小的代码了。0 p3 ^9 O$ t* u3 j' l [; _( M
: W& S4 `$ E: d3 _) }" F1 n& H结论:
4 e& O2 `2 @4 I! ?通过上述的步骤,我们了解了如何修改那些编译连接选项来达到执行文件瘦身的目; h3 ^ j2 o4 ~$ W- m, R f/ E
的。但是,通常来讲,在我们的Release文件当中,并不需要如此小的执行文件。
3 I) S3 `* B0 F0 ^4 w# C, l如果想达到瘦身的目的,修改为library:MutiThreaded Dll和添加/opt:nowin98已
; w) U. q3 v& V9 x0 Z经是很好的选择了。其他别的选项在编译的时候或多或少的有警告出现,而且,带5 ?: k" i7 H D4 U) Q8 S
有那些编译选项编出来的执行文件也不一定在各个平台上能够适用。
+ }9 N2 a; A/ H! O2 }
. \, j& z( B1 D) b' l- [' c另外:如果你的执行文件即使通过了这些设定还是比较大的话,也可以通过一些" B, C( H0 A5 s# z/ X* {
EXE文件压缩工具来进行压缩。比如UPX等等。在此不再细说了。, j9 [0 S( j$ ?) ~- w( W
# k+ Z( v2 \" X) ]
以上部分的不足之处,还请多多指正。 |
|