搭建CMake+Ninja+GCC开发GD32
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 验证
cmake--versionninja--versionCMake + Ninja 工程说明
本工程使用 CMake 生成 Ninja 构建规则,再由 Ninja 调用 ARM GCC 编译固件。
整体关系如下:
CMakeLists.txt | v cmake -G Ninja | v build/build.ninja | v ninja | v TARGET_NAME.elf / TARGET_NAME.hex / TARGET_NAME.bin / TARGET_NAME.map1. CMakeLists.txt 是什么
CMakeLists.txt是 CMake 工程的主配置文件。
它用来描述:
项目名称 使用的编程语言 源文件列表 头文件搜索路径 宏定义 CPU 编译参数 链接脚本 最终输出文件 构建后的转换动作对于嵌入式工程,它通常还会配置:
MCU 内核参数,例如 cortex-m0plus 启动汇编文件 链接脚本 .ld objcopy 生成 .hex / .bin size 输出 Flash / RAM 占用2. CMake、Ninja、GCC 的关系
三者分工不同:
CMake:读取 CMakeLists.txt,生成构建规则 Ninja:读取 build.ninja,执行具体编译命令 GCC:真正编译 C/ASM 文件并链接生成固件也就是:
CMakeLists.txt --cmake--> build.ninja --ninja--> gcc 编译/链接3. 为什么不直接手写 build.ninja
build.ninja通常不手写。
原因是:
Ninja 语法很简单,适合快速执行,不适合维护复杂工程逻辑 CMakeLists.txt 更适合描述跨平台工程结构 CMake 可以自动生成依赖关系和构建规则所以推荐维护:
CMakeLists.txt而不是维护:
build.ninja4. toolchain 文件是什么
交叉编译时,CMake 需要知道使用哪一套编译器。
因此会单独准备一个 toolchain 文件,例如:
arm-none-eabi-gcc.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. 典型目录结构
推荐目录结构如下:
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其中:
CMakeLists.txt CMake 主配置文件 arm-none-eabi-gcc.cmake ARM GCC 工具链配置 startup_xxx_gcc.s MCU 启动文件 target.ld 链接脚本 build/ CMake/Ninja 构建输出目录6. 配置工程
第一次构建前,需要先执行 CMake 配置:
cmake-S.\Project_ninja-B.\Project_ninja\build-G Ninja-DCMAKE_TOOLCHAIN_FILE=.\Project_ninja\arm-none-eabi-gcc.cmake参数含义:
-S .\Project_ninja 指定源码目录,也就是 CMakeLists.txt 所在目录 -B .\Project_ninja\build 指定构建输出目录 -G Ninja 指定生成 Ninja 构建规则 -DCMAKE_TOOLCHAIN_FILE=... 指定 ARM GCC 工具链文件配置成功后,会生成:
Project_ninja/build/build.ninja7. 编译工程
配置完成后,执行:
cmake--build.\Project_ninja\build或者进入 build 目录后直接执行:
ninja构建成功后,通常会生成:
Project_ninja/build/TARGET_NAME.elf Project_ninja/build/TARGET_NAME.hex Project_ninja/build/TARGET_NAME.bin Project_ninja/build/TARGET_NAME.map8. 清理工程
删除构建目录即可完整清理:
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.cmake9. CMakeLists.txt 常见内容
一个嵌入式 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)源文件:
set(PROJECT_SOURCES ${ROOT_DIR}/User/main.c ${ROOT_DIR}/User/system_xxx.c ${CMAKE_CURRENT_LIST_DIR}/startup_xxx_gcc.s )头文件路径:
target_include_directories(${TARGET_NAME}.elf PRIVATE ${ROOT_DIR}/User ${ROOT_DIR}/Drivers/CMSIS/Include )宏定义:
target_compile_definitions(${TARGET_NAME}.elf PRIVATE MCU_MODEL USE_FULL_LL_DRIVER )CPU 参数:
set(CPU_FLAGS -mcpu=cortex-m0plus -mthumb -mfloat-abi=soft )编译参数:
target_compile_options(${TARGET_NAME}.elf PRIVATE ${CPU_FLAGS} -Os -g3 -Wall -Wextra -ffunction-sections -fdata-sections )链接参数:
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:
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。
验证:
cmake--versionninja 找不到
确认ninja.exe所在目录已加入 PATH。
验证:
ninja--versionarm-none-eabi-gcc 找不到
如果 toolchain 文件中写了绝对路径,一般不需要加入 PATH。
检查路径是否正确:
E:/Programs/arm-gnu-toolchain/bin/arm-none-eabi-gcc.exe修改了源文件列表后怎么办
重新构建即可:
cmake--build.\Project_ninja\build如果改了 CMake 配置,建议重新配置一次:
cmake-S.\Project_ninja-B.\Project_ninja\build-G Ninja-DCMAKE_TOOLCHAIN_FILE=.\Project_ninja\arm-none-eabi-gcc.cmake11. 推荐工作流
日常开发建议流程:
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 文件后,只需要:
cmake--build.\Project_ninja\build完全清理后重新构建:
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