一、先建立心智模型:West、CMake、Ninja 的分工
Zephyr 的构建系统由三层工具协作完成,理解它们的分工是学习的第一步:
West是 Zephyr 的“元工具”,它不直接编译代码,而是负责工作区管理、多仓库版本控制,并封装了对 CMake 的调用。你可以把它理解为 Zephyr 开发的总入口——初始化工作区、拉取依赖、触发构建、烧录、调试,都通过west命令完成。
CMake是构建系统的生成器。它读取你的CMakeLists.txt、Kconfig 配置和设备树描述,执行配置阶段(configuration phase),生成 Ninja 构建文件。
Ninja是实际的构建执行器。它读取 CMake 生成的build.ninja,调用编译器完成编译和链接,产出zephyr.elf、zephyr.hex、zephyr.bin等最终文件。Zephyr 的构建过程分为两个主要阶段:配置阶段(由 CMake 驱动)和构建阶段(由 Make 或 Ninja 驱动)。
三者的调用关系是:west build→ CMake(配置) → Ninja(构建) → 产出固件。
二、构建流程全貌
一次完整的构建经过以下阶段:
west build调用 CMake
CMake 处理
CMakeLists.txt,执行find_package(Zephyr)加载开发板配置(
.dts、_defconfig)处理 Kconfig 配置(
prj.conf)处理设备树(
.dts+.overlay)生成
build.ninjaNinja 执行编译和链接
产出
zephyr.elf/.hex/.bin
三、Kconfig 与设备树:构建系统的配置层
Kconfig 和设备树是 Zephyr 构建系统中“配置”与“硬件描述”的两个核心机制。Kconfig 源自 Linux 内核,用于在编译时选择启用或禁用功能。你的应用配置通常写在prj.conf中,例如:
kconfig
CONFIG_GPIO=y CONFIG_UART_CONSOLE=y CONFIG_LOG=y
初始配置由开发板的*_defconfig与应用的prj.conf合并而成。
设备树则描述“硬件长什么样”。当你的应用需要使用开发板原生不支持的外设时,可以通过.overlay文件扩展。例如,添加一个 I2C 设备:
dts
&i2c1 { status = "okay"; my_sensor: sensor@48 { compatible = "my-vendor,my-sensor"; reg = <0x48>; }; };Shield(扩展板)机制也基于设备树 overlay 实现:开发板定义连接器引脚的标签(如arduino_i2c),Shield 的 overlay 文件引用这些标签,构建时自动“接线”。
四、项目管理:West Manifest 与多仓库
West 的核心能力是管理多个 Git 仓库。Manifest 文件是 YAML 格式的配置,定义了项目中包含的所有仓库及其版本:
yaml
manifest: projects: - name: zephyr url: https://github.com/zephyrproject-rtos/zephyr revision: main - name: hal_nordic url: https://github.com/zephyrproject-rtos/hal_nordic path: modules/hal/nordic revision: main
Manifest 文件让开发者能够轻松管理多个 Git 仓库,实现模块化开发和版本控制。你可以创建自己的 manifest 仓库,将 Zephyr 核心、你的应用代码、以及第三方模块统一管理,通过west init -m <your-manifest-url>一键初始化整个项目。
五、分阶段学习路径
第一阶段:入门筑基(1-2 周)
目标:环境搭建、理解构建流程、能编译和烧录示例。
安装 West、Zephyr SDK 和工具链
用
west build编译hello_world,用west flash烧录理解
west build→ CMake → Ninja 的调用链阅读一个示例的
CMakeLists.txt和prj.conf
里程碑:能在目标开发板上跑通hello_world,并修改源代码后重新编译烧录。
第二阶段:进阶实战(2-4 周)
目标:掌握 Kconfig、设备树、自定义应用结构。
创建自己的应用目录,编写
CMakeLists.txt和prj.conf学习 Kconfig 语法,用
menuconfig或guiconfig交互式配置编写设备树 overlay,添加外设(I2C 传感器、SPI Flash 等)
掌握
west build -p、-d、--等常用选项用
west flash和west debug完成烧录和调试
里程碑:能独立创建包含自定义外设配置的 Zephyr 应用。
第三阶段:高级深耕(1-2 个月)
目标:深入构建系统内部,掌握多仓库管理和高级构建特性。
创建自定义 West manifest 仓库,管理私有模块
编写 Zephyr 模块(module),集成第三方库
理解 Sysbuild(多镜像构建)的使用场景
掌握 Kconfig 依赖解析和设备树 binding 编写
使用
west forall、west diff等批量管理命令
里程碑:能搭建一套基于 West manifest 的多仓库项目模板,供团队复用。
六、内存与堆栈分析
ram_report的输出会按文件路径分组,并标出每个符号的字节数和占比。如果某个符号出现在(hidden)或(no paths)类别下,说明它没有可用的文件元数据,通常是链接器生成的符号或未归档的模块。
实用技巧:把报告重定向到文件,用文本编辑器按大小排序:
bash
west build -t ram_report > ram_report.txt
七、构建诊断
| 命令 | 用途 |
|---|---|
west build -t menuconfig | 启动 curses 交互界面,搜索、查看、修改 Kconfig 配置 |
west build -t guiconfig | 图形化 Kconfig 配置界面 |
west build -t traceconfig | 追踪每个 Kconfig 值的来源,排查“为什么这个配置没生效” |
west build -p always | Pristine 构建,清除缓存后重新配置,切换板子/改设备树后必备 |
west build --cmake-only | 只跑 CMake 配置阶段,不编译,用于快速检查设备树/Kconfig 是否有效 |
menuconfig里按/可以搜索符号,按?查看帮助和依赖关系,是排查“配置项为什么没生效”的首选工具。
traceconfig特别适合解决 Kconfig 配置被覆盖或依赖不满足的问题,它能显示每个值的最终来源。注意:必须在 pristine 构建之后运行,否则旧的.config会干扰结果。
八、设备树排查
| 命令 | 用途 |
|---|---|
west build --cmake-only | 只跑配置,生成最终的zephyr.dts,不编译 |
查看build/zephyr/zephyr.dts | 所有 overlay 合并后的最终设备树,确认节点、属性、状态是否正确 |
查看build/zephyr/include/generated/devicetree_generated.h | 设备树生成的宏定义,确认DT_NODELABEL等宏展开结果 |
设备树语法错误会在west build时直接报错;但如果节点存在却没有生成对应设备,通常是 Kconfig 中驱动选项未启用,需要用menuconfig确认。
九、烧录与调试
| 命令 | 用途 |
|---|---|
west flash | 烧录固件到目标板 |
west flash -r <runner> | 指定烧录器(jlink、openocd、pyocd等) |
west flash -H | 列出当前板子支持的所有 runner |
west debug | 启动 GDB 调试会话,自动连接 OpenOCD/JLink 等 |
west debugserver | 只启动调试服务器,不自动连接 GDB |
west attach | 附加到已在运行的目标,不重新烧录(适合调试已烧录的签名固件) |
west rtt | 通过 SEGGER RTT 实时读取目标日志 |
west debug会加载未签名的 ELF 文件,如果你的固件经过签名(比如 Ambiq 的 OTA 打包流程),直接用west debug可能不匹配。这时先用west flash烧录,再用west attach附加调试。
十、工作区与依赖诊断
| 命令 | 用途 |
|---|---|
west list | 列出工作区中所有项目及其路径 |
west manifest --validate | 校验 manifest 文件语法是否正确 |
west manifest --resolve | 输出合并所有 import 后的最终 manifest,排查“某个模块为什么没被拉取” |
west manifest --path | 打印当前使用的 manifest 文件路径 |
west diff | 显示工作区中所有仓库的未提交改动(你已经用过) |
west status | 类似git status,但作用于整个工作区 |
west forall -c "命令" | 在所有项目中批量执行命令,如west forall -c "git log --oneline -1" |
west update --stats | 更新时输出统计信息,排查拉取失败 |
west -v update | 详细模式,输出实际执行的 Git 命令,排查网络/权限问题 |
west config -l | 列出当前生效的所有配置项(system/global/local 合并后的结果) |
十一、配置诊断
| 命令 | 用途 |
|---|---|
west config -l | 列出所有生效配置 |
west config manifest.path | 查看当前 manifest 路径配置 |
west config zephyr.base | 查看ZEPHYR_BASE的实际来源 |
west boards | 列出所有支持的开发板,确认板子名称拼写是否正确 |
west help <command> | 查看任意命令的详细帮助 |