|
|
|
在网上,有好多绿色软件,不仅功能强大,而且软件本身的体积非常小。有的通常
; a0 A) q' U" C* M只在几十K左右。那他们是怎么做到把软件做的怎么小的呢?现在我手把手的告诉
3 m8 D6 e/ ~7 o, R) T4 d你如何通过修改程序的编译选项来瘦身你的执行文件8 i" c; V# q/ k8 V
先看一个最典型的程序:
& a5 Y4 U2 q5 z) K: q#include<stdio.h># }! d% s3 j9 p; w! v
int main()$ x1 q$ m9 N7 @0 g& W, B
{( }! u$ h2 ?6 }0 a: t
printf("Hello,World");" U/ b* E' z' i7 p3 ]6 N
return 0;. ?/ P# @: P5 z; g- B6 s9 z
}
4 J# B a2 ?; b8 p q! J& x( J6 h3 K' |; R8 d" O8 R7 K; _
上面的程序之所以被称之为典型,是因为他有如下的内容:
$ t. a, j; h/ J8 B7 o# K1、系统函数调用:printf
& Y) O( G5 Q! l9 D" x$ @( I2、有静态数据段0 E! t u) m$ o' z8 R
8 R4 n# X4 M# ^3 s& k. M
好,现在把此文件放到VisualStudio6.0中进行编译,看看文件有多大。
, H5 ~2 A, b! N8 N8 @) ?) }1、用VisualStudio6.0打开HelloWorld.cpp文件,直接按F7。然后点击OK,生成
d& `" ]) b! O7 J( fProject文件,然后进行编译。编译完成了以后,看看Debug目录下的执行文件的大& J8 k! X, ~' }8 C; n9 \: w' a9 _4 N) N
小,为172,096Bytes。' V" _6 O: l2 i+ D
/ `7 G# |3 b8 a' I( f' r1 b. `. e/ X
2、刚才编译的Debug文件,现在修改成Release文件看看。选择Win32 Release,再
* ~. V4 h) p1 G1 A: H* \6 q8 w编译。察看执行文件大小,现在成了40,960Bytes。看来Debug版本的要比Release
+ n4 W- y5 }7 k8 s8 T的小。
4 [+ |( C7 X, Y- K( v8 h
6 I, c2 D4 a! \3、检查代码优化:发现执行文件的优化是Maximize Speed。那么修改成Minimize
8 a& N( g9 z2 oSize看看。重新编译,得到执行文件的大小为:40,960Bytes。看来大小没什么变) {5 {+ i3 |7 Q+ U4 T: G
化。其实这是由于我们的代码本身太小的缘故,导致即使变化了也看不出来。, U; M( U2 ? ?4 X/ q0 n5 b% ^
! Z% B! v7 ]1 }; I8 l+ c* ]* z& z$ i. [
4、想想我们程序的main函数是由CRT类库进行引导的。在我们现在的设定当中,由
7 Z+ D4 t1 C; T于采取的是系统缺省的编译连接方式(缺省为编译为Single Thread,Static
& T B9 Z1 C5 vLibrary),所以,在我们的执行文件当中,包含了CRT的二进制代码。好,修改编
* l7 }! D4 Z% }* E译选项:C/C++ => Category:Code Generation => Use run-time7 g, c; r0 F) k# \9 L2 y
library:MutiThreaded Dll。编译看看:执行文件大小变成了16,384Bytes。
$ |" M: D9 Y! a9 w! @9 [9 m4 l! Z
* G+ |* e& v: D6 x5、刚才的设定确实不错,一下子把执行文件大小减小到了16K。现在用UltraEdit
; W$ o. U1 G4 }% K- U看看执行文件都是些什么内容。结果大吃一惊:基本上都是0。看来这个有减小的
1 Q. D2 f% v( r9 \$ }7 A. P( Y3 a必要了。都知道,执行文件都有自己的代码段,数据段等等,每个段的大小也是采
6 f6 u9 m& s6 z# a: u用编译器缺省设定的。好,我们来修改一下段的大小看看:: R, w. a" ]0 N+ e7 T! A
5.1 连接选项中有一个是/opt:nowin98,意思是将段的大小设定成为Win2000适应
- X/ C' s3 {" ]的。编译看看:哇塞,变成了2,560byte。看来这个选项确实把文件变小了N多。
1 I/ R/ r& D& F3 e0 Z5.2 在查察连接选项中还有没有什么特别的。发现/align:xx还可以将段大小缩- {# k3 S9 _ ?. p8 U' H
小。通过UltraEdit察看刚才/opt:nowin98编译出来的文件,发现每个段的大小都# v2 \" l* J& f$ b; q& J
是4K的整数倍。看来/align:xx还有减小的趋势。试一把再说:添加连接选项:
) k" {: B, U6 R+ n/align:16(这个大小已经是能够设定的最小的了)。看看结果:1,408Bytes。厉
, d# y7 B& L2 H& t2 I" I害,现在代码更小了。/ e2 g. p/ B, u% Z
5.3 现在回想起来,执行文件大小有数据段,执行代码段等等,如果把这些段都合! @. B; @) n# @: q+ k
并起来,是不是就会把段之间的冗余有减小了呢?再试试看:添加选项:, q8 f3 V1 \7 X
/merge:.data=.text /merge:.rdata=.text。再看看文件大小:1,328bytes。真的
, D) o: O$ i Q/ {# Y很不错了。
$ D' U/ | P4 J3 b+ y8 `0 B5 r5 s3 F1 i; n$ A" s
6、刚才的设定确实不错,似乎达到了我们想要的极限了。但是回头想一下,如果
) P4 |5 F: N \! r8 u没有CRT库的话,会不会更小了?实际上确实这样。添加连接选项: /entry:* U9 a. z. C: q8 ^
main,把入口地址直接指向我们的main函数看看。得到592Bytes。+ ^1 T% U5 t% G! g9 E" H# o( f9 X5 h" d
% f* i2 c5 q# |) f/ b0 B) l
最终我们得到我们最后的大小592Bytes了。我想这也许是我们通过编译器能够编译
% O* Z5 ~1 j$ a7 _/ V$ d出来的最小的代码了。
; ~9 x1 \& `- q/ s. V, |; h. [4 z4 U$ r; T& d
结论:
1 G3 Y- I- q- c; w7 \" k通过上述的步骤,我们了解了如何修改那些编译连接选项来达到执行文件瘦身的目* P8 M$ I5 r3 s2 }1 Y
的。但是,通常来讲,在我们的Release文件当中,并不需要如此小的执行文件。
7 {. [$ a: f& u6 y( P如果想达到瘦身的目的,修改为library:MutiThreaded Dll和添加/opt:nowin98已
$ I s3 @; W1 h+ S5 E' d- `/ y经是很好的选择了。其他别的选项在编译的时候或多或少的有警告出现,而且,带
" f3 g, Q6 M' |有那些编译选项编出来的执行文件也不一定在各个平台上能够适用。
1 P( u1 \8 P5 `3 e/ ^
/ a2 {0 q. I! f6 v; s) c( t另外:如果你的执行文件即使通过了这些设定还是比较大的话,也可以通过一些7 J' Z) |" U! |' K
EXE文件压缩工具来进行压缩。比如UPX等等。在此不再细说了。, Z+ f& c2 K% W5 @$ b
6 O" ^ r q: m- H以上部分的不足之处,还请多多指正。 |
|