当我编写一个无操作程序时:
int main(void)
{
return 0;
}
使用各种编译器:
GCC(与LLVM类似的结果):提供10-KiB可执行文件(使用-s
编译)
章节:.CRT
,.bss
,.data
,.idata
,.rdata
,.text
,.tls
< / p>
取决于msvcrt.dll
和kernel32.dll
MSVC 2010:提供5.5 KiB可执行文件(使用/MD /Ox
编译)
章节:.data
,.rdata
,.reloc
,.text
取决于msvcr100.dll
和kernel32.dll
将.rdata
与.text
合并
Windows驱动程序工具包7.1:提供6.5 KiB可执行文件(使用/MD /Ox
编译,与msvcrt_winxp.obj
链接以允许它在XP上运行)
章节:.data
,.rdata
,.text
取决于msvcrt.dll
和kernel32.dll
将.rdata
与.text
合并
Windows 2003驱动程序开发工具包:提供3.5 KiB可执行文件
章节:.data
,.rdata
,.text
取决于msvcrt.dll
将.rdata
与.text
合并
Tiny C Compiler(TCC):提供1.5 KiB可执行文件
章节:.data
,.text
取决于msvcrt.dll
所以我想这个问题很简单:
是否可以进一步降低GCC或LLVM的目标可执行文件大小,使它们更接近可能的最小值,同时仍然链接到msvcrt.dll
?
(编辑:我显然不是在寻找像UPX
这样的包装工具。)
答案 0 :(得分:3)
这不是一件特别有意义的事情。有可能消除一些东西,但只要你有一个实际上做任何事情的程序,它就会把这些东西直接拉回来。
例如,在另一个平台上(我没有做太多的Windows工作),程序的最小大小比你想象的要大,因为每个程序都有一个atexit处理程序来清理。该处理程序有一个可能的错误情况,这意味着它拉入printf和所有I / O的东西。 Atexit本身也会引入malloc和所有内存处理的东西。毫无疑问,还有一些其他的东西。最终结果是400KB静态二进制大小。这在无操作程序中很烦人,但实际上所有程序都需要这些东西,所以这是一个没有实际意义的点。
一般情况下,如果您想最小化程序大小,请使用-Os
进行编译,并尝试使用-flto
或 -fwhole-program
(但最后需要对构建过程进行了大量更改)。另外,不要使用-g
,并删除最终的二进制文件(如果这不会破坏它们)。