【发布时间】:2016-08-26 18:08:48
【问题描述】:
我有一个需要在不同芯片上运行的小型 C 程序。 可执行文件应小于 32kb。 为此,我有几个工具链,其中包含用于 arm、mips 等的不同编译器。
该程序由几个文件组成,每个文件都被编译成一个目标文件,然后链接在一起成为一个可执行文件。
当我使用系统 gcc (x86) 时,我的可执行文件有 15kb 大。 使用 arm 工具链,可执行文件大小为 65kb。 使用另一个工具链是 47kb。
例如,对于 arm,可执行文件中包含的所有对象加起来都是 14kb 大。
使用以下选项编译对象:
-march=armv7-m -mtune=cortex-m3 -mthumb -msoft-float -Os
使用以下选项进行链接:
-s -specs=nosys.specs -march-armv7-m
nosys.specs 库大小为 274 字节。
当我的代码只有 14kb 而库是 274 字节时,为什么我的可执行文件仍然大得多(65kb)?
更新:
根据答案的建议,我从我的代码中删除了所有 malloc 和 printf 命令,并删除了未使用的包含。我还添加了编译标志 -ffunction-sections -fdata-sections 和链接标志 --gc-sections ,但可执行文件仍然太大。
为了进行实验,我创建了一个虚拟程序:
int main()
{
return 1;
}
当我使用不同的编译器编译程序时,我会得到非常不同的可执行文件大小:
8.3 KB : gcc -Os
22 KB : r2-gcc -Os
40 KB : arm-gcc --specs=nosys.specs -Os
1.1 KB : avr-gcc -Os
那么为什么我的 arm-gcc 可执行文件要大得多? 我猜 avr-gcc 可执行文件也会进行静态链接。
【问题讨论】:
-
首先这是什么文件格式,它是原始二进制图像还是像 elf、coff 或 exe 之类的?几乎所有格式的文件大小不一定是重要的实际二进制文件的直接指标。对于 x86 与 arm,可能有一些动态库与静态库。
-
也许从查看您的链接器映射文件输出开始 - 这应该让您了解链接到图像中的内容并占用所有内存。我可以推测,但这只是——推测......
-
您的 x86 版本是否托管?即它是为在完整的 GPOS(如 WINdows 或 Linux)上运行而构建的吗?独立应用程序必须将其所有 I/O 和库代码静态链接,而 GPOS 将支持到标准库和操作系统库的动态链接,并且大部分 I/O 功能将由操作系统提供。
-
x86 构建确实是托管的,其他编译器进行静态链接(我猜)。但是例如为什么我的 amtel 芯片(avr-gcc 编译器)的 exec 比 arm-gcc 小得多?