我有一个小的 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 可执行文件也进行静态链接。
最佳答案
您的 x86 可执行文件可能是动态链接的,因此您使用的任何标准库函数——malloc
、printf
、字符串和数学函数等——都不包括在内在二进制文件中。
ARM 可执行文件是静态链接的,因此这些函数必须包含在您的二进制文件中。这就是它更大的原因。要使其更小,您可能需要考虑使用 -ffunction-sections -fdata-sections
进行编译,然后使用 --gc-sections
进行链接以丢弃任何未使用的函数或数据来自你的二进制文件。
(“nosys.specs 库”不是一个库。它是一个配置文件。真正的库文件在别处。)
关于c - 为什么链接后我的可执行文件更大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39172325/