减小GCC目标EXE代码大小?

5
当我编译一个空操作程序时:
int main(void)
{
    return 0;
}

使用各种编译器:
GCC(与LLVM类似):使用-s编译,产生了一个10-KiB的可执行文件。 - 包含的节: .CRT, .bss, .data, .idata, .rdata, .text, .tls - 依赖于msvcrt.dllkernel32.dll MSVC 2010:使用/MD /Ox编译,产生了一个5.5 KiB的可执行文件。 - 包含的节: .data, .rdata, .reloc, .text - 依赖于msvcr100.dllkernel32.dll - 可以通过将.rdata.text合并来进一步减小文件大小。
Windows Driver Kit 7.1: 使用/MD /Ox编译,并通过链接msvcrt_winxp.obj使其可以在XP上运行,产生了一个6.5 KiB的可执行文件。 - 包含的节: .data, .rdata, .text - 依赖于msvcrt.dllkernel32.dll - 可以通过将.rdata.text合并来进一步减小文件大小。
Windows 2003 Driver Development Kit:产生了一个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之类的打包工具。)


你能解释一下为什么要问这个问题吗?你经常编译这样微小的程序吗?难道对于编译器来说,编译现实中更大的程序不是更重要吗?(大多数程序都比这个大得多)! - Basile Starynkevitch
请返回已翻译的文本:https://dev59.com/InM_5IYBdhLWcg3wWRyV http://embeddedfreak.wordpress.com/2009/02/10/removing-unused-functionsdead-codes-with-gccgnu-ld/ - Ulterior
@Ulterior:-s选项与strip基本相同。其他选项也没有帮助。 - user541686
在Linux/x86-64/Debian/Sid上,使用gcc-4.6 -O2 -flto -s nop.c -o nop编译,得到一个4408字节的nop文件;使用gcc-4.6 -Os -flto -s nop.c -o nop编译,则得到一个4392字节的文件。 - Basile Starynkevitch
@BasileStarynkevitch:其中一部分是因为我有点偏执,另一部分确实是实际问题:我经常发送可执行文件的Base64版本,而且当你将其粘贴在消息内时,发送1千字节可执行文件的Base64版本比发送10千字节可执行文件方便得多。 - user541686
你不会至少发送几百行源代码的程序吗? - Basile Starynkevitch
1个回答

3
这不是一个特别有意义的事情。也许可以消除一些东西,但只要你有一个实际执行任务的程序,它就会再次引入这些东西。
例如,在另一个平台上(我不做太多Windows相关的东西),程序的最小大小比您想象的要大,因为每个程序都有一个atexit处理程序来进行清理。该处理程序具有可能出错的情况,这意味着它会引入printf和所有的I/O相关的东西。Atexit本身也会引入malloc和所有的内存管理相关的东西。毫无疑问还有其他一些细节。最终结果是静态二进制文件大小为400KB。这在一个空操作程序中很恼人,但实际上所有的程序都需要这些东西,所以这是一个无关紧要的问题。
总的来说,如果想要最小化程序大小,请使用-Os编译,并尝试使用-flto-fwhole-program(但后者需要对构建过程进行大量更改)。此外,不要使用-g,并剥离最终的二进制文件(如果这样不会破坏它们)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接