硬件:飞凌嵌入式 FCU1501(Rockchip RK3506,ARMv7l 架构) 系统:Buildroot 2024.02,glibc 2.38 自带 Python:3.11.8(但被大幅裁剪,缺少 zlib/ssl/xml 等核心模块)
一、问题背景
飞凌 FCU1501 是一款基于 Rockchip RK3506 的 ARMv7l 开发板,出厂自带 Buildroot 2024.02 系统和 Python 3.11.8。但实际使用中发现,这个 Python 被 Buildroot 裁剪得非常精简,大量核心 C 扩展模块缺失:
root@ok3506:~# python3 --version
Python 3.11.8
root@ok3506:~# python3 -c "import zlib"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'zlib'
root@ok3506:~# python3 -c "import ssl"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'ssl'排查后发现缺失的模块清单如下:
模块 | 状态 | 影响 |
|---|---|---|
| ❌ 缺失 | 无法解压 wheel 包,pip 无法工作 |
| ❌ 缺失 | 无法 HTTPS 连接 PyPI |
| ❌ 缺失 | pip 内部依赖崩溃 |
| ❌ 缺失 | SSL 证书校验失败 |
| ❌ 缺失 | 无法使用 SQLite 数据库 |
| ❌ 缺失 | 部分压缩格式不支持 |
最关键的是——厂家没有提供 Buildroot 源码,无法通过 make menuconfig 重新编译 Python 来开启这些模块。
这就陷入了一个死局:没有编译器(板子上没有 gcc),没有 Buildroot 源码,Python 又缺核心模块。pip 装不上,装上了也跑不起来。
二、失败的尝试
2.1 尝试 ensurepip
Python 自带的 ensurepip 模块可以引导安装 pip,但在这块板子上直接失败了:
root@ok3506:~# python3 -m ensurepip --default-pip
Traceback (most recent call last):
...
zipimport.ZipImportError: can't decompress data; zlib not available原因很明确:Python 编译时没有链接 zlib,无法解压 ensurepip 内置的 wheel 包。
2.2 尝试手动解压 wheel
板子上有 unzip 命令,于是尝试手动解压 ensurepip 内置的 pip wheel:
cd /tmp
unzip -o /usr/lib/python3.11/ensurepip/_bundled/pip-24.0-py3-none-any.whl -d pip_extract
cp -r pip_extract/pip /usr/lib/python3.11/site-packages/文件是放进去了,但运行时直接崩溃:
root@ok3506:~# pip3 --version
Traceback (most recent call last):
...
ImportError: libz.so.1: cannot open shared object filepip 内部依赖 zlib 模块,不是简单放文件就能解决的。
2.3 尝试 zlib stub
甚至尝试写了一个 Python 纯实现的 zlib stub 模块来骗过 pip:
# /usr/lib/python3.11/site-packages/zlib.py
class decompressobj:
def decompress(self, data):
return data # 直接返回原始数据
def decompress(data, wbits=15, bufsize=0):
return datapip --version 确实能跑了,但安装包时立刻报错——因为 wheel 内部的文件是真正用 zlib 压缩过的,假模块解不开。
结论:在裁剪过的 Buildroot Python 上硬装 pip,此路不通。
三、解决方案:借花献佛——使用 Debian 预编译包
3.1 思路
既然板子用的是 glibc 2.38,而 Debian Bookworm 的 armhf 架构(ARM Hard Float)与 ARMv7l 的 ABI 兼容,那 Debian 的 Python 二进制文件应该可以直接在这块板子上运行。
关键验证点:
root@ok3506:~# uname -m
armv7l
root@ok168.1.232:~# strings /lib/libc.so.6 | grep 'GNU C Library'
GNU C Library (glibc) stable release version 2.38.
root@ok3506:~# /lib/ld-linux-armhf.so.3 --version
# armhf 加载器存在,说明支持 hard-float ABI3.2 下载 Debian Python 包
从 Debian 中国镜像下载 3 个 armhf 的 .deb 包:
mkdir -p /tmp/deb && cd /tmp/deb
# 核心三个包
curl -sL -o python3.11-minimal.deb \
'http://ftp.cn.debian.org/debian/pool/main/p/python3.11/python3.11-minimal_3.11.2-6+deb12u7_armhf.deb'
curl -sL -o libpython3.11-minimal.deb \
'http://ftp.cn.debian.org/debian/pool/main/p/python3.11/libpython3.11-minimal_3.11.2-6+deb12u7_armhf.deb'
curl -sL -o libpython3.11-stdlib.deb \
'http://ftp.cn.debian.org/debian/pool/main/p/python3.11/libpython3.11-stdlib_3.11.2-6+deb12u7_armhf.deb'3.3 提取并安装
Buildroot 系统没有 dpkg,但可以用 ar + tar 手动提取 .deb:
mkdir -p /tmp/python3.11_full && cd /tmp/python3.11_full
for deb in /tmp/deb/python3.11-minimal.deb \
/tmp/deb/libpython3.11-minimal.deb \
/tmp/deb/libpython3.11-stdlib.deb; do
ar x "$deb"
xz -d < data.tar.xz | tar xf -
rm -f debian-binary control.tar.xz data.tar.xz
done提取后的目录结构是标准的 usr/bin、usr/lib 等,直接复制到 /opt:
rm -rf /opt/python3.11
mkdir -p /opt/python3.11
cp -a /tmp/python3.11_full/usr/* /opt/python3.11/3.4 创建 wrapper 脚本
为了让新 Python 与原系统 Python 共存,创建一个 wrapper 脚本:
cat > /usr/bin/python3-full << 'EOF'
#!/bin/sh
export PYTHONHOME=/opt/python3.11
export PYTHONPATH=/opt/python3.11/lib/python3.11:/opt/python3.11/lib/python3.11/lib-dynload
export PATH=/opt/python3.11/local/bin:/opt/python3.11/bin:$PATH
exec /opt/python3.11/bin/python3.11 "$@"
EOF
chmod +x /usr/bin/python3-full验证:
root@ok3506:~# python3-full --version
Python 3.11.2
root@ok3506:~# python3-full -c "import zlib, ssl, xml, hashlib, sqlite3; print('All OK')"
All OK所有缺失的模块全部恢复正常!
四、安装 pip
4.1 下载 get-pip.py
curl -sL -o /tmp/get-pip.py https://bootstrap.pypa.io/get-pip.py4.2 安装
python3-full /tmp/get-pip.py \
--no-warn-script-location \
--break-system-packages \
--trusted-host pypi.org \
--trusted-host files.pythonhosted.org安装成功后创建 pip wrapper:
cat > /usr/bin/pip3-full << 'EOF'
#!/bin/sh
export PYTHONHOME=/opt/python3.11
export PYTHONPATH=/opt/python3.11/lib/python3.11:/opt/python3.11/lib/python3.11/lib-dynload
export PATH=/opt/python3.11/local/bin:/opt/python3.11/bin:$PATH
exec /opt/python3.11/bin/python3.11 -m pip "$@"
EOF
chmod +x /usr/bin/pip3-full4.3 修复 SSL 证书
pip 能跑,但访问 PyPI 时 SSL 证书校验会失败(板子没有系统 CA 证书包)。安装 certifi 解决:
pip3-full install certifi然后在 wrapper 脚本中加入证书路径:
export SSL_CERT_FILE=/opt/python3.11/local/lib/python3.11/dist-packages/certifi/cacert.pem4.4 配置 pip
mkdir -p /opt/python3.11/etc
cat > /opt/python3.11/pip.conf << 'EOF'
[global]
trusted-host = pypi.org files.pythonhosted.org
break-system-packages = true
root-user-action = ignore
EOF验证端到端:
root@ok3506:~# pip3-full --version
pip 26.1.2 from /opt/python3.11/local/lib/python3.11/dist-packages/pip (python 3.11)
root@ok3506:~# pip3-full install requests
Successfully installed requests-2.34.2
root@ok3506:~# python3-full -c "import requests; print(requests.get('https://pypi.org').status_code)"
200五、安装 NumPy(可选)
嵌入式开发板上经常需要数值计算,但 PyPI 上没有 armv7l 的预编译 NumPy wheel,源码编译又没有 gcc。解决方案同样是借用 Debian armhf 的预编译包。
5.1 下载并提取
cd /tmp
curl -sLo python3-numpy.deb \
'http://ftp.cn.debian.org/debian/pool/main/n/numpy/python3-numpy_1.24.2-1+deb12u1_armhf.deb'
mkdir -p /tmp/numpy_extract && cd /tmp/numpy_extract
ar x ../python3-numpy.deb
xz -d < data.tar.xz | tar xf -
cp -r usr/lib/python3.11/dist-packages/numpy* \
/opt/python3.11/lib/python3.11/site-packages/5.2 安装依赖库
NumPy 的 .so 文件依赖 BLAS/LAPACK 库,同样从 Debian 下载:
cd /tmp
curl -sLo libblas3.deb \
'http://ftp.cn.debian.org/debian/pool/main/l/lapack/libblas3_3.11.0-2_armhf.deb'
curl -sLo liblapack3.deb \
'http://ftp.cn.debian.org/debian/pool/main/l/lapack/liblapack3_3.11.0-2_armhf.deb'
curl -sLo libgfortran5.deb \
'http://ftp.cn.debian.org/debian/pool/main/g/gcc-12/libgfortran5_12.2.0-14+deb12u1_armhf.deb'
mkdir -p /tmp/lib_extract && cd /tmp/lib_extract
for deb in /tmp/libblas3.deb /tmp/liblapack3.deb /tmp/libgfortran5.deb; do
ar x "$deb"
xz -d < data.tar.xz | tar xf -
rm -f debian-binary control.tar.xz data.tar.xz
done
# 复制 .so 到系统库目录
cp $(find . -name '*.so*') /lib/5.3 更新 PYTHONPATH
wrapper 脚本的 PYTHONPATH 需要包含 site-packages:
export PYTHONPATH=/opt/python3.11/lib/python3.11:/opt/python3.11/lib/python3.11/lib-dynload:/opt/python3.11/lib/python3.11/site-packages:/opt/python3.11/local/lib/python3.11/dist-packages5.4 测试
import numpy as np
import time
# 基本功能
a = np.array([1, 2, 3, 4, 5])
print(f"版本: {np.__version__}")
print(f"数组: {a}")
print(f"均值: {np.mean(a)}")
# 线性代数
m = np.array([[1, 2], [3, 4]])
print(f"行列式: {np.linalg.det(m)}")
print(f"特征值: {np.linalg.eig(m)[0]}")
# FFT
signal = np.array([1, 2, 1, -1, -2, -1])
print(f"FFT: {np.round(np.fft.fft(signal), 2)}")
# 性能
t0 = time.time()
result = np.dot(np.random.rand(1000, 1000), np.random.rand(1000, 1000))
print(f"1000x1000 矩阵乘法: {time.time()-t0:.1f}s")输出:
版本: 1.24.2
数组: [1 2 3 4 5]
均值: 3.0
行列式: -2.0
特征值: [-0.37 5.37]
FFT: [0.+0.j 3.-5.2j 0.+0.j 0.+0.j 0.+0.j 3.+5.2j]
1000x1000 矩阵乘法: 20.1s全部功能正常。1000×1000 矩阵乘法 20 秒,ARMv7l 无 NEON 优化的预期水平。
六、磁盘空间优化
嵌入式开发板存储空间有限(根分区 458M),安装 Python + pip 后空间紧张。以下是实际清理记录:
6.1 清理临时文件
# 安装过程中产生的临时文件
rm -rf /tmp/pip_extract /tmp/setuptools_extract
rm -f /root/get-pip.py
rm -rf /tmp/deb /tmp/deb_extract /tmp/python3.11_full /tmp/numpy_extract /tmp/lib_extract6.2 清理 pip 缓存
rm -rf /root/.cache/pip6.3 删除测试文件
# setuptools 自带的测试目录
rm -rf /opt/python3.11/local/lib/python3.11/dist-packages/setuptools/tests
rm -rf /opt/python3.11/local/lib/python3.11/dist-packages/setuptools/_distutils/tests6.4 清理 .pyc 缓存
Python 运行时会自动生成 .pyc 字节码缓存文件,在嵌入式设备上意义不大:
find /opt/python3.11 -type d -name '__pycache__' -exec rm -rf {} +在 wrapper 脚本中加入环境变量,防止 .pyc 自动重建:
export PYTHONDONTWRITEBYTECODE=16.5 清理效果
已用 | 可用 | 使用率 | |
|---|---|---|---|
清理前 | 435M | 0M | 100% |
清理后 | 296M | 130M | 70% |
共释放 139M 空间。
七、最终环境概览
7.1 完整的 wrapper 脚本
/usr/bin/python3-full:
#!/bin/sh
export PYTHONHOME=/opt/python3.11
export PYTHONPATH=/opt/python3.11/lib/python3.11:/opt/python3.11/lib/python3.11/lib-dynload:/opt/python3.11/lib/python3.11/site-packages:/opt/python3.11/local/lib/python3.11/dist-packages
export SSL_CERT_FILE=/opt/python3.11/local/lib/python3.11/dist-packages/certifi/cacert.pem
export PYTHONDONTWRITEBYTECODE=1
export PATH=/opt/python3.11/local/bin:/opt/python3.11/bin:$PATH
exec /opt/python3.11/bin/python3.11 "$@"/usr/bin/pip3-full:
#!/bin/sh
export PYTHONHOME=/opt/python3.11
export PYTHONPATH=/opt/python3.11/lib/python3.11:/opt/python3.11/lib/python3.11/lib-dynload:/opt/python3.11/lib/python3.11/site-packages:/opt/python3.11/local/lib/python3.11/dist-packages
export SSL_CERT_FILE=/opt/python3.11/local/lib/python3.11/dist-packages/certifi/cacert.pem
export PYTHONDONTWRITEBYTECODE=1
export PATH=/opt/python3.11/local/bin:/opt/python3.11/bin:$PATH
exec /opt/python3.11/bin/python3.11 -m pip "$@"7.2 日常使用
# 查看版本
python3-full --version # Python 3.11.2
pip3-full --version # pip 26.1.2
# 安装第三方包
pip3-full install requests
# 原系统 Python 不受影响
python3 --version # Python 3.11.8 (Buildroot 原始版)7.3 安装其他 Debian 预编译包的通用方法
如果某个包在 PyPI 上没有 armv7l 的 wheel(很常见),可以用同样的方法从 Debian armhf 仓库安装:
下载
.deb文件ar x+xz -d | tar xf提取将 Python 包复制到
/opt/python3.11/lib/python3.11/site-packages/将
.so依赖库复制到/lib/
八、总结
方案 | 可行性 | 说明 |
|---|---|---|
Buildroot 重新编译 | ✅ 最佳 | 需要源码,厂家未提供 |
板上源码编译 | ❌ 不可行 | 板上无 gcc,无 Python dev headers |
ensurepip 引导 | ❌ 不可行 | Python 缺 zlib,无法解压 wheel |
zlib stub 绕过 | ❌ 不可行 | ssl、xml 也缺失,pip 无法正常工作 |
Debian armhf 预编译包 | ✅ 可行 | glibc 兼容,ABI 匹配,完美运行 |
核心原理:飞凌 FCU1501 使用 glibc 2.38,与 Debian Bookworm armhf 的 ABI 完全兼容。通过提取 Debian 预编译的 Python 二进制和标准库,可以在不重新编译的情况下获得完整的 Python 环境。
这套方案的优点:
零编译:不需要 gcc,不需要源码
零冲突:与原系统 Python 隔离运行,互不干扰
完整功能:zlib、ssl、xml、sqlite3 等模块全部可用
pip 可用:可以正常从 PyPI 安装纯 Python 包
局限:
需要联网下载
根分区空间有限(458M),需精打细算
需要编译的包(如 NumPy)需额外从 Debian 仓库获取预编译版本
本文记录了在飞凌 FCU1501 开发板上从零搭建完整 Python 环境的全过程,希望能帮助到同样受困于 Buildroot 裁剪 Python 的嵌入式开发者。如果你有 Buildroot 源码,还是建议通过
make menuconfig开启 Python 的 zlib/ssl/xml 模块重新编译,那才是最干净的方案。
