终极 CMake 模板:构建现代化嵌入式工程

Evek Golden Lv4

在 2026 年的今天,可以毫不客气地说:不会用 CMake 的嵌入式工程师是不完整的。

如果你还在用 Keil 的 .uvprojx 或 IAR 的 .ewp 来管理工程,由于这些是私有二进制(或 XML)格式,Git 合并冲突时你会想哭。而 CMake 是纯文本的脚本,天生对版本控制友好。

1. 交叉编译工具链 (Toolchain File)

告诉 CMake 我们要用 arm-none-eabi-gcc 而不是系统自带的 gcc
新建 arm-none-eabi-gcc.cmake:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)

# 强制指定编译器
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_SIZE arm-none-eabi-size)

# 设置一些查找路径,防止链接到 PC 的库
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

2. 核心 CMakeLists.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
cmake_minimum_required(VERSION 3.15)
project(MyFirmware C CXX ASM)

# 全局编译选项
add_compile_options(
-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
-Wall -Wextra
-ffunction-sections -fdata-sections # 用于移除未引用代码
-g3 -gdwarf-2
)

# 包含头文件
include_directories(
Core/Inc
Drivers/STM32F4xx_HAL_Driver/Inc
)

# 添加源文件(可以使用 file GLOB,但推荐手动列出以避免增量编译失效)
set(SOURCES
Core/Src/main.c
Core/Src/stm32f4xx_it.c
Core/Src/system_stm32f4xx.c
Startup/startup_stm32f407xx.s
)

# 生成 ELF
add_executable(${PROJECT_NAME}.elf ${SOURCES})

# 链接脚本
target_link_options(${PROJECT_NAME}.elf PUBLIC
-T${CMAKE_SOURCE_DIR}/STM32F407VGTX_FLASH.ld
-Wl,--gc-sections # 移除未引用代码
-Wl,-Map=${PROJECT_NAME}.map
--specs=nano.specs # 使用 Newlib-nano 减小体积
)

# 生成 Hex 和 Bin
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O ihex ${PROJECT_NAME}.elf ${PROJECT_NAME}.hex
COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin
COMMAND ${CMAKE_SIZE} ${PROJECT_NAME}.elf
)

3. 为什么是 Ninja?

CMake 只是构建系统生成器。它生成的 Makefile 还是太慢。配合 Ninja 构建工具,编译速度能比 Make 快 10 倍以上。

1
2
3
4
5
# 生成 Ninja 工程
cmake -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=arm-none-eabi-gcc.cmake

# 编译
ninja -C build

总结

一旦你切到了 CMake,你会发现新世界的大门打开了:它可以无缝集成 VS Code,可以轻松接入 CI/CD 流水线,可以方便地在一个工程里编译多个 Target(比如单元测试和固件)。

  • Title: 终极 CMake 模板:构建现代化嵌入式工程
  • Author: Evek Golden
  • Created at : 2023-07-05 15:30:00
  • Updated at : 2026-06-12 08:57:02
  • Link: https://blog.cocodemo.uno/posts/cmake8s2/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
终极 CMake 模板:构建现代化嵌入式工程