|
|
|
在网上,有好多绿色软件,不仅功能强大,而且软件本身的体积非常小。有的通常
% y. z$ h, d% @8 r只在几十K左右。那他们是怎么做到把软件做的怎么小的呢?现在我手把手的告诉
0 D9 F l- ], h* u9 M你如何通过修改程序的编译选项来瘦身你的执行文件
8 ~0 s1 J4 P8 Z6 x4 i( K先看一个最典型的程序: / n1 N2 S7 P7 O- q, `
#include<stdio.h>
4 x9 j: v0 E- ^6 j% Wint main()7 ^; H, o" D F. I' k
{
( [2 u4 [! S3 {% {0 p. o" \ printf("Hello,World");
. G7 T. i: }. O return 0;
' F6 E2 g4 X0 v0 d}. n) A1 z# g$ v- A6 Z2 y
* x1 j$ w0 Q& j: k: q; Q- I上面的程序之所以被称之为典型,是因为他有如下的内容:
% Q( S- q' X* l) @) o4 w% I1、系统函数调用:printf2 m! @. @5 v. I0 P6 V
2、有静态数据段; G+ [" c7 y. Q- f1 s: c! F
3 k% ]; Q6 P& i/ [4 V+ w好,现在把此文件放到VisualStudio6.0中进行编译,看看文件有多大。! q f; `9 M1 C) A. v9 |. A
1、用VisualStudio6.0打开HelloWorld.cpp文件,直接按F7。然后点击OK,生成% c$ Y/ w( z' _1 T& @- C6 [* w6 ?' [. O
Project文件,然后进行编译。编译完成了以后,看看Debug目录下的执行文件的大
0 \" P2 O+ Z! J$ @3 E小,为172,096Bytes。4 _" s' l6 c; S2 v& v% b
2 ^# W& e* N' Q" I, j! ^2、刚才编译的Debug文件,现在修改成Release文件看看。选择Win32 Release,再
5 l5 W) g2 Q4 k# ^. X; }编译。察看执行文件大小,现在成了40,960Bytes。看来Debug版本的要比Release" `6 j! I4 ^5 @& K3 a* V1 N7 j
的小。 [% {% w# H8 C. l3 w: z/ a- @( g) R' C
+ k" V. ] a- v& ~, r* s
3、检查代码优化:发现执行文件的优化是Maximize Speed。那么修改成Minimize
}# {/ C- B, X2 o/ }6 ?4 ^Size看看。重新编译,得到执行文件的大小为:40,960Bytes。看来大小没什么变* s/ d$ x( R8 U$ v7 v
化。其实这是由于我们的代码本身太小的缘故,导致即使变化了也看不出来。6 d+ ~) Q1 M5 P7 P6 g1 t
& s8 R( A$ K1 L8 z6 ^# Q4、想想我们程序的main函数是由CRT类库进行引导的。在我们现在的设定当中,由8 ]2 A& n- V( P" x y7 O
于采取的是系统缺省的编译连接方式(缺省为编译为Single Thread,Static
+ U3 S& ~" E6 a: a2 MLibrary),所以,在我们的执行文件当中,包含了CRT的二进制代码。好,修改编9 u$ I+ c/ n7 A+ {# T! d
译选项:C/C++ => Category:Code Generation => Use run-time. h4 N1 J6 e; m/ [3 \4 A( w
library:MutiThreaded Dll。编译看看:执行文件大小变成了16,384Bytes。& z: _1 M) W4 ^0 Y$ U/ Y) `
4 E/ c; @. Q! J; `' K$ J5、刚才的设定确实不错,一下子把执行文件大小减小到了16K。现在用UltraEdit
) V1 F2 ]& _- m" `" ]) D看看执行文件都是些什么内容。结果大吃一惊:基本上都是0。看来这个有减小的
~8 ?# w' }3 w必要了。都知道,执行文件都有自己的代码段,数据段等等,每个段的大小也是采2 J' y" O- \: \6 S: C. ^1 o& n
用编译器缺省设定的。好,我们来修改一下段的大小看看: J: c1 q) [& Z( F
5.1 连接选项中有一个是/opt:nowin98,意思是将段的大小设定成为Win2000适应
8 V* l- _1 e6 i% b的。编译看看:哇塞,变成了2,560byte。看来这个选项确实把文件变小了N多。
- s3 v4 |! U0 ^( j: |1 e$ ]$ ~' i+ E5.2 在查察连接选项中还有没有什么特别的。发现/align:xx还可以将段大小缩3 w0 \$ b1 N& E3 @
小。通过UltraEdit察看刚才/opt:nowin98编译出来的文件,发现每个段的大小都$ J' z5 x$ o1 }! l9 a
是4K的整数倍。看来/align:xx还有减小的趋势。试一把再说:添加连接选项:
4 ]1 q5 S/ t* v4 L' A, z/ n i( a/align:16(这个大小已经是能够设定的最小的了)。看看结果:1,408Bytes。厉) L4 q* N8 R3 y+ V" q8 e
害,现在代码更小了。8 N! |- q* l8 k/ @
5.3 现在回想起来,执行文件大小有数据段,执行代码段等等,如果把这些段都合
2 z# ?- s$ P( }" U并起来,是不是就会把段之间的冗余有减小了呢?再试试看:添加选项:
& [- M, K8 i& }5 G/merge:.data=.text /merge:.rdata=.text。再看看文件大小:1,328bytes。真的
5 b5 Z; w4 P7 m) [很不错了。
& n* Q' z; ]& q2 n. Q( M% }, W. X" l: g: a& p6 s2 M$ G6 n9 E
6、刚才的设定确实不错,似乎达到了我们想要的极限了。但是回头想一下,如果' [; K! L6 @2 z
没有CRT库的话,会不会更小了?实际上确实这样。添加连接选项: /entry:
9 |# D; d# n$ _& M. R [3 ?main,把入口地址直接指向我们的main函数看看。得到592Bytes。
% R8 {$ R/ o9 O( ^4 M: v
8 y" ^ b! i* S4 _, u8 @- X最终我们得到我们最后的大小592Bytes了。我想这也许是我们通过编译器能够编译/ B; ]7 q5 F! n/ P
出来的最小的代码了。
; w- T: V! d, j! i' i# w0 V& B, i0 _) f
结论:
/ G7 ?, h+ b& s' N, r% _1 S8 K通过上述的步骤,我们了解了如何修改那些编译连接选项来达到执行文件瘦身的目
: O- {5 ?& K Q. b, Z# r8 p的。但是,通常来讲,在我们的Release文件当中,并不需要如此小的执行文件。7 b2 m) {) H7 B# S# \+ {( [6 _; H% V+ O
如果想达到瘦身的目的,修改为library:MutiThreaded Dll和添加/opt:nowin98已3 N u* ~* f) G) x. K N/ T- T
经是很好的选择了。其他别的选项在编译的时候或多或少的有警告出现,而且,带* }' A: c2 _6 w
有那些编译选项编出来的执行文件也不一定在各个平台上能够适用。# u! ]% p6 x' t9 C; |
! I: N" j9 {+ K8 _% @, o另外:如果你的执行文件即使通过了这些设定还是比较大的话,也可以通过一些: Z+ ?! t# g* K
EXE文件压缩工具来进行压缩。比如UPX等等。在此不再细说了。0 I; l4 z. d- A5 O8 g
e! p0 n/ d' H5 e- z9 S# d9 N, m
以上部分的不足之处,还请多多指正。 |
|