[i=s] 本帖最后由 业余菜狗 于 2026-8-4 08:59 编辑 [/i]
树莓派/Orange Pi 也能编译 Ai-Thinker-WB2 —— ARM 架构完整踩坑指南
适用环境:ARM 架构开发板(树莓派、Orange Pi 等)上编译 Ai-Thinker-WB2 SDK
系统:Ubuntu 22.04(aarch64 / ARM 64 位)
SDK:Ai-Thinker-WB2
关键词:ARM 交叉编译 / RISC-V 工具链 / BL602 / Ai-WB2
📌 引言
在用树莓派、Orange Pi 这类 ARM 架构开发板编译安信可 Ai-WB2 的 SDK 时,直接照官方 README 执行 make,结果一编译就报各种错误:
text
fatal error: string.h: No such file or directory
或者:
text
ABI is incompatible with that of the selected emulation
以为是自己环境装错了,其实是 SDK 自带的编译工具链是 x86 架构的,在 ARM 上根本跑不起来。
本贴把我实际踩坑、并最终编译成功的过程完整记录下来,希望能帮到同样在 ARM 平台上折腾的朋友。
🔍 问题根源:工具链是 x86 的
Ai-Thinker-WB2 SDK 克隆下来后,自带一套 RISC-V 交叉编译工具链,位于:
text
toolchain/riscv/Linux/bin/
用 file 命令看一下就明白了:
bash
file toolchain/riscv/Linux/bin/riscv64-unknown-elf-gcc
输出:
text
ELF 64-bit LSB executable, x86-64, ... for GNU/Linux
架构是 x86-64,你的树莓派/Orange Pi 是 aarch64,CPU 指令集都不一样,直接跑不了,所以编译必挂。
💡 总体思路:三件事
既然自带的工具链不能用,思路就是「换一套 ARM 能跑的工具链」,共三步:
| 步骤 |
内容 |
说明 |
| 1 |
安装 Ubuntu 官方的原生 RISC-V 工具链 |
版本正好也是 10.2.0,和 SDK 要求的一致 |
| 2 |
补齐 newlib |
Ubuntu 的 gcc 包不自带 C 库头文件,要从 SDK 自带的工具链里复制过来 |
| 3 |
补齐 multilib 映射 |
SDK 用 rv32imc 编译,但 Ubuntu 工具链的目录结构里没有它,要手动补上 |
下面一步步来。
📦 第一步:克隆项目(含子模块)
工具链是以子模块方式存放的,一定要用 --recursive 克隆,否则 toolchain/ 目录是空的:
bash
git clone --recursive https://gitee.com/Ai-Thinker-Open/Ai-Thinker-WB2.git
国内用户推荐 Gitee 源,速度快。克隆完成后确认工具链目录存在:
bash
ls Ai-Thinker-WB2/toolchain/riscv/Linux/riscv64-unknown-elf/
能看到 include 和 lib 两个目录就对了(后面要用的 newlib 就在这里)。
🔧 第二步:安装原生 RISC-V 工具链
Ubuntu 22.04 官方源里有现成的交叉编译工具链,直接装:
bash
sudo apt install -y gcc-riscv64-unknown-elf binutils-riscv64-unknown-elf
验证版本:
bash
riscv64-unknown-elf-gcc --version
输出:
text
riscv64-unknown-elf-gcc () 10.2.0
版本正好是 10.2.0,和 SDK 自带的一致,兼容性最好。
📁 第三步:补齐 newlib 头文件和库
Ubuntu 的 gcc-riscv64-unknown-elf 是个裸机编译器,不带 C 库头文件和库文件(string.h、stdio.h、libc.a 这些都没有)。所以编译时才会报:
text
fatal error: string.h: No such file or directory
解决办法:SDK 自带的工具链里有完整的 newlib,而且这些头文件/库是给 RISC-V 目标用的,和宿主机架构无关,直接复制过来用:
bash
# 路径换成你的 SDK 实际位置
BUNDLED=/path/to/Ai-Thinker-WB2/toolchain/riscv/Linux/riscv64-unknown-elf
sudo mkdir -p /usr/riscv64-unknown-elf
sudo cp -a $BUNDLED/include/. /usr/riscv64-unknown-elf/include/
sudo cp -a $BUNDLED/lib/. /usr/riscv64-unknown-elf/lib/
验证复制成功:
bash
ls /usr/riscv64-unknown-elf/include/string.h
ls /usr/riscv64-unknown-elf/lib/libc.a
两个文件都在就 OK。
🧩 第四步:补齐 multilib 映射(最坑的一步)
复制完 newlib 后再编译,会报新的错误:
text
/usr/riscv64-unknown-elf/lib/libc.a(lib_a-memcpy.o): ABI is incompatible with that of the selected emulation:
target emulation `elf64-littleriscv' does not match `elf32-littleriscv'
翻译一下:链接器找不到 32 位(RV32)的 libc,回退用了顶层 64 位(RV64)的 libc,导致 ABI 不兼容。
原因分析:
- SDK 编译时用的是
-march=rv32imc -mabi=ilp32(见 make_scripts_riscv/project.mk)
- 但 Ubuntu 工具链的 multilib 列表里没有
rv32imc 这个目录,它会把 rv32imc 映射到 rv32im/ilp32
- 而
rv32im/ilp32 这个目录我们没建,所以链接器跑到顶层用了 RV64 的库
解决办法:用 SDK 自带工具链里对应 ABI 的库,把缺的两个映射目录补上。rv32imc 和 rv32im 只差一个 C(压缩指令)扩展,ABI 完全兼容,可以混用:
bash
B=/path/to/Ai-Thinker-WB2/toolchain/riscv/Linux/riscv64-unknown-elf/lib
# rv32imc -> rv32im
sudo mkdir -p /usr/riscv64-unknown-elf/lib/rv32im/ilp32
sudo cp -a $B/rv32imc/ilp32/. /usr/riscv64-unknown-elf/lib/rv32im/ilp32/
# rv32imfc -> rv32imf(有的项目用浮点 ABI,一并补上)
sudo mkdir -p /usr/riscv64-unknown-elf/lib/rv32imf/ilp32f
sudo cp -a $B/rv32imfc/ilp32f/. /usr/riscv64-unknown-elf/lib/rv32imf/ilp32f/
⚙️ 第五步:修改 toolchain.mk(免参数编译)
每次编译都要手动传一堆参数太麻烦,直接改配置文件一劳永逸。
编辑 make_scripts_riscv/toolchain.mk,把:
make
CONFIG_TOOLPREFIX ?= $(BL60X_SDK_PATH)/toolchain/riscv/$(shell uname |cut -d '_' -f1)/bin/riscv64-unknown-elf-
改成:
make
CONFIG_TOOLPREFIX ?= riscv64-unknown-elf-
CPATH ?= /usr/riscv64-unknown-elf/include
export CPATH
两个配置的作用:
| 配置 |
作用 |
CONFIG_TOOLPREFIX |
改用系统 PATH 里的原生工具链 |
CPATH |
告诉 gcc 去 /usr/riscv64-unknown-elf/include 找 newlib 头文件,export 保证子目录的 make 也能继承 |
✅ 第六步:编译并验证
配置完成后,编译就和其他平台一样简单了:
bash
cd applications/get-started/helloworld
make -j4
编译成功会看到:
text
Building Finish.
产物在 build_out/ 目录下:
text
build_out/helloworld.bin # 可烧录的固件
build_out/helloworld.elf # 调试用
build_out/helloworld.map # 链接映射表
最后验证一下固件确实是 RISC-V 的:
bash
file build_out/helloworld.elf
输出:
text
ELF 32-bit LSB executable, UCB RISC-V, RVC, single-float ABI, version 1 (SYSV), statically linked
看到 32-bit LSB executable, UCB RISC-V 就说明编译完全正确,可以烧录了。
📋 常见报错对照表
| 报错 |
原因 |
解决办法 |
fatal error: string.h: No such file or directory |
newlib 头文件缺失 |
完成第三步,确认 CPATH 已设置 |
ABI is incompatible ... elf64-littleriscv does not match elf32-littleriscv |
multilib 映射缺失,链接到了 RV64 的 libc |
完成第四步 |
bad value ... for -march |
工具链版本过旧 |
确认安装的是 10.2.0 版本 |
riscv64-unknown-elf-gcc: command not found |
工具链没装上 |
确认第二步 apt 安装成功 |
🚀 懒人专用:一键配置脚本
如果不想手动折腾,我把以上所有步骤封装成了一个脚本:setup_arm_toolchain.sh。
bash
# 默认找当前目录下的 Ai-Thinker-WB2
bash setup_arm_toolchain.sh
# 或指定 SDK 路径
bash setup_arm_toolchain.sh /path/to/Ai-Thinker-WB2
脚本会自动完成:
- ✅ 检测架构
- ✅ 安装工具链
- ✅ 复制 newlib
- ✅ 补齐 multilib
- ✅ 修改 toolchain.mk(重复运行也不会改坏,幂等)
需要 sudo 权限,会提示输入密码。
脚本内容如下(保存为 setup_arm_toolchain.sh):
bash
#!/bin/bash
# ARM 平台一键配置 Ai-Thinker-WB2 工具链
set -e
SDK_PATH="${1:-$(pwd)/Ai-Thinker-WB2}"
if [ ! -d "$SDK_PATH/toolchain/riscv/Linux/riscv64-unknown-elf" ]; then
echo "错误: 找不到 SDK 工具链目录,请确认路径是否正确"
echo "当前查找路径: $SDK_PATH/toolchain/riscv/Linux/riscv64-unknown-elf"
exit 1
fi
echo "检测到 SDK 路径: $SDK_PATH"
# 第二步:安装工具链
echo ">>> 安装 RISC-V 工具链..."
sudo apt update
sudo apt install -y gcc-riscv64-unknown-elf binutils-riscv64-unknown-elf
# 第三步:复制 newlib
echo ">>> 复制 newlib 头文件和库..."
BUNDLED="$SDK_PATH/toolchain/riscv/Linux/riscv64-unknown-elf"
sudo mkdir -p /usr/riscv64-unknown-elf
sudo cp -a $BUNDLED/include/. /usr/riscv64-unknown-elf/include/
sudo cp -a $BUNDLED/lib/. /usr/riscv64-unknown-elf/lib/
# 第四步:补齐 multilib
echo ">>> 补齐 multilib 映射..."
B="$BUNDLED/lib"
sudo mkdir -p /usr/riscv64-unknown-elf/lib/rv32im/ilp32
sudo cp -a $B/rv32imc/ilp32/. /usr/riscv64-unknown-elf/lib/rv32im/ilp32/
sudo mkdir -p /usr/riscv64-unknown-elf/lib/rv32imf/ilp32f
sudo cp -a $B/rv32imfc/ilp32f/. /usr/riscv64-unknown-elf/lib/rv32imf/ilp32f/
# 第五步:修改 toolchain.mk
echo ">>> 修改 toolchain.mk..."
TOOLCHAIN_MK="$SDK_PATH/make_scripts_riscv/toolchain.mk"
if [ -f "$TOOLCHAIN_MK" ]; then
sed -i 's|CONFIG_TOOLPREFIX ?= $(BL60X_SDK_PATH)/toolchain/riscv/$(shell uname |cut -d '\''_'\'' -f1)/bin/riscv64-unknown-elf-|CONFIG_TOOLPREFIX ?= riscv64-unknown-elf-|g' "$TOOLCHAIN_MK"
if ! grep -q "^CPATH ?=" "$TOOLCHAIN_MK"; then
echo "CPATH ?= /usr/riscv64-unknown-elf/include" >> "$TOOLCHAIN_MK"
echo "export CPATH" >> "$TOOLCHAIN_MK"
fi
echo "toolchain.mk 已更新"
else
echo "警告: 找不到 toolchain.mk,请手动修改"
fi
echo ""
echo "=========================================="
echo "✅ 配置完成!现在可以正常编译了"
echo "测试命令: cd applications/get-started/helloworld && make -j4"
echo "=========================================="
📝 结语
总结一下 ARM 平台编译 Ai-WB2 的完整链路:
text
装原生工具链(10.2.0) -> 复制 newlib 到 /usr/riscv64-unknown-elf/
-> 补 rv32im / rv32imf 两个 multilib 目录
-> 改 toolchain.mk 指向系统工具链
-> make -j4 收工
核心就一句话:SDK 自带的工具链是 x86 的,换成 Ubuntu 原生的 RISC-V 工具链,再补上 newlib 和 multilib 目录就行了。
如果过程中遇到问题,欢迎在楼下留言交流,我会尽量帮忙排查。
附件:setup_arm_toolchain.zip