Skip to content

概念先知道

  • 外部工程:工程目录不放在 SDK 里面,SDK 通过 git 子模块嵌入工程(如 my_app/sdk/),工程只提交自己的代码,SDK 版本用 submodule 锁定。
  • BL_SDK_BASE:指向 SDK 根目录的环境变量,是“SDK 在哪里”的唯一线索;Makefile 与 CMake 都靠它定位 SDK。
  • 与 SDK 内工程的区别:文件几乎一样,唯一关键差异是 MakefileBL_SDK_BASE 指向 ./sdk,以及工程可以独立于 SDK 仓库提交。

操作步骤

1
创建工程目录并初始化 git

工程与 SDK 分离:工程自己是一个 git 仓库,SDK 作为子模块放进工程里:

mkdir my_app
cd my_app
git init
2
把 SDK 添加为子模块

子模块(submodule)是“仓库里的仓库”,SDK 以固定版本嵌入工程,便于团队协作和版本锁定:

git submodule add https://github.com/bouffalolab/bouffalo_sdk.git sdk
3
创建 CMakeLists.txt

与 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)
4
创建 Makefile

BL_SDK_BASE 指向工程内的 sdk 子目录(注意这里是 ./sdk,不是 ../..):

SDK_DEMO_PATH ?= $(abspath .)
BL_SDK_BASE ?= $(abspath ./sdk)

export BL_SDK_BASE

include $(BL_SDK_BASE)/project.build
5
创建 Kconfig / defconfig / main.c

这三个文件与 SDK 内工程 完全一致:Kconfig 引用 SDK 菜单,defconfig 写组件开关,main.c 写应用入口。

6
编译与烧录

Makefile 已自动导出 BL_SDK_BASE,直接编译烧录即可:

make CHIP=bl616 BOARD=bl616dk
make flash CHIP=bl616 COMX=/dev/ttyUSB0

每个文件是干什么的(逐文件拆解)

git 子模块:SDK 的“版本锁”

bash
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

cmake
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

make
SDK_DEMO_PATH ?= $(abspath .)
BL_SDK_BASE ?= $(abspath ./sdk)     # 关键差异:指向工程内的 sdk 子目录
export BL_SDK_BASE
include $(BL_SDK_BASE)/project.build

export BL_SDK_BASE 会把路径传给 CMake 的 $ENV{BL_SDK_BASE}find_package 才能找到 SDK。

Kconfig / defconfig / main.c

SDK 内工程 的对应文件完全一致:

  • Kconfigsource "$BL_SDK_BASE/Kconfig"(外部工程里 $BL_SDK_BASE 就是 ./sdk)。
  • defconfigCONFIG_FREERTOS =y 等组件开关。
  • main.cboard_init() 起步的应用入口。

flash_prog_cfg.ini(可选)

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 内工程能互相迁移吗?

可以。文件几乎相同,迁移只需改 MakefileBL_SDK_BASE 的路径(../.../sdk)。

遇到问题?

如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23