构建编译
1. 前置准备
1.1 可选:使用 Robot Skills 辅助环境搭建
如果使用 Codex、Claude Code 或 Cursor 等 coding agent,可以先安装 Robot Skills,让 Agent 辅助完成 SDK 获取、依赖检查、板端连接、开发模式选择和编译验证。Robot Skills 是可选辅助,不替代下文的手工命令。
在 Agent 对话框中直接给出仓库链接即可安装Robot skills:
请安装 https://github.com/spacemit-robotics/robot-skills
如果通过agent交互安装不成功,可以手动进行安装
# Codex
npx skills add spacemit-robotics/robot-skills --agent codex
# Claude Code
npx skills add spacemit-robotics/robot-skills --agent claude-code
# Cursor
npx skills add spacemit-robotics/robot-skills --agent cursor
Robot Skills 会按当前场景选择开发模式:
| 模式 | 适用场景 | SDK 位置 | 构建/运行位置 |
|---|---|---|---|
| local | Agent 直接运行在开发板上 | 开发板 | 开发板 |
| remote | Agent 在 PC 上,通过 SSH 使用开发板 | 开发板,PC 不需要下载 SDK | 开发板 |
| hybrid | PC 本地编辑,开发板构建运行 | PC 和开发板各一份;PC 默认 ~/workspace/spacemit-robot | 开发板 |
remote 和 hybrid 模式下,Agent 会通过 SSH 登录开发板,在板端检查 SDK、安装依赖、编译和运行。Robot Skills 会先根据用户提供的 SSH 目标、端口、私钥或本机 SSH config 检查是否已经可以免密登录;如果尚未配置,会引导用户选择已有密钥或创建新密钥,并把公钥安装到开发板。这个过程通常需要用户确认目标地址,并可能在终端交互式输入一次开发板登录密码;Agent 不会保存密码,也不会要求用户把私钥内容写进对话。
首次使用时,安装好Robot-skill后建议先告诉 Agent(如codex、claude code)开发板 SSH 地址,例如:
开发板地址是 bianbu@10.0.90.29,使用hybrid开发模式,请帮我搭建SDK环境。
Agent 在执行 sudo apt install、repo init、repo sync、修改源配置或同步文件前,应先说明执行位置和影响范围,并等待用户确认。
1.2 后续章节如何使用
1.1 和后续章节是两种使用方式,不是需要全部叠加执行的步骤:
| 使用方式 | 后续章节怎么用 |
|---|---|
| 使用 SDK 手工搭建 | 跳过 1.1,从第 2 节开始按顺序执行。 |
| Agent 辅助 | 安装 Robot Skills 后,把开发板地址、SDK 状态和开发模式告诉 Agent;第 2 节及后续章节作为标准流程和命令核对依据,不需要逐条手动执行。 |
| 混合使用 | 可以让 Agent 先检查环境和生成命令,再由用户手工执行;同一个动作不要重复执行,例如不要手工执行一次 repo sync 后又让 Agent 再完整同步一次。 |
| 不使用 SDK | 如果只需要系统 ROS 2 和 Python 基础环境,执行 1.3;第 2 节及后续 SDK 获取、配置和编译步骤可跳过。 |
1.3 可选:不使用 SDK 时安装 ROS 2 与基础依赖
如果不使用 Robot SDK,只需要 ROS 2,可按本节准备最小 ROS 2 环境。若使用 Robot SDK 主流程,可跳过本节,继续执行第 2 节。
sudo apt update
sudo apt install \
ros-humble-ros-base \
ros-dev-tools \
ros-humble-robot-localization \
ros-humble-joint-state-publisher \
ros-humble-tf-transformations
该最小环境不包含 RViz、Nav2、MoveIt、ros2_control 及其他图形或硬件相关组件。
后续在新终端中使用 ROS 2 时,先加载 Humble 环境:
source /opt/ros/humble/setup.sh
2. 代码获取
通过以下方式下载 Robot SDK 的全量仓库代码:
sudo apt update
sudo apt install repo git
# 配置git用户名和邮箱(repo工具依赖git提交记录,需先配置)
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
mkdir spacemit_robot
cd spacemit_robot
# 方式一:使用GitHub
repo init -u https://github.com/spacemit-robotics/manifest.git -b main -m default.xml \
--repo-url=https://gitee.com/spacemit-robotics/git-repo
repo sync -j4
repo start robot-dev --all
# 方式二:使用Gitee:
repo init -u https://gitee.com/spacemit-robotics/manifest.git -b main -m default.xml \
--repo-url=https://gitee.com/spacemit-robotics/git-repo
repo sync -j4
repo start robot-dev --all
若仅需部分源码,可在 repo init 时使用 -g 参数限定分组,再执行 repo sync;详见 「5. 组合下载」 章节。
3. 一键编译
本节默认使用板端环境编译。若需要在PC环境下编译构建,可参考后续小节选择 Docker 编译或交叉编译。
cd spacemit_robot
source build/envsetup.sh
lunch # 选择相应方案
3.1. 全量编译
cd spacemit_robot
m
3.2. 单组件编译
cd 组件目录
mm
编译完成后,产物按以下目录结构组织:可执行文件位于 bin、库文件位于 lib、头文件位于 include、配置文件位于 share。
普通编译和 Docker 编译的安装前缀为 output/staging。交叉编译会改用独立输出根目录,安装前缀为 output/cross/<target>/staging,详见 3.5。
3.3. 编译模式选择
Robot SDK 构建系统支持普通编译、Bianbu Docker 编译和交叉编译。三种模式使用同一套 lunch、m、mm 命令入口,但执行环境和输出目录不同。
| 模式 | 适用场景 | 执行环境 | 相对编译速度 | 安装前缀 | 运行部署目录 |
|---|---|---|---|---|---|
| 普通编译 | 在开发板或已准备好依赖的本机环境中编译 | 当前系统 | k1比较慢,k3中等 | output/staging | output/rootfs |
| Bianbu Docker 编译 | 需要尽量模拟板端 Bianbu 环境,或希望隔离系统依赖 | Bianbu riscv64 Docker 容器 | 较慢 | output/staging | output/rootfs |
| 交叉编译 | 在 x86_64 PC 上生成 riscv64 目标产物 | Ubuntu host 容器 + Bianbu sysroot 容器 | 较快 | output/cross/<target>/staging | output/cross/<target>/rootfs |
上表为 x86_64 PC 性能相近、构建包集和并行度相同时的定性对比。实际耗时还会受 CPU 核数、内存、存储性能、parallel_jobs、缓存命中情况及首次创建容器、下载镜像和准备 sysroot 等因素影响。交叉编译的首次构建有额外环境准备开销,后续复用容器和 sysroot 时更能体现速度优势。
运行部署目录由 all 全量编译结束时自动生成;如果只执行 m -C、m -R 或 mm,通常只更新安装前缀,需要部署目录时再执行 ./build/build.sh deploy-rootfs,交叉编译则执行 ./build/cross_build.sh deploy-rootfs。
Docker 编译和交叉编译都需要先安装 Docker,并确保当前用户可以执行 docker 命令。两者都是显式开关,source build/envsetup.sh 后默认关闭;同一个 shell 中不要同时启用 Docker 编译和交叉编译。
3.4. Docker 编译
Docker 编译会把普通 build/build.sh 放入匹配目标板的 Bianbu 容器中执行,外部命令仍使用 m 和 mm。这不是交叉编译:编译器、系统依赖和 ROS 2 环境都来自 Bianbu 容器。
K3 target 默认使用 bianbu:4.0;如果本地没有镜像,脚本会尝试拉取 harbor.spacemit.com/bianbu/bianbu:4.0。K1 target 使用 bianbu:2.3。
常用流程:
cd spacemit_robot
source build/envsetup.sh
lunch k3-com260-minimal
# 在当前 shell 启用 Bianbu Docker 编译
m_enable_docker_build
# 全量编译
m
# 只编译 CMake / non-ROS2 包
m -C
# 只编译 ROS 2 包
m -R
单组件 Docker 编译:
cd spacemit_robot
source build/envsetup.sh
lunch k3-com260-minimal
m_enable_docker_build
cd components/peripherals/lidar
mm
mm --with-deps
脚本或 CI 也可以对单次命令显式启用 Docker 编译:
cd spacemit_robot
SROBOTIS_USE_DOCKER_BUILD=1 BUILD_TARGET=k3-com260-minimal ./build/build.sh all
SROBOTIS_USE_DOCKER_BUILD=1 BUILD_TARGET=k3-com260-minimal ./build/build.sh cmake
SROBOTIS_USE_DOCKER_BUILD=1 BUILD_TARGET=k3-com260-minimal ./build/build.sh package components/peripherals/lidar --with-deps
常用控制项:
| 命令 / 变量 | 说明 |
|---|---|
m_enable_docker_build | 在当前 shell 启用 Docker 编译 |
m_enable_docker_build disable | 在当前 shell 关闭 Docker 编译 |
SROBOTIS_DOCKER_CONTAINER_NAME=srobotis-k3-build | 指定固定容器名,便于复用或排查 |
SROBOTIS_DOCKER_PLATFORM=linux/riscv64 | 覆盖 Docker 平台,默认即为 linux/riscv64 |
SROBOTIS_DOCKER_DEVICES=/dev/xxx | 需要访问宿主设备时透传 /dev/* 设备 |
Docker 容器默认会按 SDK 路径和 Bianbu 版本复用。Docker 编译不会创建独立的 output/docker 目录,构建中间目录、日志、安装前缀和部署目录仍写回当前源码目录下的 output/:
output/
build/ # CMake / ROS2 构建中间目录
log/ # 构建日志
staging/ # 安装前缀,m / m -C / m -R / mm 的主要安装输出
rootfs/ # m all 或 deploy-rootfs 生成的运行部署目录
因此 Docker 编译后的运行、打包和部署路径与普通编译一致。
注意
- 如需从 Docker 编译切换到交叉编译,先执行
m_enable_docker_build disable;反向切换时先执行m_enable_cross_build disable。- 重新执行
source build/envsetup.sh会关闭 Docker 编译和交叉编译开关,如需继续使用对应模式,需重新执行启用命令。
3.5. 交叉编译
交叉编译用于在 x86_64 PC 上构建 riscv64 目标产物,入口是 build/cross_build.sh。它会使用 Ubuntu host 容器执行 CMake、colcon、Cargo 等构建命令,并使用 Bianbu 容器安装目标依赖、导出 riscv64 sysroot。
常用流程:
cd spacemit_robot
source build/envsetup.sh
lunch k3-com260-minimal
# 在当前 shell 启用交叉编译
m_enable_cross_build
# 全量交叉编译
m
# 只交叉编译 CMake / non-ROS2 包
m -C
# 只交叉编译 ROS 2 包
m -R
# 清理当前 target 的交叉编译输出
m clean
单组件交叉编译:
cd spacemit_robot
source build/envsetup.sh
lunch k3-com260-minimal
m_enable_cross_build
cd components/peripherals/motor
mm
mm --with-deps
mm clean
脚本或 CI 可以直接调用 cross_build.sh,不依赖 shell 快捷函数:
cd spacemit_robot
BUILD_TARGET=k3-com260-minimal ./build/cross_build.sh all
BUILD_TARGET=k3-com260-minimal ./build/cross_build.sh cmake
BUILD_TARGET=k3-com260-minimal ./build/cross_build.sh ros2
BUILD_TARGET=k3-com260-minimal ./build/cross_build.sh package components/peripherals/motor --with-deps
BUILD_TARGET=k3-com260-minimal ./build/cross_build.sh clean all
交叉编译输出目录如下:
output/cross/<target>/
build/ # CMake / ROS2 构建中间目录
log/ # 构建日志
host/ # host 侧工具前缀
sysroot/ # 从 Bianbu 容器导出的 riscv64 目标 sysroot
staging/ # 交叉编译安装前缀,m / m -C / m -R / mm 的主要安装输出
rootfs/ # m all 或 deploy-rootfs 生成的运行部署目录
toolchain-riscv64.cmake # CMake toolchain file
meson-riscv64.ini # Meson cross file
可先查看交叉编译依赖拆分,不实际编译:
BUILD_TARGET=k3-com260-minimal ./build/cross_build.sh deps all
BUILD_TARGET=k3-com260-minimal ./build/cross_build.sh deps package components/peripherals/motor
交叉编译完成后,可从 staging / rootfs 扫描 ELF 动态库并反推板端运行时 apt 依赖:
BUILD_TARGET=k3-com260-minimal ./build/cross_build.sh runtime-deps all
常用控制项:
| 命令 / 变量 | 说明 |
|---|---|
m_enable_cross_build | 在当前 shell 启用交叉编译,之后 m / mm 会转到 build/cross_build.sh |
m_enable_cross_build disable | 在当前 shell 关闭交叉编译 |
SROBOTIS_CROSS_OUTPUT_ROOT=<dir> | 覆盖默认输出目录 output/cross/<target> |
SROBOTIS_CROSS_REFRESH_SYSROOT=1 | 强制重新导出 sysroot,适用于 target 依赖变更后重新构建 |
SROBOTIS_CROSS_BIANBU_IMAGE=<image> | 覆盖 Bianbu sysroot 镜像 |
3.6. 新增应用适配交叉编译
新应用通常放在 application/native/<app> 或 application/ros2/<app> 下。如果应用使用标准 CMake 或 ament CMake 构建,构建系统会自动传入 riscv64 toolchain、sysroot 和安装前缀,一般无需在应用中重复配置交叉编译器。
适配时需完成以下配置:
- 为应用提供
package.xml,用<depend>声明 Robot SDK 仓库内的组件依赖,用<system_depend>声明 apt 系统依赖。 - 将运行库、头文件等目标依赖配置为
realm="target",它们会安装到 Bianbu sysroot。不填写realm时,应用和组件的系统依赖默认也归属 target。 - 将代码生成器和构建工具,例如
protoc、grpc_cpp_plugin、moc和 Meson,配置为realm="host",它们会安装到 x86_64 Ubuntu host 容器。 - 将应用路径加入目标方案的
enabled_packages。使用mm --with-deps时可以单独构建应用及其 SDK 依赖;使用m时则按 target 中的完整包集合构建。
例如,一个依赖 motor SDK 组件、protobuf 目标库和 host 侧 protoc 的 CMake 应用,可使用以下 application/native/my_robot_app/package.xml:
<?xml version="1.0"?>
<package format="3">
<name>my_robot_app</name>
<version>0.1.0</version>
<description>My robot application</description>
<depend>motor</depend>
<system_depend realm="target" check_kind="pkg-config" check_arg="protobuf">libprotobuf-dev</system_depend>
<system_depend realm="host" check_kind="command" check_arg="protoc">protobuf-compiler</system_depend>
<export>
<build_type>cmake</build_type>
</export>
</package>
<system_depend> 还可以使用以下属性:
| 属性 | 说明 |
|---|---|
when="cross" | 仅在交叉编译时使用该依赖;native 和 docker 可用于排除交叉编译 |
| `realm="host | target |
arch="riscv64" | 仅在当前 realm 的架构匹配时使用 |
check_kind / check_arg | 指定依赖检查方式和参数,支持 dpkg、command、pkg-config、file 和 rustlib |
再将应用加入 target 配置:
{
"enabled_packages": [
"components/peripherals/motor",
"application/native/my_robot_app"
]
}
建议先检查依赖拆分,再进行单应用构建:
BUILD_TARGET=k3-com260-my-robot ./build/cross_build.sh deps package application/native/my_robot_app
BUILD_TARGET=k3-com260-my-robot ./build/cross_build.sh package application/native/my_robot_app --with-deps
当应用的 CMake 工程内部还使用 ExternalProject_Add 启动新的 CMake 配置过程时,子工程不会自动继承顶层 toolchain,需将 SROBOTIS_CMAKE_EXTRA_ARGS 转换为 CMake 参数列表并传入子工程的 CMAKE_ARGS。如果子工程使用 Meson,需传入 --cross-file "${SROBOTIS_MESON_CROSS_FILE}"。对于需要在构建期运行的工具,应明确使用 host 侧可执行文件,不要尝试运行 sysroot 中的 riscv64 程序。
4. 方案配置
根据所选方案,可在对应的配置文件中启用或禁用组件/包的编译。若需排除特定包,将其从配置中移除即可。
ls target/k3-*.json
以 k3-com260-minimal.json 为例:
{
"version": "1.0",
"board": "k3-com260",
"product": "minimal",
"description": "K3 COM260 board - minimal build configuration",
"enabled_packages": [
"components/peripherals/imu",
"components/peripherals/motor",
"components/peripherals/lidar",
"components/agent_tools/mlink_device",
"components/model_zoo/vision"
],
"enabled_package_options": {
"components/peripherals/motor": { "enabled_drivers": ["drv_can_dm"] },
"components/peripherals/imu": { "enabled_drivers": ["drv_uart_cmp10a"] },
"components/peripherals/lidar": { "enabled_drivers": ["drv_uart_ydlidar", "drv_uart_rplidar"] },
"components/peripherals/nfc": { "enabled_drivers": ["drv_i2c_SI512"] },
"components/peripherals/pm": { "enabled_drivers": [] }
},
"options": {
"parallel_jobs": 4,
"auto_resolve_dependencies": true
}
}
修改配置文件后,重新执行 lunch <target> 选择该方案,然后再编译。
5. 组合下载
若无需下载全量 SDK,可按场景按需下载所需的包。只需在 repo init 命令末尾追加 -g 参数指定要下载的软件包分组,具体示例如下:
# 只下载AI相关的应用:Model Zoo + ai-gateway
repo init -u https://github.com/spacemit-robotics/manifest.git -b main -m default.xml \
--repo-url=https://gitee.com/spacemit-robotics/git-repo \
-g core,model_zoo,ai-gateway
repo sync -j4
repo start robot-dev --all
# 只下载人型应用:人形全套(humanoid + model_zoo_rl + simulation,仿真见 manifest component/simulation.xml)
repo init -u https://github.com/spacemit-robotics/manifest.git -b main -m default.xml \
--repo-url=https://gitee.com/spacemit-robotics/git-repo \
-g core,model_zoo_rl,humanoid,simulation
repo sync -j4
repo start robot-dev --all
# 只下载桌面机器人应用: Reachy mini
repo init -u https://github.com/spacemit-robotics/manifest.git -b main -m default.xml \
--repo-url=https://gitee.com/spacemit-robotics/git-repo \
-g core,peripherals,agent_tools,reachy_mini
repo sync -j4
repo start robot-dev --all
按需分组一览(-g 仅在 repo init 时指定,随后的 repo sync -j4 与第 2 节一致,最后执行 repo start robot-dev --all):
| 序号 | 场景 | repo init 追加 -g(接在 §2 同一条 init 命令末尾) |
|---|---|---|
| 0 | 全量下载 | 不加 -g |
| 1 | 人形全套 | -g core,model_zoo_rl,humanoid,simulation |
| 2 | 人形指定机型 | -g core,model_zoo_rl,humanoid_common,humanoid_unitree_g1,simulation |
| 3 | 桌面 Reach mini | -g core,peripherals,agent_tools,reachy_mini |
| 4 | 轮式 Linksee | -g core,ros2,linksee |
| 5 | 语音交互 Omni | -g core,multimedia,model_zoo,agent_tools,omni_agent |
| 6 | Model Zoo + ai-gateway | -g core,model_zoo,ai-gateway |
| 7 | 外设驱动基础 | -g core,peripherals,agent_tools |
| 8 | 机器人感知 | -g core,model_zoo,ros2_perception |
| 9 | 机器人外设 | -g core,peripherals |
| 10 | 规划、控制 | -g core,multimedia,model_zoo,control,ros2_planning,ros2_control |
完整分组定义以 manifest 仓库各 .xml 文件中 groups="..." 属性为准;片段路径参见 default.xml 中的 include 配置。
6. 常见问题
目录无效:
[mm] ERROR: Not a valid package directory
[mm] Hint: Run mm from a directory with CMakeLists.txt, package.xml, or build.sh
当前目录不是有效的组件目录。请确认目录中包含以下标识文件之一:
| 目录标识 | 编译逻辑 | 支持的路径示例 |
|---|---|---|
存在 CMakeLists.txt | 纯 CMake 编译 | components/peripherals/motor, application/native/* |
存在执行权限的 build.sh | 自定义脚本编译 | 任何含有 build.sh 的子目录 |
存在 package.xml (ament) | ROS2 (colcon) 编译 | middleware/ros2/*, application/ros2/* |
附录:常用编译命令
在仓库根目录加载环境并选择构建目标后,即可执行编译命令生成各组件的示例应用。
| 场景 | 编译命令 | 清理命令 | 说明 |
|---|---|---|---|
| 全量编译 | m | m clean | 编译所有组件 |
| 只编译 CMake 包 | m -C | m -C clean | 跳过 ROS2 包 |
| 只编译 ROS2 包 | m -R | m -R clean | 跳过 CMake 包 |
| 单组件编译 | cd 组件目录 && mm | mm clean | 编译当前目录组件 |
| 回到仓库根 | croot | — | 在任意子目录执行后 cd 到 SDK 根目录(与 source build/envsetup.sh 后环境配套) |