环境搭建与编译工具链
本文介绍 fw-AC63_BT_SDK(AC63 系列蓝牙 SoC 固件开发套件)的环境搭建流程与编译工具链:如何安装杰理编译工具链、如何通过顶层 Makefile / Code::Blocks / VS Code 三种方式编译固件,以及常见错误的排查方法。
Purpose and Scope
本页面向首次接触该 SDK 的开发者,覆盖从零开始搭建开发环境的完整链路:
- 宿主系统前提条件(Windows / Linux)
- 杰理编译工具链(clang 工具链)的安装与验证
- 顶层 Makefile 的 target 体系(芯片 × 应用 × 板级目录的映射关系)
- 三种编译方式:Code::Blocks IDE、Makefile 命令行、VS Code
- 烧录工具的选型与常见编译错误排查
属于兄弟页面、由其他目录项专门讲解的内容:应用层代码结构(apps/ 目录)、板级配置(board_xxx_cfg.h、board_xxx_global_build_cfg.h)、各应用工程(SPP+BLE / HID / Mesh)的具体功能,请参见对应目录项,本页仅在其与编译链路相关的范围内提及。
Overview
fw-AC63_BT_SDK 是杰理科技(Jieli)面向 AC63 系列蓝牙 SoC 的开源固件开发套件,支持 AC631N、AC632N、AC635N、AC636N、AC637N、AC638N 六款芯片平台,覆盖 SPP + BLE 透传、HID 人机交互、Bluetooth Mesh 三类应用。该 SDK 的编译体系具有鲜明的**「顶层 Makefile 委派 + 板级工程独立编译」**特征:根目录的 Makefile 不直接编译任何源码,而是以 $(MAKE) -C <目录> -f Makefile 的方式递归调用各 apps/<应用>/board/<板级>/Makefile;板级目录同时保留 Code::Blocks 工程文件(.cbp),使 Windows 用户可以使用 IDE 图形化编译。
编译依赖的核心外部组件是杰理编译工具链——一个以 clang 为编译器的交叉编译套件。在 Linux 下它被约定安装到 /opt/jieli,并要求 /opt/jieli/common/bin/clang 存在;同时链接阶段对文件描述符数量有较高要求(ulimit -n 建议大于 8096)。理解这套「目录约定 + 环境变量 + make 委派」的组合,是正确搭建环境、避免「编译通过但链接失败」类问题的关键。
Architecture
下图为 SDK 编译体系的整体架构:顶层 Makefile 作为统一入口,把不同 target 委派给对应板级目录的 Makefile / Code::Blocks 工程;板级工程读取应用层源码与板级配置,调用杰理工具链(clang)编译链接,最终产出 .hex 固件供烧录工具使用。
flowchart TD
subgraph sg_Toolchain["编译工具链(外部依赖)"]
Clang["杰理 clang 工具链<br/>/opt/jieli/common/bin/clang"]
GMake["GNU make"]
end
subgraph sg_Make["Makefile 体系(仓库内)"]
TopMake["顶层 Makefile<br/>make ac632n_spp_and_le"]
BoardMake["板级 Makefile<br/>apps/*/board/*/Makefile"]
CBProj["Code::Blocks 工程<br/>board_*.cbp"]
end
subgraph sg_Src["源码与配置"]
Apps["应用层 apps/<br/>spp_and_le / hid / mesh"]
BoardCfg["板级配置<br/>board_xxx_cfg.h"]
BuildCfg["全局编译配置<br/>board_xxx_global_build_cfg.h"]
end
subgraph sg_Out["产物与烧录"]
Hex["固件 .hex"]
Flasher["烧录工具<br/>USB 升级 / 生产烧写"]
end
TopMake --> BoardMake
TopMake --> CBProj
BoardMake --> Clang
CBProj --> Clang
Apps --> BoardMake
BoardCfg --> BoardMake
BuildCfg --> BoardMake
Clang --> Hex
Hex --> Flasher
架构要点说明:
- 顶层 Makefile 是纯委派层:它不包含任何编译规则,只负责把
make <target>翻译成对特定板级目录的$(MAKE) -C调用(见 Makefile)。这使新增一个板级 target 的成本极低——只需仿照既有条目追加一条规则。 - 板级目录是编译单元:每个
apps/<应用>/board/<板级>/目录同时拥有Makefile与board_*.cbp,两者指向同一份源码与板级配置,因此同一板级既可用命令行编译也可用 IDE 编译,产物一致。 - 工具链是唯一的外部依赖:除
make与clang工具链外,SDK 不依赖其他第三方编译组件;apps/common/下的 cJSON、第三方协议等均作为源码直接参与编译。
芯片 × 应用 × 板级目录映射
顶层 Makefile 支持的 target 命名规则为 ac<芯片>_<应用>,其到板级目录的映射如下(依据 Makefile 归纳):
| Target 前缀 | 芯片系列 | spp_and_le | hid | mesh |
|---|---|---|---|---|
ac638n_ | AC638N | board/br34 | board/br34 | board/br34 |
ac632n_ | AC632N | board/bd19 | board/bd19 | board/bd19 |
ac631n_ | AC631N | board/bd29 | board/bd29 | board/bd29 |
ac636n_ | AC636N | board/br25 | board/br25 | board/br25 |
ac637n_ | AC637N | board/br30 | board/br30 | board/br30 |
ac635n_ | AC635N | board/br23 | board/br23 | board/br23 |
可见同一芯片的三个应用共用同一个板级目录(如 br34 同时服务 spp_and_le、hid、mesh),板级差异通过 board_*.cbp / board_xxx_global_build_cfg.h 中的功能开关体现;Code::Blocks 工作区文件 default.workspace 中同样按 6 芯片 × 3 应用列出了全部 18 个 .cbp 工程(见 default.workspace)。
环境搭建步骤
前提条件
SDK 官方支持两种宿主环境(见 README.md):
| 系统 | 说明 |
|---|---|
| Windows | 推荐使用 Code::Blocks IDE 编译,也可用 tools/make_prompt.bat 进入预配置的命令行环境执行 make |
| Linux | 支持 Makefile 命令行编译,工具链需安装到 /opt/jieli 约定目录 |
无论哪种系统,都需要杰理编译工具链作为编译后端。该工具链以 clang 为交叉编译器,是仓库内所有板级 Makefile 与 .cbp 工程共同依赖的编译后端。
安装杰理编译工具链
安装步骤(依据 README.md):
- 从杰理官方文档获取工具链安装包:https://doc.zh-jieli.com/Tools/zh-cn/dev_tools/dev_env/index.html
- Linux 用户可直接从 http://pkgman.jieliapp.com/doc/all 获取下载链接
- 下载后将工具链解压到
/opt/jieli目录,并确认/opt/jieli/common/bin/clang存在(注意目录层次,这是最常见的安装失败点) - 安装完成后验证:
# 验证工具链是否安装成功
clang --version
Source: README.md
设计意图:工具链的目录约定(/opt/jieli/common/bin/clang)而非环境变量 PATH 是 Makefile 体系查找编译器的依据,因此在 Linux 下「解压位置正确」比「配置 PATH」更重要;若 clang 无法通过命令行直接调用,通常是 PATH 未配置或安装目录层次错误。
Linux 下的额外系统调优
顶层 Makefile 的注释明确要求(见 Makefile):
- 文件描述符限制:
ulimit -n的结果需要足够大(建议大于 8096),否则链接阶段可能因「打开文件太多」而失败。可通过ulimit -n 8096临时调大,或写入 shell 配置文件持久化。
# 建议在编译前执行,避免链接期 Too many open files 错误
ulimit -n 8096
Source: Makefile
该要求源于 SDK 链接时需要对大量目标文件与库文件建立句柄,默认的 1024 限制在大型固件工程中必然触发失败,因此被写入 Makefile 头部注释作为显式前置条件。
Windows 环境:Code::Blocks 与 make_prompt
Windows 用户有两条路径:
- IDE 路径:打开板级目录下的
board_*.cbp工程文件(如AC632N_hid.cbp),在 Code::Blocks 中执行 Build → Build(快捷键Ctrl+F9)即可编译。 - 命令行路径:双击
tools/make_prompt.bat打开预配置的命令行环境——该脚本已设置好所有环境变量和make的路径,解决 Windows 下make不是有效命令的问题(见 README.md)。
此外,仓库根目录的 default.workspace 是一个 Code::Blocks 工作区文件,将全部 18 个板级工程(6 芯片 × 3 应用)组织在一个工作区中(见 default.workspace),方便在 IDE 内切换不同目标工程。
编译方式详解
方式一:Code::Blocks(推荐 Windows 用户)
# 1. 进入对应的板级目录
cd apps/hid/board/bd19/
# 2. 双击打开 .cbp 工程文件(如 AC632N_hid.cbp)
# 3. 在 Code::Blocks 中点击 Build → Build (Ctrl+F9)
# 4. 编译成功后,使用 USB 升级工具烧录生成的 .hex 文件
Source: README.md
方式二:Makefile 命令行
# Windows 用户
双击 tools/make_prompt.bat 打开命令行环境
# Linux/macOS 用户
cd SDK 根目录
# 编译完整工程
make ac632n_spp_and_le
# 编译完成后,在对应 board 目录下找到生成的 .hex 文件
Source: README.md
命令行方式下,顶层 Makefile 的实际动作是把 target 翻译成子工程调用。以 ac632n_spp_and_le 为例:
ac632n_spp_and_le:
$(MAKE) -C apps/spp_and_le/board/bd19 -f Makefile
clean_ac632n_spp_and_le:
$(MAKE) -C apps/spp_and_le/board/bd19 -f Makefile clean
Source: Makefile
可以看到每个 target 都配套一个 clean_<target> 规则,二者共享同一目录调用,仅附加 clean 参数,保证「清理」与「编译」作用于同一编译单元。
方式三:VS Code
仓库已预配置 VS Code 编译任务,按 Ctrl+Shift+B 即可弹出任务列表选择编译目标(见 README.md)。该方式内部仍然复用 Makefile 体系,只是通过 VS Code 任务封装了命令行调用。
板级目录中的编译相关文件
每个板级目录(如 apps/hid/board/bd19/)内与编译链路直接相关的文件(见 README.md):
| 文件 | 作用 |
|---|---|
Makefile | 命令行编译脚本(顶层 Makefile 委派的实际执行者) |
board_*.cbp | Code::Blocks 工程文件(IDE 编译入口) |
board_xxx.c | 板级初始化代码(参与编译的源文件之一) |
board_xxx_cfg.h | 板级配置:引脚、外设等 |
board_xxx_global_build_cfg.h | 全局编译配置:功能开关,决定裁剪/启用哪些模块 |
Core Flow:一次完整的编译-烧录流程
下图以 make ac632n_spp_and_le 为例,展示从命令行入口到固件落盘的完整链路:
sequenceDiagram
participant Dev as 开发者
participant Top as 顶层 Makefile
participant Board as 板级 Makefile<br/>apps/spp_and_le/board/bd19
participant Clang as 杰理工具链 (clang)
participant Out as 产物目录 (.hex)
participant Flash as USB 升级工具
Dev->>Top: make ac632n_spp_and_le
Top->>Board: $(MAKE) -C apps/spp_and_le/board/bd19 -f Makefile
Board->>Clang: 编译 C 源码(含板级配置头文件)
Clang-->>Board: 目标文件 (.o)
Board->>Clang: 链接(高文件描述符占用)
Clang-->>Out: 生成 .hex 固件
Dev->>Flash: 使用 USB 升级工具烧录 .hex
Flash-->>Dev: 固件写入目标板完成
流程要点:
- 入口委派:顶层 Makefile 不编译任何代码,仅负责 target → 板级目录的映射(
make通过.PHONY声明确保同名文件不会干扰目标执行)。 - 板级编译:板级 Makefile 拉取应用层源码(
apps/)与板级配置(board_xxx_cfg.h、board_xxx_global_build_cfg.h),调用clang完成编译与链接。 - 产物:固件以
.hex格式输出到对应 board 目录,供烧录工具使用。 - 烧录:
.hex文件通过 USB 升级工具(或生产烧写工具/无线测试盒)写入目标板。
烧录工具选型
编译产物 .hex 需要配合杰理官方烧录工具使用(见 README.md):
| 工具 | 用途 | 获取方式 |
|---|---|---|
| USB 升级工具 | 将固件烧录到目标板(开发期最常用) | 官方申请链接 + 使用文档 |
| 生产烧写工具 | 量产/裸片烧写 | 使用文档 |
| 无线测试盒 | 空中升级/射频标定/产品测试 | 官方申请链接 + 使用文档 |
设计意图:三类工具覆盖「开发调试 → 产线量产 → 售后测试」三个生命周期阶段。开发期只需 USB 升级工具 + 编译出的 .hex 即可完成迭代;量产场景才需要生产烧写工具与无线测试盒。
Usage Examples
编译单个工程
# 编译 AC632N 的 SPP+BLE 工程(顶层 target)
make ac632n_spp_and_le
Source: Makefile
编译全部工程 / 全部清理
all: ac638n_spp_and_le ac632n_spp_and_le ac631n_spp_and_le ac636n_spp_and_le ac637n_spp_and_le ac635n_spp_and_le ac638n_hid ac632n_hid ac631n_hid ac636n_hid ac637n_hid ac635n_hid ac638n_mesh ac632n_mesh ac631n_mesh ac636n_mesh ac637n_mesh ac635n_mesh
@echo +ALL DONE
clean: clean_ac638n_spp_and_le clean_ac632n_spp_and_le clean_ac631n_spp_and_le clean_ac636n_spp_and_le clean_ac637n_spp_and_le clean_ac635n_spp_and_le clean_ac638n_hid clean_ac632n_hid clean_ac631n_hid clean_ac636n_hid clean_ac637n_hid clean_ac635n_hid clean_ac638n_mesh clean_ac632n_mesh clean_ac631n_mesh clean_ac636n_mesh clean_ac637n_mesh clean_ac635n_mesh
@echo +CLEAN DONE
Source: Makefile
make all 会依次编译 18 个工程(6 芯片 × 3 应用),make clean 逐一清理;二者通过 .PHONY 声明避免与同名文件冲突(见 Makefile)。
验证工具链安装
clang --version
Source: README.md
Configuration Options
环境搭建阶段涉及的关键配置项与约定:
| 配置项 | 类型 | 默认值 / 约定 | 说明 |
|---|---|---|---|
/opt/jieli/common/bin/clang | 路径 | Linux 约定安装位置 | 杰理工具链编译器,必须存在于该路径(注意目录层次) |
| 工具链下载源 | URL | http://pkgman.jieliapp.com/doc/all | Linux 下获取工具链安装包 |
ulimit -n | 系统限制 | 建议 > 8096 | 文件描述符上限,过小会导致链接失败(Too many open files) |
tools/make_prompt.bat | 脚本 | Windows 命令行入口 | 预配置环境变量与 make 路径,解决 make 命令不可用问题 |
default.workspace | 文件 | 仓库根目录 | Code::Blocks 工作区,聚合 18 个 .cbp 工程 |
| 编译 target | make 参数 | ac<芯片>_<应用> | 由顶层 Makefile 解析并委派给板级目录 |
Failure Modes、边界情况与并发注意
环境搭建与编译阶段的高频故障及官方给出的处置方式(见 README.md):
| 错误信息 | 根因 | 处置 |
|---|---|---|
clang: command not found | 未安装杰理编译工具链,或环境变量未配置 | 重新安装工具链;Linux 下确认解压到 /opt/jieli 且 /opt/jieli/common/bin/clang 存在;检查 PATH |
Too many open files | Linux 文件描述符限制过小 | 执行 ulimit -n 8096 增大限制(建议写入 shell 配置持久化) |
Windows 下 make 不是有效命令 | make 未加入 PATH | 使用 tools/make_prompt.bat 进入预配置命令行环境 |
边界情况与注意事项:
- 目录层次敏感:工具链「解压到
/opt/jieli且common/bin/clang存在」是 Makefile 体系的硬性约定,解压层级错误(多套一层目录)是最隐蔽的失败方式,此时clang --version可能仍能通过(若 PATH 指向其他 clang),但板级 Makefile 在链接时可能定位不到正确工具链。 .PHONY与同名文件:顶层 Makefile 通过.PHONY声明所有 target,防止仓库中恰好存在名为clean、all或ac632n_spp_and_le的文件时 make 误判目标已是最新而不执行(见 Makefile)。- 并发/并行构建:Makefile 体系本身是顺序委派结构(
all逐个调用子工程),未在顶层启用-j并行;若用户自行使用make -jN,需注意 18 个子工程可能同时争用文件描述符,进一步放大ulimit -n的重要性。 - 跨平台产物差异:同一板级的
.cbp(Code::Blocks)与Makefile两条编译路径产出同一份.hex,但 IDE 路径依赖 Code::Blocks 自带的工具链配置,命令行路径依赖/opt/jieli约定,两者工具链版本不一致时可能出现「IDE 能编、命令行不能编」的差异,建议统一工具链版本。
Performance 与运维建议
- 链接是资源瓶颈:Makefile 注释明确将
ulimit -n与「链接失败」挂钩,说明链接阶段是文件描述符占用峰值;在 CI/容器环境中编译前必须显式调大限制。 - 全量编译成本高:
make all需要顺序编译 18 个工程,适合发布前验证;日常迭代建议只编译目标芯片/应用的单个 target(如make ac632n_spp_and_le),缩短反馈周期。 - 清理策略:切换应用类型(如从 hid 切到 mesh)或更换板级配置后,建议先执行
make clean_<target>或make clean再重新编译,避免旧目标文件污染构建产物(板级配置board_xxx_global_build_cfg.h的功能开关变化不会自动触发全量重编)。 - 产物管理:
.hex固件生成在对应 board 目录内,建议建立版本化命名规范,与board_xxx_global_build_cfg.h的功能开关变更记录对应,便于回溯。
Extension Points:新增芯片或板级 target
SDK 的编译体系为扩展预留了清晰的模式。新增一个 ac<芯片>_<应用> target 只需三步(参照 Makefile 的既有写法):
- 在
apps/<应用>/board/<板级>/下准备板级目录(含Makefile、board_*.cbp、board_xxx.c、board_xxx_cfg.h、board_xxx_global_build_cfg.h); - 在顶层 Makefile 中追加编译规则与
clean_规则,格式与既有条目完全一致($(MAKE) -C <板级目录> -f Makefile/... clean); - 将新 target 加入
.PHONY声明,并按需加入all/clean聚合目标列表,以及default.workspace中的.cbp条目。
该模式的低耦合设计(顶层只做委派、板级自治编译)使得多芯片多应用矩阵的维护成本与工程数量呈线性而非乘积关系。
Tests 说明
本仓库为固件 SDK,根目录未发现与「环境搭建」直接相关的自动化测试脚本;环境正确性主要通过 clang --version 与一次成功的 make <target> 编译来验证。工具链安装是否成功的最快检验方式即执行 make 编译任意单板工程并确认生成 .hex。
Related Links
- Makefile(顶层编译入口)
- README.md(环境搭建与快速开始章节)
- default.workspace(Code::Blocks 工作区)
- 相关目录项:工程结构(
apps/应用层布局)、板级配置(board_xxx_cfg.h与功能开关)、各应用工程(SPP+BLE / HID / Mesh) - 外部资源:杰理工具链下载(https://doc.zh-jieli.com/Tools/zh-cn/dev_tools/dev_env/index.html)、Linux 下载源(http://pkgman.jieliapp.com/doc/all)、USB 升级工具文档(https://doc.zh-jieli.com/Tools/zh-cn/dev_tools/forced_upgrade/index.html)