减少GCC目标EXE代码大小?

Meh*_*dad 5 size executable gcc llvm

当我编写一个无操作程序时:

int main(void)
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

与各种编译器:

  • GCC(与LLVM类似的结果):提供10-KiB可执行文件(编译-s)

    • 部分:.CRT,.bss,.data,.idata,.rdata,.text,.tls

    • 取决于msvcrt.dllkernel32.dll

  • MSVC 2010:获得5.5 KiB可执行文件(编译/MD /Ox)

    • 部分:.data,.rdata,.reloc,.text

    • 取决于msvcr100.dllkernel32.dll

    • 本来通过合并进一步减少.rdata.text

  • Windows驱动程序工具包7.1:提供6.5 KiB可执行文件(编译/MD /Ox,链接msvcrt_winxp.obj以允许它在XP上运行)

    • 部分:.data,.rdata,.text

    • 取决于msvcrt.dllkernel32.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等)

ams*_*ams 3

这并不是一件特别有意义的事情。也许可以消除一些东西,但是一旦你有了一个真正可以做任何事情的程序,它就会把这些东西直接拉回来。

例如,在另一个平台上(我不做太多 Windows 的事情),程序的最小大小比您想象的要大,因为每个程序都有一个 atexit 处理程序需要清理。该处理程序可能存在错误情况,这意味着它会引入 printf 和所有 I/O 内容。Atexit 本身也引入了 malloc 和所有内存处理的东西。毫无疑问,除此之外还有其他一些内容。最终结果是 400KB 的静态二进制大小。这在无操作程序中很烦人,但实际上所有程序都需要这些东西,所以这是一个有争议的问题。

一般来说,如果您想最小化程序大小,请使用 进行编译-Os,并尝试使用-flto or -fwhole-program(但这最后将需要对您的构建过程进行大量更改)。另外,不要使用-g,并删除最终的二进制文件(如果这不会破坏它们)。