对于经常发布桌面应用程序的攻城狮而言,当然希望自己的程序只要一个可执行文件,拷贝到任何位置直接双击就能运行啦。比如笔者,经常使用MSYS2 里的mingw64 Qt静态编译程序,以便只要一个可执行文件就能到处运行。
以前,我用MFC静态编译很香。换成Qt后,感觉静态编译出来的程序,体积出乎意料的大,有的一个EXE文件就有20MB。虽然比起一个APP动辄200MB起步而言,PC上的exe有20MB也不算啥,但对从DOS时代 长城PC 286 1.2MB软盘走来的我,还是觉得有些膈应。
解决的办法是使用压缩加壳工具,UPX,配合lzma开关,能轻松达到20%以下的压缩比。

在msys2环境下,运行
pacman -S upx
而后,执行upx,看到输出就可以了。
$ upx
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2020
UPX 3.96 Markus Oberhumer, Laszlo Molnar & John Reiser Jan 23rd 2020
Usage: upx [-123456789dlthVL] [-qvfk] [-o file] file..
Commands:
-1 compress faster -9 compress better
-d decompress -l list compressed file
-t test compressed file -V display version number
-h give more help -L display software license
Options:
-q be quiet -v be verbose
-oFILE write output to 'FILE'
-f force compression of suspicious files
-k keep backup files
file.. executables to (de)compress
Type 'upx --help' for more detailed help.
UPX comes with ABSOLUTELY NO WARRANTY; for details visit https://upx.github.io
我们选取一个比较极端的文件,就是taskbus软件无线电平台的发行版,单个exe文件有40MB,我们执行命令:
$ upx --lzma --overlay=strip taskBusPlatform.exe
输出:
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2020
UPX 3.96 Markus Oberhumer, Laszlo Molnar & John Reiser Jan 23rd 2020
File size Ratio Format Name
-------------------- ------ ----------- -----------
42947762 -> 7836672 18.25% win64/pe taskBusPlatform.exe
Packed 1 file.
可以看见,直接压缩为7MB左右。参数说明:
对发布文件夹下的所有程序、DLL进行压缩.
$ find . -type f -name "*.exe" -exec upx --lzma --force --overlay=strip {} \;
$ find . -type f -name "*.dll" -exec upx --lzma --force --overlay=strip {} \;
参数说明:
–force 是忽略警告强行压缩。
压缩后,发行包的体积大大减少了。
要仔细测试压缩后的程序。一些含有资源的EXE,要看看图标、声音还在不在了。如果图标和声音都还在,那就问题不大。如本例子,下图显示正常,图标都在。

另外,对于当代的硬盘空间而言,可执行文件体积并不是问题。所以,通过7z整体压缩绿色软件,也是更为安全的方法。这种加壳的二进制文件,再次用7z压缩,效果就很差啦。所以,如果是单纯为了节约带宽,建议用7z压缩发布包即可。