前言
在上一部分,我们提到了为 EV3 简单安装几个 Python 软件包的方法。下面我们更进一步,演示安装 Python 3.13.3 和 SciPy 软件包的过程。本文中会附上我们打包好的一些软件包,文末还将附上经过这些操作之后可直接烧录的 img 镜像。(由于在不断摸索中完成,成品与下面演示所得并不完全相同,具体修改的部分将另行说明)
实验性质
以下所有操作均不保证能达到预期效果。处理方法粗糙,操作如有错误,敬请读者批评指正。已知目前编译所得 Python 性能较低,原因未知。
仅图一乐
乐高 EV3 性能极低,如 SciPy 等并不能很好地在其上运行,如果一定要尝试,还需要配置 Swap 等才能使其运行。下面所提到的内容,“折腾”的意义远大于实际应用上的意义。更换到更高性能的设备,是更好的解决方案。关键点:由于 Debian 10 早已停止支持,很多新的软件包并不能通过 apt 安装,我们需要编译安装所需软件包。对于 SciPy,编译安装的过程中需要依赖 OpenBLAS,我们需要一并编译安装。
- 现假设已经按照上一部分所说进行了修改。我们以此为基础完成下面的操作。
- 由于容器模拟 CPU 架构会造成很大的性能损失,直接在容器内编译所需程序需要数个小时。因此,我们选择在宿主机(而非容器)交叉编译 Python(和依赖库)、GCC、OpenBLAS。
直接在容器内编译更简单
在模拟架构的容器内编译安装是相对简单的,且通常不会出现各类莫名其妙的问题。本文选择交叉编译,仅出于节省时间的想法,实际上是有不少问题的,比如没有构建tkinter
模块(题外话:真的有人需要在 EV3 上用这个吗?);软件包打包不规范,可能影响系统运行......
一、准备交叉编译工具链
# 安装依赖
sudo apt update
sudo apt install -y gperf bison flex texinfo help2man gawk libtool-bin automake libncurses-dev python3-dev
# 下载 crosstool-NG
wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.27.0.tar.xz
tar xf crosstool-ng-1.27.0.tar.xz
cd crosstool-ng-1.27.0
# 编译安装 crosstool-NG 到 /opt/crosstool-ng
./configure --prefix=/opt/crosstool-ng
make -j$(nproc)
sudo make install
export PATH="/opt/crosstool-ng/bin:$PATH"
# 创建工具链配置
mkdir ~/armv5te-toolchain && cd ~/armv5te-toolchain
ct-ng arm-unknown-linux-gnueabi # 选择近似模板
ct-ng menuconfig # 编辑配置(修改见下方)
修改配置
只需要修改下面的内容,其他配置保持默认,完成后选择 Save 保存。
- Target options:
Emit assembly for CPU
: arm926ej-s- Toolchain options:
Tuple's vendor string
: ev3- Operating System:
Version of linux
: 4.19.324- Binary utilities:
Version of binutils
: 2.40- C-library:
Version of glibc
: 2.28- C compiler:
Version of gcc
: 13.3.0C++
: 启用Fortran
: 启用
完成上面的配置后,开始构建工具链:
ct-ng build -j$(nproc)
参考用时
在网络条件良好的情况下,使用 Ubuntu (WSL 2) 的i7-14650HX
机器耗时 19 分 33 秒。[INFO ] (elapsed: 19:33.15)
[INFO ] Finishing installation (may take a few seconds)...
生成的工具链默认在 ~/x-tools/arm-ev3-linux-gnueabi
。不要忘记将 ~/x-tools/arm-ev3-linux-gnueabi/bin
也加入到 PATH 中。
二、交叉编译
为了得到相对完整可用的 Python,我们需要先交叉编译一些依赖库。为了能最终在容器里继续编译安装软件包,我们还需要交叉编译新版 GCC 编译器。这一过程非常复杂,笔者也没有完全弄清,如有深入见解,欢迎交流讨论。
因此对这个过程,我们利用 AI 写了一些脚本简化我们的工作。这些脚本已在 GitHub 开源。
请移步上方仓库链接查看详细使用方法。简单来说,完成第一步后,只需:
# 克隆仓库
git clone https://github.com/Spams-Tech/ev3-build-scripts
cd ev3-build-scripts
# 添加脚本运行权限并开始构建
chmod +x full.sh
./full.sh -a -o
脚本会自动下载源码并构建所需要的内容,然后打包成 deb 格式。
软件包打包并不规范
help wanted 正如前文所述,由于笔者不熟悉相关知识,此脚本编译、打包软件包的操作非常粗糙且不规范,可能导致一些意想不到的后果。如果您愿意提供帮助,可直接在上方仓库发起 Pull Request。三、安装交叉编译的软件包
上一步打包完成后,所有 deb 包位于 ~/cross-compile/packages
。可用下列命令将所有包复制到容器里:
mkdir ~/ev3-deb-packages
cp ~/cross-compile/packages/*.deb ~/ev3-deb-packages
sudo docker cp ~/ev3-deb-packages 目标容器ID.例如b09c76f149e1:/home/robot
启动到容器:
sudo docker container exec -it 目标容器ID.例如b09c76f149e1 /bin/bash
在容器内安装:
dpkg -i /home/robot/ev3-deb-packages/*.deb
注:安装过程中出现“Python 报错”是正常现象。
四、安装其他软件包(NumPy, SciPy, ...)
在容器里指定编译器:
export CC=arm-ev3-linux-gnueabi-gcc
export CXX=arm-ev3-linux-gnueabi-g++
export FC=arm-ev3-linux-gnueabi-gfortran
提示
如果在安装部分软件包时遇到错误,可尝试改用系统自带的 GCC 8.3.0:
unset CC
unset CXX
unset FC
但在编译安装 NumPy 、SciPy 前需要改回高版本,否则编译无法通过。
先建立一个 Python 3.13 的虚拟环境并激活:
cd /home/robot
python3.13 -m venv venv313
安装 SciPy 等所需软件包:
pip install numpy scipy --verbose # 编译用时长,建议启用 --verbose 参数查看调试信息
获取部分编译好的 wheel 包
在模拟 CPU 架构运行的容器下编译仍然很慢,可直接从这里获取部分我们已编译好的 wheel 包,文件列表附后:cmake-4.0.3-py3-none-linux_armv5tel.whl
contourpy-1.3.2-cp313-cp313-linux_armv5tel.whl
evdev-1.9.2-cp313-cp313-linux_armv5tel.whl
kiwisolver-1.4.8-cp313-cp313-linux_armv5tel.whl
markupsafe-3.0.2-cp313-cp313-linux_armv5tel.whl
matplotlib-3.10.3-cp313-cp313-linux_armv5tel.whl
ninja-1.11.1.4-py3-none-linux_armv5tel.whl
numpy-2.3.1-cp313-cp313-linux_armv5tel.whl
pandas-2.3.0-cp313-cp313-linux_armv5tel.whl
pillow-11.2.1-cp313-cp313-linux_armv5tel.whl
scipy-1.16.0-cp313-cp313-linux_armv5tel.whl
五、打包
打包前,更改虚拟环境所属用户为 robot
,删除容器内 deb 软件包,然后退出容器:
chown -R robot /home/robot/venv313
rm -rf /home/robot/ev3-deb-packages
exit
- 最后就是熟悉的
brickstrap
打包环节了,不过需要注意,经过上述操作,镜像文件大小很可能超过了默认上限3600M
,需要配置环境变量才能正常生成:
# 提交到镜像
sudo docker container commit 此前查询到的容器ID.例如b09c76f149e1 ev3d10new:latest
# 用 brickstrap 工具打包得到可烧录的镜像,注意配置生成 img 文件大小,不能小于实际占用
sudo su
brickstrap create-tar ev3d10new:latest ev3d10new.tar
BRICKSTRAP_IMAGE_FILE_SIZE=5200M brickstrap create-image ev3d10new.tar ev3d10-gcc13-py313-scipy.img
这样,得到的 ev3d10-gcc13-py313-scipy.img
就是我们所需要的可烧录系统镜像。
在本文的最后,给出我们制作的 img 系统镜像。
请校验下载文件信息
文件名ev3d10-gcc13-py313-scipy.7z
MD5 c85121ad1c1398d00055da6560a9d4f9
SHA-1 bdf61974a31ab537a57ab98fd1b084d6d4c6560a
一些细节
- 基于
growflavor/ev3images:ev3dev10imgv02b
制作; - 文件大小设置为
5200M
,需要容量 8GB 及以上的 SD 卡以安装; - 原有 Python 3.11.9 虚拟环境(
/home/robot/venv311
)内额外安装了Flask flask-cors requests evdev
; - 安装了上文第二步编译得到的所有软件包(2025/6/28 - GitHub Release);
虚拟环境
/home/robot/venv313
已安装的包保存在/home/robot/requirements313venv.txt
:blinker==1.9.0 certifi==2025.6.15 charset-normalizer==3.4.2 click==8.2.1 cmake==4.0.3 contourpy==1.3.2 cycler==0.12.1 et_xmlfile==2.0.0 evdev==1.9.2 Flask==3.1.1 flask-cors==6.0.1 fonttools==4.58.4 idna==3.10 itsdangerous==2.2.0 Jinja2==3.1.6 kiwisolver==1.4.8 MarkupSafe==3.0.2 matplotlib==3.10.3 ninja==1.11.1.4 numpy==2.3.1 openpyxl==3.1.5 packaging==25.0 pandas==2.3.0 pillow==11.2.1 plumbum==1.9.0 pyparsing==3.2.3 python-dateutil==2.9.0.post0 python-ev3dev2==2.1.0.post1 pytz==2025.2 requests==2.32.4 rpyc==6.0.2 scipy==1.16.0 six==1.17.0 tzdata==2025.2 urllib3==2.5.0 Werkzeug==3.1.3
本文(https://www.cgtsoft.com/archives/46/)来源于 CGT Software,使用 CC BY-NC-SA 4.0 许可发布。