概念先知道
- 外部工程:工程目录不放在 SDK 里面,SDK 通过 git 子模块嵌入工程(如
my_app/sdk/),工程只提交自己的代码,SDK 版本用 submodule 锁定。 - BL_SDK_BASE:指向 SDK 根目录的环境变量,是“SDK 在哪里”的唯一线索;Makefile 与 CMake 都靠它定位 SDK。
- 与 SDK 内工程的区别:文件几乎一样,唯一关键差异是
Makefile里BL_SDK_BASE指向./sdk,以及工程可以独立于 SDK 仓库提交。
操作步骤
工程与 SDK 分离:工程自己是一个 git 仓库,SDK 作为子模块放进工程里:
mkdir my_app
cd my_app
git init子模块(submodule)是“仓库里的仓库”,SDK 以固定版本嵌入工程,便于团队协作和版本锁定:
git submodule add https://github.com/bouffalolab/bouffalo_sdk.git sdk与 SDK 内工程几乎一样,区别是 BL_SDK_BASE 指向工程内的 sdk 目录(编译前设置环境变量):
cmake_minimum_required(VERSION 3.15)
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
sdk_set_main_file(main.c)
project(my_app)BL_SDK_BASE 指向工程内的 sdk 子目录(注意这里是 ./sdk,不是 ../..):
SDK_DEMO_PATH ?= $(abspath .)
BL_SDK_BASE ?= $(abspath ./sdk)
export BL_SDK_BASE
include $(BL_SDK_BASE)/project.build这三个文件与 SDK 内工程 完全一致:Kconfig 引用 SDK 菜单,defconfig 写组件开关,main.c 写应用入口。
Makefile 已自动导出 BL_SDK_BASE,直接编译烧录即可:
make CHIP=bl616 BOARD=bl616dk
make flash CHIP=bl616 COMX=/dev/ttyUSB0每个文件是干什么的(逐文件拆解)
git 子模块:SDK 的“版本锁”
git submodule add https://github.com/bouffalolab/bouffalo_sdk.git sdk # 首次添加
git submodule update --init --recursive # 别人克隆后拉取子模块- 工程提交时只记录 SDK 的提交号,不复制 SDK 代码进自己的仓库。
- 克隆工程后需要
git submodule update --init才能拿到 SDK。 - 需要升级 SDK 时:
cd sdk && git pull,再提交子模块更新。
CMakeLists.txt
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) # BL_SDK_BASE 指向 ./sdk
sdk_set_main_file(main.c)
project(my_app)与 SDK 内工程唯一区别:BL_SDK_BASE 不再由 ../.. 推导,而是由 Makefile 显式设为 ./sdk。
Makefile
SDK_DEMO_PATH ?= $(abspath .)
BL_SDK_BASE ?= $(abspath ./sdk) # 关键差异:指向工程内的 sdk 子目录
export BL_SDK_BASE
include $(BL_SDK_BASE)/project.buildexport BL_SDK_BASE 会把路径传给 CMake 的 $ENV{BL_SDK_BASE},find_package 才能找到 SDK。
Kconfig / defconfig / main.c
与 SDK 内工程 的对应文件完全一致:
Kconfig:source "$BL_SDK_BASE/Kconfig"(外部工程里$BL_SDK_BASE就是./sdk)。defconfig:CONFIG_FREERTOS =y等组件开关。main.c:board_init()起步的应用入口。
flash_prog_cfg.ini(可选)
[FW]
filedir = ./build/build_out/my_app_$(CHIPNAME)*.bin
address = 0x000000同上,供 make flash 使用。
FAQ
为什么用 BL_SDK_BASE 而不是把 SDK 复制进工程?
子模块方式只记录 SDK 版本号,仓库小、升级可控、团队一致;复制源码会让仓库巨大且难以同步版本。
克隆工程后编译提示找不到 SDK?
子模块默认不自动拉取:先执行 git submodule update --init --recursive,确认 sdk/ 目录非空。
外部工程和 examples 内工程能互相迁移吗?
可以。文件几乎相同,迁移只需改 Makefile 里 BL_SDK_BASE 的路径(../.. ↔ ./sdk)。
遇到问题?
如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

