1.1 CMake Windows x64 MSI:
cmake-4.3.2-windows-x86_64.msi

1.2 Ninja 官方 GitHub Release
https://github.com/ninja-build/ninja/releases

解压到E:/Programs,这里路径,arm-none-eabi-gcc.cmake里面修改
1.3 gcc
https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
arm-gnu-toolchain-15.2.rel1-mingw-w64-x86_64-arm-none-eabi.zip
解压后,路径加入系统环境变量
1.4 验证
bash
cmake --version
bash
ninja --version
CMake + Ninja 工程说明
本工程使用 CMake 生成 Ninja 构建规则,再由 Ninja 调用 ARM GCC 编译固件。
整体关系如下:
text
CMakeLists.txt
|
v
cmake -G Ninja
|
v
build/build.ninja
|
v
ninja
|
v
TARGET_NAME.elf / TARGET_NAME.hex / TARGET_NAME.bin / TARGET_NAME.map
1. CMakeLists.txt 是什么
CMakeLists.txt 是 CMake 工程的主配置文件。
它用来描述:
text
项目名称
使用的编程语言
源文件列表
头文件搜索路径
宏定义
CPU 编译参数
链接脚本
最终输出文件
构建后的转换动作
对于嵌入式工程,它通常还会配置:
text
MCU 内核参数,例如 cortex-m0plus
启动汇编文件
链接脚本 .ld
objcopy 生成 .hex / .bin
size 输出 Flash / RAM 占用
2. CMake、Ninja、GCC 的关系
三者分工不同:
text
CMake:读取 CMakeLists.txt,生成构建规则
Ninja:读取 build.ninja,执行具体编译命令
GCC:真正编译 C/ASM 文件并链接生成固件
也就是:
text
CMakeLists.txt --cmake--> build.ninja --ninja--> gcc 编译/链接
3. 为什么不直接手写 build.ninja
build.ninja 通常不手写。
原因是:
text
Ninja 语法很简单,适合快速执行,不适合维护复杂工程逻辑
CMakeLists.txt 更适合描述跨平台工程结构
CMake 可以自动生成依赖关系和构建规则
所以推荐维护:
text
CMakeLists.txt
而不是维护:
text
build.ninja
4. toolchain 文件是什么
交叉编译时,CMake 需要知道使用哪一套编译器。
因此会单独准备一个 toolchain 文件,例如:
text
arm-none-eabi-gcc.cmake
它里面通常指定:
cmake
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(TOOLCHAIN_DIR "E:/Programs/arm-gnu-toolchain/bin")
set(CMAKE_C_COMPILER "${TOOLCHAIN_DIR}/arm-none-eabi-gcc.exe")
set(CMAKE_ASM_COMPILER "${TOOLCHAIN_DIR}/arm-none-eabi-gcc.exe")
set(CMAKE_OBJCOPY "${TOOLCHAIN_DIR}/arm-none-eabi-objcopy.exe")
set(CMAKE_SIZE "${TOOLCHAIN_DIR}/arm-none-eabi-size.exe")
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
这样即使 arm-none-eabi-gcc.exe 没有加入系统 PATH,CMake 也能找到它。
5. 典型目录结构
推荐目录结构如下:
text
Project_ninja/
CMakeLists.txt
arm-none-eabi-gcc.cmake
startup_xxx_gcc.s
target.ld
build/
build.ninja
TARGET_NAME.elf
TARGET_NAME.hex
TARGET_NAME.bin
TARGET_NAME.map
其中:
text
CMakeLists.txt CMake 主配置文件
arm-none-eabi-gcc.cmake ARM GCC 工具链配置
startup_xxx_gcc.s MCU 启动文件
target.ld 链接脚本
build/ CMake/Ninja 构建输出目录
6. 配置工程
第一次构建前,需要先执行 CMake 配置:
powershell
cmake -S .\Project_ninja -B .\Project_ninja\build -G Ninja -DCMAKE_TOOLCHAIN_FILE=.\Project_ninja\arm-none-eabi-gcc.cmake
参数含义:
text
-S .\Project_ninja
指定源码目录,也就是 CMakeLists.txt 所在目录
-B .\Project_ninja\build
指定构建输出目录
-G Ninja
指定生成 Ninja 构建规则
-DCMAKE_TOOLCHAIN_FILE=...
指定 ARM GCC 工具链文件
配置成功后,会生成:
text
Project_ninja/build/build.ninja
7. 编译工程
配置完成后,执行:
powershell
cmake --build .\Project_ninja\build
或者进入 build 目录后直接执行:
powershell
ninja
构建成功后,通常会生成:
text
Project_ninja/build/TARGET_NAME.elf
Project_ninja/build/TARGET_NAME.hex
Project_ninja/build/TARGET_NAME.bin
Project_ninja/build/TARGET_NAME.map
8. 清理工程
删除构建目录即可完整清理:
powershell
Remove-Item -Recurse -Force .\Project_ninja\build
然后重新配置:
powershell
cmake -S .\Project_ninja -B .\Project_ninja\build -G Ninja -DCMAKE_TOOLCHAIN_FILE=.\Project_ninja\arm-none-eabi-gcc.cmake
9. CMakeLists.txt 常见内容
一个嵌入式 CMake 工程通常包含:
cmake
cmake_minimum_required(VERSION 3.20)
project(TARGET_NAME C ASM)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
set(TARGET_NAME target_name)
set(ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
set(LINKER_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/target.ld)
源文件:
cmake
set(PROJECT_SOURCES
${ROOT_DIR}/User/main.c
${ROOT_DIR}/User/system_xxx.c
${CMAKE_CURRENT_LIST_DIR}/startup_xxx_gcc.s
)
头文件路径:
cmake
target_include_directories(${TARGET_NAME}.elf PRIVATE
${ROOT_DIR}/User
${ROOT_DIR}/Drivers/CMSIS/Include
)
宏定义:
cmake
target_compile_definitions(${TARGET_NAME}.elf PRIVATE
MCU_MODEL
USE_FULL_LL_DRIVER
)
CPU 参数:
cmake
set(CPU_FLAGS
-mcpu=cortex-m0plus
-mthumb
-mfloat-abi=soft
)
编译参数:
cmake
target_compile_options(${TARGET_NAME}.elf PRIVATE
${CPU_FLAGS}
-Os
-g3
-Wall
-Wextra
-ffunction-sections
-fdata-sections
)
链接参数:
cmake
target_link_options(${TARGET_NAME}.elf PRIVATE
${CPU_FLAGS}
-T${LINKER_SCRIPT}
-Wl,-Map=${CMAKE_BINARY_DIR}/${TARGET_NAME}.map
-Wl,--gc-sections
-Wl,--print-memory-usage
-specs=nano.specs
-specs=nosys.specs
-nostartfiles
)
生成 HEX / BIN:
cmake
add_custom_command(TARGET ${TARGET_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O ihex
$<TARGET_FILE:${TARGET_NAME}.elf>
${CMAKE_BINARY_DIR}/${TARGET_NAME}.hex
COMMAND ${CMAKE_OBJCOPY} -O binary
$<TARGET_FILE:${TARGET_NAME}.elf>
${CMAKE_BINARY_DIR}/${TARGET_NAME}.bin
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${TARGET_NAME}.elf>
)
10. 常见问题
cmake 找不到
确认 CMake 已加入 PATH。
验证:
powershell
cmake --version
ninja 找不到
确认 ninja.exe 所在目录已加入 PATH。
验证:
powershell
ninja --version
arm-none-eabi-gcc 找不到
如果 toolchain 文件中写了绝对路径,一般不需要加入 PATH。
检查路径是否正确:
text
E:/Programs/arm-gnu-toolchain/bin/arm-none-eabi-gcc.exe
修改了源文件列表后怎么办
重新构建即可:
powershell
cmake --build .\Project_ninja\build
如果改了 CMake 配置,建议重新配置一次:
powershell
cmake -S .\Project_ninja -B .\Project_ninja\build -G Ninja -DCMAKE_TOOLCHAIN_FILE=.\Project_ninja\arm-none-eabi-gcc.cmake
11. 推荐工作流
日常开发建议流程:
powershell
cmake -S .\Project_ninja -B .\Project_ninja\build -G Ninja -DCMAKE_TOOLCHAIN_FILE=.\Project_ninja\arm-none-eabi-gcc.cmake
cmake --build .\Project_ninja\build
修改 C 文件后,只需要:
powershell
cmake --build .\Project_ninja\build
完全清理后重新构建:
powershell
Remove-Item -Recurse -Force .\Project_ninja\build
cmake -S .\Project_ninja -B .\Project_ninja\build -G Ninja -DCMAKE_TOOLCHAIN_FILE=.\Project_ninja\arm-none-eabi-gcc.cmake
cmake --build .\Project_ninja\build