在 2026 年的今天,可以毫不客气地说:不会用 CMake 的嵌入式工程师是不完整的。
如果你还在用 Keil 的 .uvprojx 或 IAR 的 .ewp 来管理工程,由于这些是私有二进制(或 XML)格式,Git 合并冲突时你会想哭。而 CMake 是纯文本的脚本,天生对版本控制友好。
告诉 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)
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 )
set(SOURCES Core/Src/main.c Core/Src/stm32f4xx_it.c Core/Src/system_stm32f4xx.c Startup/startup_stm32f407xx.s )
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 )
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
| cmake -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=arm-none-eabi-gcc.cmake
ninja -C build
|
总结
一旦你切到了 CMake,你会发现新世界的大门打开了:它可以无缝集成 VS Code,可以轻松接入 CI/CD 流水线,可以方便地在一个工程里编译多个 Target(比如单元测试和固件)。