构建与链接配置
本页介绍 AW30N BLE SDK 的构建与链接配置体系,包括 Jieli 编译工具链的安装、Code::Blocks / Makefile / VS Code 三种构建方式、顶层工程文件结构、预编译库链接机制以及编译后处理流程。
Purpose and Scope
本页覆盖 AW30N SDK(sdk/ 目录)中与"构建、编译、链接"相关的全部配置与流程:
- 构建工具链(Jieli 编译工具链,基于 clang 的 PI32 交叉编译环境)
- 工程入口(
AW30N_mbox_flash.cbp、顶层Makefile) - 三种构建方式(Code::Blocks IDE、Makefile 命令行、VS Code 任务)
- 链接相关机制(
include_lib/liba/预编译静态库、头文件/库目录布局、编译后处理脚本post_build/) - 编译输出与烧录衔接
以下内容属于其他目录页的范围,本页不做展开:
- 烧录工具与固件升级流程 → 参见「烧录与升级」相关目录页
- 具体应用功能(BLE 蓝牙 / 小音箱 / 音频播放)→ 参见「mbox_flash 应用」目录页
- 环境安装之外的音频工具链 → 参见「音频工具」说明
说明:SDK 主体(
sdk/下的 Makefile、链接脚本、工具脚本)以仓库子目录形式存在。本页依据仓库顶层 README 中记录的构建指南与工程结构编写;sdk/Makefile与sdk/AW30N_mbox_flash.cbp内部的逐条编译/链接标志细节属于 SDK 子目录内容,文中已明确标注出处与可验证范围。
Overview
AW30N 是杰理科技(Jieli Tech)的 BLE 音频 SoC 系列。其 SDK 采用交叉编译模式:开发机(Windows / Linux / macOS)上运行 Jieli 提供的 clang 工具链(pi32 平台),编译产物为面向 AW30N 芯片的固件,再通过 USB 升级工具烧录到目标板。
SDK 的构建体系有三大特点:
- 双入口并行:同一套源码既可以通过 Code::Blocks 工程(
.cbp)构建,也可以通过顶层Makefile命令行构建;VS Code 则通过预配置任务调用底层命令。 - 预编译库为主:大量底层能力(解码器、编码器、音频、设备驱动、升级等)以预编译静态库(
.a)形式放在apps/include_lib/liba/,链接时由构建系统统一收集,应用层只需包含对应 API 头文件。 - 编译后处理:构建完成后的固件打包、校验、下载等步骤由
apps/app/post_build/下的脚本与工具完成,Windows 与 Linux 环境需要不同的适配(README 明确提示 Linux 需重写download_sh.c)。
理解这套配置的关键概念:
- 工程入口:
sdk/AW30N_mbox_flash.cbp是唯一列出的应用工程(mbox_flash:BLE 蓝牙 / 小音箱 / 音频播放)。 - 工具链:Jieli 编译工具链,Linux 安装在
/opt/jieli,可执行文件为/opt/jieli/pi32/bin/clang。 - 构建产物:编译成功后生成固件,由 USB 升级工具烧录。
Architecture
下图展示构建系统的整体架构与各组件间的关系:
flowchart TD
subgraph sg_DevEnv["开发环境 (Windows / Linux / macOS)"]
CB["Code::Blocks IDE<br/>AW30N_mbox_flash.cbp"]
MK["顶层 Makefile<br/>make -j4"]
VS["VS Code 任务<br/>Ctrl+Shift+B"]
BATCH["make_prompt.bat<br/>(Windows 命令行入口)"]
end
subgraph sg_Toolchain["Jieli 编译工具链"]
CLANG["clang (pi32 交叉编译器)<br/>/opt/jieli/pi32/bin/clang"]
end
subgraph sg_Src["SDK 源码 (sdk/)"]
APPSRC["apps/app/src/mbox_flash/ 应用源码"]
BSP["apps/app/bsp/ 板级支持包"]
INCLIB["apps/include_lib/ 头文件 + 预编译库"]
POSTBUILD["apps/app/post_build/ 编译后处理"]
TOOLS["tools/ 工具与脚本<br/>tools/utils/ (make、rm 等)"]
end
subgraph sg_Out["构建产物"]
FW["固件 (Firmware)"]
end
CB --> CLANG
MK --> BATCH
MK --> CLANG
VS --> CLANG
CLANG --> APPSRC
CLANG --> BSP
CLANG --> INCLIB
MK --> POSTBUILD
CB --> POSTBUILD
POSTBUILD --> FW
FW --> USB["USB 升级工具烧录"]
架构说明:
- 三个前端(Code::Blocks、Makefile、VS Code)最终都收敛到同一条交叉编译链路:
clang (pi32)读取应用源码、BSP 与include_lib/中的头文件和预编译库,产出目标文件并链接成固件。 make_prompt.bat是 Windows 下 Makefile 方式的环境入口:双击后打开带工具链 PATH 的命令行环境,随后执行make即可。post_build/位于链接之后,负责固件的打包/校验/下载衔接;这也是 Linux 需要适配download_sh.c的原因。- 链接阶段依赖的静态库集中在
include_lib/liba/,这是"链接配置"的核心数据来源。
构建工具链与环境配置
前提条件与平台支持
SDK 对不同开发平台的构建支持方式不同,README 中明确列出了适配矩阵:
| 平台 | 构建方式 | 说明 |
|---|---|---|
| Windows | Code::Blocks IDE(推荐) | 直接双击 .cbp 工程编译 |
| Linux | Makefile 命令行 | 需要重写 download_sh.c 脚本适配 Linux 环境 |
| macOS | 手动配置 | 需自行配置交叉编译工具链 |
来源:README.md
这一设计的意图在于:post_build 阶段依赖的下载/烧录脚本(download_sh.c)最初面向 Windows 环境编写,因此 Linux 用户必须自行适配;而编译主体(clang 交叉编译)本身是跨平台的,所以 Makefile 路径在 Linux 下可直接工作。
工具链安装
工具链是"杰理编译工具链",安装要点如下:
- 从杰理官方下载编译工具链(Linux 用户也可从
pkgman.jieliapp.com获取)。 - Linux 下解压到
/opt/jieli目录,并确保/opt/jieli/pi32/bin/clang存在——这是后续make能否找到编译器的关键路径。 - 安装完成后可用以下命令验证:
# 验证工具链是否安装成功
clang --version
来源:README.md
pi32 是 Jieli 芯片的 CPU 平台标识,工具链目录结构 pi32/bin/clang 表明该工具链是基于 LLVM/clang 的交叉编译器,而非 GCC。这也解释了为什么链接配置中可能出现 clang 风格的 -target / -mcpu 等选项(具体标志定义在 sdk/Makefile 与 .cbp 工程中)。
烧录配套工具
构建完成后需要烧录工具将固件写入目标板,README 列出的配套工具包括:
- USB 升级工具:将固件烧录到目标板(开发阶段主用)。
- 生产烧写工具:量产/裸片烧写(代理商处获取)。
- 无线测试盒:空中升级、射频标定、产品测试。
来源:README.md
烧录环节与构建环节通过"固件产物"衔接,具体升级流程属于「烧录与升级」目录页的范围。
构建方式详解
方式一:Code::Blocks(推荐 Windows 用户)
- 进入
sdk/目录,双击打开AW30N_mbox_flash.cbp工程文件(唯一列出的应用工程,对应 mbox_flash 应用)。 - 点击 Build → Build(快捷键 Ctrl+F9)编译。
- 编译成功后,使用 USB 升级工具烧录生成的固件。
来源:README.md
.cbp 是 Code::Blocks 的工程描述文件(XML 格式),其中定义了源文件集合、头文件搜索路径、编译器/链接器选项与输出文件名。它和顶层 Makefile 构成 SDK 的"双构建入口"。
方式二:Makefile 命令行
# Windows 用户
双击 sdk/make_prompt.bat 打开命令行环境
# 编译
make -j4
# 显示编译详情
make VERBOSE=1 -j4
来源:README.md
要点:
make_prompt.bat是 Windows 下的环境入口脚本:它把tools/utils/中的 make、rm 等工具加入 PATH,并配置好工具链环境,随后用户即可在普通命令行里直接执行make。其意义在于让 Windows 用户无需手动设置交叉编译环境变量。-j4启用 4 路并行编译,缩短构建时间;并行粒度由 Makefile 中的依赖关系决定。VERBOSE=1让 make 输出每条实际执行的编译/链接命令,便于排查-I头文件路径、-L库路径等链接参数问题——这是调试链接错误时的首选开关。
方式三:VS Code 构建
仓库预配置了 VS Code 任务,按 Ctrl+Shift+B 即可选择编译目标。
来源:README.md
VS Code 任务本质上是对 Makefile 或工程构建命令的封装,属于同一构建链路的第三种前端。
链接配置与工程结构
与链接相关的目录布局
README 中记录的 SDK 工程结构(节选与构建/链接相关部分):
fw-AW30N/
├── sdk/ # SDK 主目录
│ ├── apps/ # 应用层代码
│ │ ├── app/ # 应用入口源码
│ │ │ ├── src/ # 应用源码
│ │ │ │ └── mbox_flash/ # BLE 蓝牙/小音箱/音频播放应用
│ │ │ ├── bsp/ # 板级支持包(BSP)
│ │ │ └── post_build/ # 编译后处理脚本与工具
│ │ └── include_lib/ # 头文件与预编译库
│ │ ├── cpu/ # CPU 平台头文件
│ │ ├── decoder/ # 解码器 API 头文件
│ │ ├── encoder/ # 编码器 API 头文件
│ │ ├── audio/ # 音频 API 头文件
│ │ ├── device/ # 设备驱动头文件
│ │ ├── common/ # 公共头文件
│ │ ├── config/ # 配置头文件
│ │ ├── msg/ # 消息机制
│ │ ├── update/ # 固件升级
│ │ └── liba/ # 预编译库 (.a)
│ ├── tools/ # 编译工具与脚本
│ │ ├── make_prompt.bat # Windows 编译命令行入口
│ │ └── utils/ # 工具集(make、rm 等)
│ ├── Makefile # 顶层 Makefile
│ └── *.cbp # Code::Blocks 工程文件
├── doc/ # 文档
来源:README.md
预编译库链接机制(include_lib/liba)
链接配置的核心是 apps/include_lib/liba/ 中的预编译静态库(.a)。设计意图:
- 二进制分发、源码隔离:解码器、编码器、音频、设备驱动、消息机制、固件升级等底层模块以
.a形式发布,应用开发者只拿到include_lib/下对应的 API 头文件(decoder/、encoder/、audio/、device/、msg/、update/等目录),无需也无法修改底层实现。这保护了杰理的核心 IP,同时显著降低应用层编译时间。 - 头文件-库一一对应:每个功能域既有头文件目录又有库文件,链接器通过 Makefile /
.cbp中配置的-L(库搜索路径)与-l(库名)选项收集这些.a,因此头文件路径和库路径必须同步维护——新增一个功能域时,两处都要更新,这是链接配置中最重要的扩展点。 - CPU 平台头文件(
cpu/)与config/配置头文件参与编译期宏定义,影响被链接的代码路径(如是否启用某解码器),属于编译与链接之间隐性耦合的典型场景。
编译后处理(post_build)
apps/app/post_build/ 存放编译后处理脚本与工具,负责链接之后的固件加工步骤:固件打包、校验、以及(在 Makefile / 工程配置触发时)调用下载脚本烧录。README 特别提示 Linux 用户需要重写 download_sh.c 才能使用下载环节,说明:
post_build中有一个名为download_sh的下载脚本(download_sh.c为其源码);- 该脚本依赖 Windows 环境(可能使用了 Windows API 或命令行工具),Linux 下需重新实现等价功能;
- 这意味着
make在 Linux 下编译通常可行,但自动烧录需要适配——纯编译任务与下载任务在此处解耦。
工具集(tools/)
sdk/tools/ 提供构建所需的辅助工具:make_prompt.bat(Windows 命令行入口)与 tools/utils/(make、rm 等 GNU 工具集)。utils/ 的存在使 Windows 用户在未安装完整 GNU 环境的情况下也能执行 make,是"双入口"策略能在 Windows 上成立的基础设施。
核心构建流程
下图描述从源码到固件的完整构建链路(以 Makefile 方式为例;Code::Blocks 与 VS Code 路径在编译/链接阶段等价):
sequenceDiagram
participant Dev as 开发者
participant Env as make_prompt.bat<br/>(Windows) / Shell (Linux)
participant Make as 顶层 Makefile
participant CC as clang (pi32 交叉编译器)
participant Post as post_build 脚本
participant Out as 固件产物
Dev->>Env: 打开构建环境 (双击 bat / 进入终端)
Dev->>Make: make -j4 (或 make VERBOSE=1 -j4)
Make->>CC: 编译应用源码 + BSP<br/>(-I include_lib 各头文件目录)
CC->>CC: 生成目标文件 (.o)
Make->>CC: 链接目标文件 + liba 预编译库<br/>(-L include_lib/liba -l...)
CC-->>Make: 生成可执行/固件映像
Make->>Post: 调用 post_build 编译后处理
Post->>Post: 固件打包/校验 (Windows 含 download_sh.c 下载)
Post-->>Out: 输出最终固件
Out-->>Dev: 使用 USB 升级工具烧录到目标板
流程要点:
- 环境准备:Windows 下必须先通过
make_prompt.bat进入构建环境,否则make/rm不在 PATH 中;Linux/macOS 需自行保证工具链与 make 可用。 - 编译阶段:clang 逐个编译
apps/app/src/mbox_flash/与bsp/下的源文件,头文件搜索路径覆盖include_lib/的全部功能域目录(cpu、decoder、encoder、audio、device、common、config、msg、update)。 - 链接阶段:链接器收集目标文件与
liba/中的预编译库,按 Makefile /.cbp中定义的库顺序与链接脚本生成固件映像。链接失败时优先使用VERBOSE=1复现,检查库搜索路径与库顺序。 - 编译后处理:post_build 完成固件打包与校验;Windows 下可衔接
download_sh.c下载,Linux 需自行适配。 - 烧录:固件通过 USB 升级工具写入目标板(进入编程模式后执行),此环节详见「烧录与升级」目录页。
配置选项
以下配置项来自 README 构建指南与 SDK 工程结构的可验证信息;sdk/Makefile 与 AW30N_mbox_flash.cbp 内部定义的宏/标志(如 -D 编译宏、-mcpu、链接脚本路径等)未在顶层文档中逐条列出,需以实际工程文件为准。
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| 编译工具链 | 外部依赖 | 需手动安装 | Jieli 编译工具链;Linux 下要求 /opt/jieli/pi32/bin/clang 存在 |
| 工程入口 | 文件 | sdk/AW30N_mbox_flash.cbp | Code::Blocks 工程,唯一应用工程(mbox_flash) |
| 顶层构建入口 | 文件 | sdk/Makefile | Makefile 命令行构建入口 |
| Windows 构建环境 | 脚本 | sdk/tools/make_prompt.bat | 双击打开带工具链 PATH 的命令行 |
| 并行度 | make 参数 | —(用户指定) | 示例使用 -j4,可按机器核数调整 |
| 详细输出 | make 变量 | 关闭 | VERBOSE=1 输出每条编译/链接命令 |
| 预编译库目录 | 链接输入 | apps/include_lib/liba/ | 静态库(.a)集合,链接时统一收集 |
| 头文件目录 | 编译输入 | apps/include_lib/*/ | cpu、decoder、encoder、audio、device、common、config、msg、update |
| 编译后处理 | 脚本目录 | apps/app/post_build/ | 固件打包/校验/下载;Linux 需重写 download_sh.c |
| 工具集 | 目录 | sdk/tools/utils/ | Windows 下提供 make、rm 等 GNU 工具 |
| 目标板状态 | 外部前置条件 | — | 烧录前需连接 USB 升级工具且目标板进入编程模式 |
来源:README.md
失败模式、边界情况与并发
常见失败模式
| 失败现象 | 根因 | 排查/规避 |
|---|---|---|
make 找不到编译器 | 工具链未安装或路径不符 | 确认 /opt/jieli/pi32/bin/clang 存在;clang --version 验证 |
| Linux 下烧录/下载失败 | download_sh.c 依赖 Windows 环境 | 按 README 提示重写 download_sh.c 适配 Linux |
Windows 命令行找不到 make | 未先运行 make_prompt.bat | 双击 make_prompt.bat 后再执行 make |
| 链接错误(符号未定义/重复定义) | liba/ 库路径或库顺序问题 | make VERBOSE=1 查看实际 -L/-l 参数;核对头文件与库是否同步 |
| 编译宏不一致导致的链接错位 | config/ 配置头与预编译库编译条件不一致 | 保持 include_lib 各域头文件与 liba 库版本配套(整体升级) |
| 烧录失败 | 目标板未进入编程模式或 USB 工具未连接 | 参照 README 提示,先连接升级工具并让目标板进入编程模式 |
边界情况
- 平台差异:同一份源码在 Windows(Code::Blocks)与 Linux(Makefile)下构建,只有
post_build的下载环节存在平台耦合,编译/链接链路本身跨平台一致——因此迁移平台时优先关注post_build与工具链路径,而非源码本身。 - 预编译库黑盒边界:
liba/中的库是二进制分发的,其内部编译宏与include_lib头文件必须配套;任何"只改头文件、不换库"或反向操作都可能导致运行时行为异常(编译期可能无法发现)。
并发与构建一致性
make -j4采用并行编译,make 依据 Makefile 依赖关系保证同一文件不被并发写;但并行编译期间的错误信息可能交错输出,排查时可回退为单线程make或使用VERBOSE=1结合-j1定位首个错误。- 多次构建之间,增量编译依赖 make 的时间戳判断;若头文件与预编译库版本被替换,建议
make clean后全量重建,避免陈旧目标文件与新版头文件/库混链。
性能与运维注意事项
- 并行度选择:
-j4是文档示例值;在多核机器上提高并行度可缩短编译时间,但会显著增加内存占用,需按开发机配置调整。 - 构建缓存:增量编译是默认行为,
post_build只处理本次链接产物,因此频繁迭代时编译很快;涉及工具链或库版本变更时必须全量重建。 - CI/脚本化:Linux 场景适合将
make接入 CI,但需在流水线中处理download_sh.c的 Linux 适配与/opt/jieli工具链的预装步骤。 - 产物管理:固件产物是后续烧录、量产、空中升级的输入,建议在构建后按版本号归档;量产烧写使用生产烧写工具(代理商处获取)。
扩展点
- 新增应用工程:复制现有
.cbp/ Makefile 目标并修改源文件集合(apps/app/src/<app>/),同时确保include_lib头文件路径被加入编译搜索路径、所需liba库被加入链接。 - 新增功能域(头文件+库):在
include_lib/下新增目录并同步更新 Makefile 的-I(头文件)与-L/-l(库)配置——头文件与库路径必须成对维护。 - 自定义编译后处理:修改或扩展
apps/app/post_build/脚本,可插入固件签名、加密、打包格式转换等步骤;Linux 下需重写download_sh.c。 - 构建前端:VS Code 任务与 Code::Blocks 工程是对同一构建链路的封装,新增 IDE 支持时只需封装顶层
make命令即可。 - 工具链升级:工具链位于
/opt/jieli(Linux)或 Code::Blocks 编译器设置中,升级时注意与liba预编译库的 ABI 兼容性。
测试与验证
SDK 顶层仓库未包含独立的构建自测脚本;构建成功与否的验证方式为:
- 工具链验证:
clang --version(README 明确给出的验证命令)。 - 构建验证:
make无错误退出并生成固件;VERBOSE=1可确认链接命令完整执行。 - 烧录验证:使用 USB 升级工具烧录后,目标板运行 mbox_flash 应用(BLE 蓝牙 / 小音箱 / 音频播放功能正常)。
Related Links
- README.md — 构建指南与工程结构
- README-en.md — Build Guide
- sdk/AW30N_mbox_flash.cbp — Code::Blocks 工程文件
- sdk/Makefile — 顶层 Makefile
- 烧录与升级流程 → 参见「烧录与升级」目录页
- mbox_flash 应用功能 → 参见「mbox_flash 应用」目录页