本文介绍了在 CMake 中使用 SEGGER 嵌入式工具链的方法,并对 SEGGER 与 ARM GCC 这两套工具链生成的代码大小进行了实际对比。对于资源受限的嵌入式项目而言,每一字节的 Flash 空间都弥足珍贵,那么不同的编译器选择会带来多大的差异呢?
我们的内部测试基于三个不同的项目:
- 一个运行在 Atmel/Microchip SAME70_Xplained Ultra 板上的 FreeRTOS 示例(下文提供了复现方法)
- 我们内部的 embench IOT 基准测试应用
- 我们内部的 emPower OS 演示应用
为了保证对比的公平性,用于比较的源码在 ARM GCC 和 SEGGER 工具链的构建之间基本保持一致,仅在某些工具链特定的代码上有所不同(例如启动/初始化代码或编译器特定的属性语法)。所有构建均配置为 “-Oz” 优化级别(即优化代码大小,对应下文提到的 “*_minsizerel” 构建预设)。此外,我们还额外展示了启用链接时优化(LTO/IPO)的效果。
通过采用本文所述的技术,你可以进一步优化固件的最终体积。关于如何使用 SEGGER CMake 工具链的一般性指南,可以在其 GitHub 仓库 https://github.com/SEGGERMicro/segger-toolchain-cmake 的 README.md 文件中找到。
构建大小比较
下面这张表格汇总了三个测试项目的关键数据,清晰地展示了 SEGGER 工具链与 ARM GCC 在代码(Code)和只读数据(RO-Data)体积上的差异。

注释:
(diff*): SEGGER 构建大小减去 ARM GCC 构建大小(负值表示 SEGGER 生成的文件更小)。
如何复现 FreeRTOS 演示的结果?
详细的复现步骤和信息,可以参考 SEGGER 知识库文章:Comparison SEGGER Toolchain and gcc with CMake。
从对比结果可以看出,在追求极致代码体积的嵌入式开发中,工具链的选择确实会带来显著影响。SEGGER 工具链在本次测试中展现出了更好的代码尺寸优化能力。这背后涉及编译器后端的优化策略、库函数的实现效率等多种因素。如果你对编译原理和底层优化感兴趣,可以深入阅读 云栈社区 上关于编译器和系统优化的讨论。
当然,选择工具链不仅仅是看体积,还需要考虑许可、技术支持、与现有开发环境的集成度等多个维度。CMake 作为一款强大的跨平台构建工具,其价值就在于能够让我们以相对统一的方式管理和切换不同的工具链,从而方便地进行此类评估与选择。

|