我有一个小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可执行文件也会进行静态链接。
答案 0 :(得分:6)
您的x86可执行文件可能是动态链接的,因此您使用的任何标准库函数 - malloc
,printf
,字符串和数学函数等 - 都不包含在二进制文件中。
ARM可执行文件是静态链接的,因此这些函数必须包含在二进制文件中。这就是为什么它更大。要使其更小,您可能需要考虑使用-ffunction-sections -fdata-sections
进行编译,然后与--gc-sections
链接以丢弃二进制文件中任何未使用的函数或数据。
(" nosys.specs库"不是库。它是一个配置文件。真正的库文件在其他地方。)
答案 1 :(得分:0)
嵌入式软件移植取决于目标硬件和软件平台。 硬件平台分为mcu,cpus,可以运行linux操作系统。 软件平台包括编译器工具链和库。
比较mcu和x86硬件平台的程序映像大小毫无意义。 但是,使用不同的工具链来比较相同类型CPU上的程序图像大小是值得的。