搭建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 验证

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
相关推荐
sulikey3 天前
个人Linux操作系统学习笔记2 - gcc与库的理解
linux·笔记·学习·操作系统·gcc·
REDcker5 天前
C++循环与编译器优化详解 别名不变量向量化与GCC Clang验证及perf实践
java·jvm·c++·c·clang·gcc
weixin_4217252612 天前
Windows下C语言编译指南
c语言·visualstudio·mingw·gcc·windows编译
陈eaten19 天前
win11下nasm编写汇编及链接方案
汇编·链接·nasm·gcc·golink
李日灐1 个月前
<5> Linux 开发工具:包管理 + Vim 实操 + GCC 编译流程 + 静态与动态链接详解
linux·运维·服务器·面试·vim·gcc
AlbertS1 个月前
distcc + ccache 编译递归问题排查总结
c++·cmake·gcc·g++·distcc·ccache
___波子 Pro Max.2 个月前
GCC选项 -frecord-gcc-switches:记录编译选项的利器
gcc
紫郢剑侠2 个月前
【C语言编程gcc@Kylin | 麒麟 】5:获取系统启动时间
c语言·开发语言·kylin·gcc·麒麟操作系统
wsoz2 个月前
GCC编译
linux·c语言·嵌入式·gcc