最近一直在使用 GCC 开发 MCU,之前就一直有听到说 GCC 编译出来的代码没有 KEIL 自带的 ARMCC 体积小,而 GCC 和 ARMCC 也都持续在发展,到今天,arm-none-eabi-gcc
已经到了 14.3
的版本,ARMCC 也从 AC5
发展到了 AC6
(改名为 ARMClang),甚至最新的 KEIL 都直接删除了 AC5
,只保留了 AC6
(如果要用到 AC5
需要手动导入)。
突然很想知道这两者目前到底有多少差距。当然,在开始测试之前有必要说明,本次测试只是在给定的环境简单对比两者生成的代码大小,并不能说明谁更优秀,也不能代表所有情况下都是这个结果,仅作为一个有趣的小实验。
测试开始,首先用 CubeMX 生成两个工程,分别为 CMake 工程和 KEIL 工程,如果想自己尝试但不知道怎么用 CubeMX 的可以参考我这篇文章的前半部分:
为保持测试代码完全一样,这里直接使用 CubeMX 生成的初始项目做测试,不添加任何人为因素,首先登场的是 GCC ,先看下版本:
gcc version 14.3.1 20250623 (Arm GNU Toolchain 14.3.Rel1 (Build arm-14.174))
编译前我们先在 CMake 配置文件中去掉优化:
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_C_FLAGS_RELEASE "-Os -g0")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_CXX_FLAGS_RELEASE "-Os -g0")
我们用的是 Debug 模式,因此默认这里就是不进行优化的(-O0
)。此时,我们进行编译,编译后的内存占用如下:
[build] Memory region Used Size Region Size %age Used
[build] RAM: 1656 B 48 KB 3.37%
[build] FLASH: 5540 B 256 KB 2.11%
可以看到对于 CubeMX 生成的初始工程,不加优化,RAM 占用 1656 字节 ,FLASH 5540 字节。紧接着我们上 KEIL,并且用其默认的 AC6 进行编译:
同样的,关闭优化:
编译查看结果:
Total RW Size (RW Data + ZI Data) 1728 ( 1.69kB)
Total ROM Size (Code + RO Data + RW Data) 5828 ( 5.69kB)
神奇的事情发生了,从对于 CubeMX 的初始工程,且不加任何优化的编译结果来看,AC6 编译出的固件尺寸甚至比 GCC 14.3 还要大 233 字节!什么,不是说 KEIL 编译出来的尺寸比 GCC 更小吗,怎么这里却相反呢,而且这还是目前主推的 AC6 编译器!
等等,难道说,AC6 默认情况下编译尺寸是偏大的,而前几年 KEIL 都是用的 AC5,所以才流传下来“GCC 比 KEIL 编译出来的代码要大” 这样的说法?为了验证,我又去官网找了 AC5 的下载地址,并且导入到了最新的 KEIL 中,不得不说 KEIL 是真的想让大家都切换到 AC6 啊,就是不在新版中内置 AC5,甚至还要删除,让大家无法方便地切换。当然这也有可能是有官方的考量,我们就不探讨这个问题了,继续测试!
导入后将编译器切换到 AC5:
同样关闭优化:
编译查看结果:
Total RW Size (RW Data + ZI Data) 1720 ( 1.68kB)
Total ROM Size (Code + RO Data + RW Data) 4676 ( 4.57kB)
果然,AC5 编译出来的尺寸小了不少,与 GCC 14.3 比起来,足足少了 864 字节,当然这还是初始工程,如果在实际的开发项目中,不开任何优化或者额外进行配置这个差距肯定会更大。
此外,我还测试了 O1
到 O3
以及 GCC 下的 Os
和 AC6 下的 Oz
(Os
和Oz
分别代表了 GCC 和 AC6 下代码体积最小的优化等级)这些不同优化级别下,GCC,AC5 以及 AC6 代码体积的差异:
转换成折线图如下(AC5 的优化等级只有到 O3 因此用其生成体积最小的 O2 与其他两个比较):
可以发现,虽然 GCC 在无优化的情况下体积小于 AC6,但开启优化后其体积始终是最大的,AC5 和 AC6 各在不同的优化等级下存在体积最小的情况,但总体来说 AC5 的平均优化体积是最小的。而在各自最高优化等级下,三者的体积已经非常接近,这种等级下的最高与最低差距也不过 84 字节!
以上就是本次小实验的所有数据,再次强调,本实验仅仅是在非常单一的条件下测试一个功能非常简单的初始例程所生成的固件体积,不能代表所有情况,且并不意味着固件生成体积越小,编译器就越好,反而通过 AC6 生成的平均体积高于 AC5,且官方力推 AC6 来看,更能证明一个编译器的综合性能和其编译产生的固件大小没有直接关系!
因此,如果你因为听说 GCC 编译的体积大而对其敬而远之,那大可以放心试用一下,毕竟目前看来也只有 GCC 是完全商用免费,没有任何律师函警告的,且其差距也没有想象的那么大,甚至可以做到几乎没有差别,在现在各种大存储 MCU 问世的时代,大概率是不会存在需要靠换编译器来满足固件大小的情况了。