减少 GCC 目标 EXE 代码大小?

Posted

技术标签:

【中文标题】减少 GCC 目标 EXE 代码大小?【英文标题】:Reducing GCC target EXE code size? 【发布时间】:2011-12-17 19:09:40 【问题描述】:

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

int main(void)

    return 0;

使用各种编译器:

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 Driver Kit 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 编译器 (TCC):提供 1.5 KiB 的可执行文件

部分:.data.text

取决于msvcrt.dll

所以我想问题很简单:

是否可以进一步减小 GCC 或 LLVM 的目标可执行文件大小,使它们更接近可能的最小值,同时仍链接到 msvcrt.dll

(编辑:我显然不是在寻找像 UPX 这样的包装器)

【问题讨论】:

你能解释一下你为什么问这个问题吗?你经常编译这么小的程序吗?编译器编译出逼真的程序不是更重要吗? (大多数都更大)! ***.com/questions/1413171/…, embeddedfreak.wordpress.com/2009/02/10/… @Ulterior:-s 选项与strip 几乎相同。其他选项也没有帮助。 在带有gcc-4.6 -O2 -flto -s nop.c -o nop 的Linux/x86-64/Debian/Sid 上,我得到一个4408 字节的nop 文件,使用gcc-4.6 -Os -flto -s nop.c -o nop 编译时为4392 字节 @BasileStarynkevitch:部分原因是偏执,部分原因实际上是一个实际问题:我经常发送 Base64 版本的可执行文件,发送 Base64 版本的 1-当您将 KiB 可执行文件粘贴到例如 10-KiB 可执行文件中时一条消息。 【参考方案1】:

这并不是一件特别有意义的事情。可能会消除一些东西,但只要你有一个实际执行任何操作的程序,它就会再次将这些东西直接拉回来。

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

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

【讨论】:

以上是关于减少 GCC 目标 EXE 代码大小?的主要内容,如果未能解决你的问题,请参考以下文章

GCC 输出文件的大小似乎太大

减少 Java 堆大小

GCC - 在没有链接描述文件的情况下获取自定义部分的大小

减少exe文件

减小 pyinstaller exe 的大小

函数调用中数组分配的差异(gcc和cl.exe)