test.c:

int main()
{
    return 0;
}

我没有使用任何标志(我是 gcc 的新手),只是使用命令:

gcc test.c

我已经用了最新的 GCC 的 TDM 构建 在 win32 上。生成的可执行文件几乎有 23KB,对于空程序来说太大了。

如何减小可执行文件的大小?

有帮助吗?

解决方案

不要按照其建议,但对于娱乐的缘故,阅读这个'故事'有关使最小可能的ELF二进制。

其他提示

我怎样才能减小它的大小?

  • 不要这样做。你只是在浪费时间。
  • 使用 -s 标志去除符号 (gcc -s)

默认情况下某些标准库(例如C运行时)与您的可执行相连。退房键--nostdlib --nostartfiles --nodefaultlib了解详情。链接选项描述此处

有关真正的程序第二个选项是尝试优化选项,例如-OS(优化大小)。

<强>放弃。在86的Linux,GCC 4.3.2产生5K二进制。可是等等!这是与动态链接!在静态链接的二进制是超过半MEG:516K。放松和学习生活与膨胀。

和他们说Modula-3语言永远不会去任何地方,因为200K的Hello World二进制的!


如果你想知道这是怎么回事,GNU C库,构成为包括某些特定的功能,你的程序是否依赖于它们。这些功能包括例如琐事如malloc和free,dlopen的,一些字符串处理,以及整体的 bucketload 的的,似乎有语言环境和国际化的事,虽然我无法找到任何相关的手册页的东西

对于需要最起码的服务程序创建小的可执行文件是的的设计目标作为glibc的。为了公平起见,它也一直的的,因为我曾经使用过(半打)。每次工作运行时系统的设计目标

其实,如果你的代码什么也不做,就是它甚至公平的编译器仍然会创建一个可执行文件? ; - )

那么,在Windows上的任何可执行仍然有大小,但它可以是合理的小。随着旧的MS-DOS系统,一个完整的什么都不做的应用也只是一对夫妇的字节。 (我觉得四个字节使用21H中断关闭程序。)再说,这些应用程序被直接装载到内存中。 当EXE格式越来越流行,事情改变了一点。现在可执行文件中,关于该过程本身,如代码和数据段加上一些校验和版本信息的搬迁附加信息。 引进的Windows添加另一头的格式,告诉MS-DOS,它不能执行可执行文件,因为它需要在Windows下运行。而Windows会承认它没有问题。 当然,可执行格式也扩展用资源的信息,如位图,图标和对话的形式和其他更多。

一个什么都不做的可执行文件将时下是4和8千字节之间的大小,取决于你的编译器和每一个你已经使用,以减少它的大小的方法。这将是在大小发生UPX实际上将导致更大的可执行文件!在你的可执行文件额外字节可能会增加,因为你添加某些库到您的代码。特别是随着初始化的数据或资源的库将增加相当数量的字节。添加调试信息也增加了可执行文件的大小。

不过,虽然这一切使得一个很好的锻炼,以减少大小,你可以不知道它是否实用,只是继续担心的应用消肿。现代硬盘将在段划分的文件并为真正的大硬盘,差别会非常小。然而,麻烦的金额,将采取保持一定的尺寸尽可能小会减慢发展速度,除非你是谁把它们的优化专家开发。这些种类的优化不倾向于提高性能,并考虑到大多数系统的平均磁盘空间,我不明白为什么它会成为现实。 (不过,我不优化自己的代码以类似的方式,但话又说回来,我对这些优化的经验。)


有兴趣在 EXE头?它开始以字母MZ,对于“马克·茨柏克沃斯基”。第一部分是旧式MS-DOS头用于可执行程序和用作存根MS-DOS说程序是的一个MS-DOS可执行文件。 (在二进制,你可以找到的文字基本上是它所做的一切“此程序无法在DOS模式下运行。”:显示该消息其次是PE头,其中Windows将识别和使用,而不是MS-DOS头部,它开始以字母 PE为可移植可执行。在此之后第二头会有可执行文件本身,对代码和数据的若干块划分。标题包含特殊的重新分配表,它告诉OS要加载特定块。如果你能保持这个到了一个极限,最终的可执行文件可以然后小于4 KB,但90%。将标题信息和无功能。

我喜欢DJGPP FAQ 很多年以前解决这个的方式:

  

在一般情况下,通过查看的“你好”的程序的大小判断码量是没有意义的,因为这些方案包括主要的启动代码。 ......大多数的所有这些功能电源都浪费在“你好”节目。有一个在运行的所有的代码只是为了打印一个15字节的字符串和退出没有任何意义。

什么是这项工作的目的是什么?

即使尽可能低的水平语言,C,还是有很多设置的具有发生前主可以调用。一些设置是由装载机(这需要一定的信息)进行处理,有些是通过调用主代码处理。然后有可能的,任何正常的程序就必须有库代码一点点。至少,有可能是标准库的引用,如果他们在DLL中。

检查空程序的二进制大小是毫无价值的运动在其本身。它会告诉你什么。如果您想了解一些关于代码大小,尝试写非空(最好是不平凡的)计划。与此相比,使用标准库与尽自己程序的程序。

如果你真的想知道发生了什么事情在二进制(以及它为什么这么大),然后找出可执行格式得到二进制转储工具,并采取身外之物。

什么是“size a.out”告诉你的代码,数据和BSS段的大小?大多数代码可能是其由O / S并执行设置工作调用的启动代码(在Unix机器经典crt0.o)(像的argv分拣出命令行参数成的argc,)调用main()之前。

在二进制运行条摆脱符号。用gcc版本3.4.4(cygming特殊)我从10K下降到4K。

您可以尝试连接一个自定义的运行时间设置运行时环境(调用主要的部分)。所有程序都使用同一个设置运行自带的gcc的环境,但你的可执行文件,你并不需要的数据或zero'ed内存。将意味着你可以摆脱未使用的库函数一样的memset / memcpy和减少CRT0大小。当寻找关于这个看在嵌入式环境GCC信息。嵌入式开发者一般使用自定义运行时环境的唯一的人。

的其余部分是用于加载的可执行OS开销。你是不是要同很多存在,除非你调整,通过手?

使用GCC,使用-Os而不是其他的优化参数(-O2-O3)中的一个编译程序。这告诉它以优化尺寸,而不是速度。顺便说一句,它有时可以使程序运行的速度比优化快会有,如果一些关键的部分恰好适合更多好听。在另一方面,-O3实际上可以诱导代码大小增加。

有可能也有一些连接标志告诉它从最终的二进制离开了无用的代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top