|
|
|
在网上,有好多绿色软件,不仅功能强大,而且软件本身的体积非常小。有的通常
7 d5 e6 o5 N/ q! j! F只在几十K左右。那他们是怎么做到把软件做的怎么小的呢?现在我手把手的告诉
6 F9 f/ p; E1 N& e, E你如何通过修改程序的编译选项来瘦身你的执行文件
' U, S7 @% g: D* V6 S! s先看一个最典型的程序: 7 ]# `- E. f3 L3 l: U( g
#include<stdio.h>
' |; b" ^, i6 Oint main()4 o" d# J& H" ]! Y/ R. b! S& M! O
{+ u) @5 o: u( Z w
printf("Hello,World");* O( I3 k4 E" h2 D( D* G9 i
return 0;! J4 _9 ]. p# U. Q1 _. p1 ^5 M+ N
}
. ~4 p, @7 C1 I. y' Q( R. {, f5 d0 S1 S& Q% X: h
上面的程序之所以被称之为典型,是因为他有如下的内容:: D! X+ c# `6 \7 l6 b
1、系统函数调用:printf
' E4 D# G# Q0 Y8 h2、有静态数据段; P, k X" ]' m# E' x, c* V
7 a0 \9 ~5 O9 j! f5 r3 |
好,现在把此文件放到VisualStudio6.0中进行编译,看看文件有多大。8 V6 [# M. F- S q
1、用VisualStudio6.0打开HelloWorld.cpp文件,直接按F7。然后点击OK,生成
7 [& H( Z5 v, a' | b* R5 _6 nProject文件,然后进行编译。编译完成了以后,看看Debug目录下的执行文件的大
$ y* E7 r, F+ D: I5 Q' T' y, Q/ o小,为172,096Bytes。
7 s/ |, E7 [8 [) @& E8 R6 f/ L
% H3 D6 w6 x: [3 H% Z- }4 x3 M2、刚才编译的Debug文件,现在修改成Release文件看看。选择Win32 Release,再
2 Q" e( M7 _$ i" o& T4 |" M编译。察看执行文件大小,现在成了40,960Bytes。看来Debug版本的要比Release) D3 X0 K( `! m- i5 G% |$ w
的小。+ v4 U' [( G# }: T0 f& h4 [
, j, p4 ^0 D8 _' N6 s3、检查代码优化:发现执行文件的优化是Maximize Speed。那么修改成Minimize
H# h& Z$ y ]9 iSize看看。重新编译,得到执行文件的大小为:40,960Bytes。看来大小没什么变" @9 V; ^7 H7 `4 v2 A/ Y% ]
化。其实这是由于我们的代码本身太小的缘故,导致即使变化了也看不出来。
; H: Z/ F& }9 U* a1 a" K
. |/ h+ v4 e! `8 P7 G' p; z4、想想我们程序的main函数是由CRT类库进行引导的。在我们现在的设定当中,由
8 a7 j) W/ x" w9 F% U于采取的是系统缺省的编译连接方式(缺省为编译为Single Thread,Static
0 T+ K- l4 R' m, N3 j' zLibrary),所以,在我们的执行文件当中,包含了CRT的二进制代码。好,修改编" C0 d0 L) K3 q/ c
译选项:C/C++ => Category:Code Generation => Use run-time' S% ?/ u- `4 V+ k
library:MutiThreaded Dll。编译看看:执行文件大小变成了16,384Bytes。" a( Q/ T" @* i, ?: r
6 S4 E9 b0 {1 z) v
5、刚才的设定确实不错,一下子把执行文件大小减小到了16K。现在用UltraEdit
9 s( t4 z3 z/ Q5 o$ ^: Q看看执行文件都是些什么内容。结果大吃一惊:基本上都是0。看来这个有减小的0 I+ n- _3 B5 ]+ P5 F
必要了。都知道,执行文件都有自己的代码段,数据段等等,每个段的大小也是采
; I s# k; Q7 F& C( F& x/ g" _用编译器缺省设定的。好,我们来修改一下段的大小看看:, t. `" ]% L8 a' U
5.1 连接选项中有一个是/opt:nowin98,意思是将段的大小设定成为Win2000适应
( [/ b1 i2 p9 J O6 R的。编译看看:哇塞,变成了2,560byte。看来这个选项确实把文件变小了N多。
) t3 u5 {& i) @# q2 p1 I5.2 在查察连接选项中还有没有什么特别的。发现/align:xx还可以将段大小缩
. v4 C) |1 q$ S0 S. J+ L小。通过UltraEdit察看刚才/opt:nowin98编译出来的文件,发现每个段的大小都1 L( q; `; B- K
是4K的整数倍。看来/align:xx还有减小的趋势。试一把再说:添加连接选项:6 c% K! S* b: R1 J1 Z! [) P
/align:16(这个大小已经是能够设定的最小的了)。看看结果:1,408Bytes。厉
6 c! o- t" n; `害,现在代码更小了。: q- }7 H5 x* \) c9 L
5.3 现在回想起来,执行文件大小有数据段,执行代码段等等,如果把这些段都合3 c& b8 k, J K- r7 v, m6 E
并起来,是不是就会把段之间的冗余有减小了呢?再试试看:添加选项:
/ f! @" c8 S% |+ W, M5 u/merge:.data=.text /merge:.rdata=.text。再看看文件大小:1,328bytes。真的. k* q; `' ]8 m. ]& x$ X
很不错了。
" u6 b0 Z0 j x" P; K; n' }
0 X$ q) y) `( c$ O- l6、刚才的设定确实不错,似乎达到了我们想要的极限了。但是回头想一下,如果
, H% f( j/ T2 \1 m& l没有CRT库的话,会不会更小了?实际上确实这样。添加连接选项: /entry:
+ J5 ?9 k+ h; Q) G8 K Y& lmain,把入口地址直接指向我们的main函数看看。得到592Bytes。4 g7 {8 I- c; }: K5 L; M
6 E% C* g' F, @
最终我们得到我们最后的大小592Bytes了。我想这也许是我们通过编译器能够编译
* ?+ P. N0 D: E+ U出来的最小的代码了。6 h: k) L5 y; c5 C9 D5 x
0 L! B, B4 m* m J6 M结论:
& q) v! `# Z. d- ^( k" n通过上述的步骤,我们了解了如何修改那些编译连接选项来达到执行文件瘦身的目% y* h9 X8 N! |+ c/ Q8 n
的。但是,通常来讲,在我们的Release文件当中,并不需要如此小的执行文件。
0 x! h" v7 q; M! z如果想达到瘦身的目的,修改为library:MutiThreaded Dll和添加/opt:nowin98已
q" S6 t1 Q, q3 Y- L经是很好的选择了。其他别的选项在编译的时候或多或少的有警告出现,而且,带
$ w* L: \1 p5 y( z9 h+ ^2 H有那些编译选项编出来的执行文件也不一定在各个平台上能够适用。4 d- n* k. Q& H2 X
: F# e' g m/ c' v I
另外:如果你的执行文件即使通过了这些设定还是比较大的话,也可以通过一些' o0 s4 K/ {7 O3 x; L
EXE文件压缩工具来进行压缩。比如UPX等等。在此不再细说了。
/ ~ z- d9 x' @ r, u6 A
! Y3 j5 a7 l9 ^ n0 @以上部分的不足之处,还请多多指正。 |
|