摘要
项目需要,要在嵌入式板子上移植python,预期需要的第三方库为numpy、pandas和pymodbus及其依赖库。记录踩坑过程。 主机为32位ubuntu 目标板为32位arm板子, 交叉编译工具链为arm-linux-gnueabihf- readelf -h 文件名 查看文件的使用架构
坑
- 嵌入式的第三方库无法使用pip install 安装
- 如果需要使用pip instal的话还需要_ctype和zlib
- numpy需要_ctypes
- pymodbus需要_ssl和zlib
- pandas需要_bz2
- 需要使用主机版pyhon的解释器,才能对目标板python的setup进行解释
准备
python3.7源码:、numpy源码:、pandas源码:、pymodbus源码:、six源码:、serial源码:、opsenssl源码:、bzip2源码:
大致流程
编译主机依赖库,编译主机python,编译目标板python,打包至目标板,编译目标板第三方库 注:所有操作在root账户下进行 sudo -i 进入root
编译依赖库
openssl for _ssl
主机openssl编译
openssl参考 参考上文,设置编译位置为/opt/hostssl
cd 源码路径
export CC=
./configure --prefix=/opt/hostssl
make
make install
mv /usr/bin/openssl /usr/bin/openssl.old //将旧版本的openssl进行备份
ln -s /usr/local/bin/openssl /usr/bin/openssl //将新版本的openssl进行软链接
openssl version
OpenSSL 1.1.1q 5 Jul 2022
如果提示找不到动态库,做如下操作
export LD_LIBRARY_PATH=/opt/hostssl/lib:$LD_LIBRARY_PATH
echo $LD_LIBRARY_PATH
目标板openssl编译
openssl参考 参考上文,编译位置选择:–prefix=/opt/ssl
cd 源码路径
make clean
mkdir /opt/ssl
./config no-asm -shared --prefix=/opt/ssl \
CC=arm-linux-gnueabihf-gcc \
CXX=arm-linux-gnueabihf-g++ \
AR=arm-linux-gnueabihf-ar \
RANLIB=arm-linux-gnueabihf-ranlib
修改makefile文件 搜索 m32 选项并删除,共两处(如是64位系统则是m64) 如不删除则编译时会出现以下错误
error: unrecognized command line option '-m32'
修改完成后
make
make install
libbz2 for _bz2
libbz2的编译
py3.7 for arm 仓库 该仓库中的libbz2.so.1.0.6和libbz2.1.0和_bz2.cpython-37m-arm-linux-gnueabihf.so可以直接使用之后再说这一步
zlib
主机板zlib编译
unzip zlib-master.zip
cd zlib-master
export CC=gcc
./configure
make
make install
目标板zlib编译
mkdir _install
export CC=arm-linux-gnueabihf-gcc //设置交叉编译器
./configure --enable-shared --prefix=/opt/zlib
make
make install
cp -rfp /opt/zlib/* /usr/local/arm-linux/gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf
libffi for _ctypes
可以不看!!本人尝试失败了 py3.7 for arm 仓库 _ctypes.cpython-37m-arm-linux-gnueabihf.so可以直接使用之后再说这一步
主机板_ctypes编译
apt-get install libffi-dev
目标板_ctypes编译
tar -xzvf libffi-3.4.2.tar.gz
cd libffi-3.4.2
mkdir /opt/libffi
export CC=arm-linux-gnueabihf-gcc
./configure CC=arm-linux-gnueabihf-gcc -host=arm-linux-gnueabihf --build=i686-linux-gnu target=arm-linux-gnueabihf --enable-shared --prefix=/opt/libffi
make
make install
cp -rfp /opt/libffi/* /usr/local/arm-linux/gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf
编译主机python
cd python源码包位置
tar -xf Python-3.7.11.tar.xz
cd Python-3.7.11/
vi Modules/Setup.dist
如图取消ssl的注释(这一步如果能成功最好,不成功就把注释加回来) 可能是因为系统本身就带有ssl的库,这一步即使不取消注释,编译出的目标板python也有_ssl库 同理,取消掉关于zlib的注释;
export CC=
./configure
make
make install
测试是否可用
rm /usr/bin/python3
ln -s /usr/local/bin/python3.7 /usr/bin/python3
root@baoyu-ubuntu:
Python 3.7.11
root@baoyu-ubuntu:/home/baoyu/libs/Python-3.7.11
Python 3.7.11 (default, Sep 6 2022, 13:21:16)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> import _ssl
>>>
测试结果python版本为3.7.11,ssl和_ssl可以正常导入
编译目标板python
cd 源码解压位置
make distclean
./configure
make Parser/pgen
mkdir armpy
mkdir /opt/python3
cp -rfp /opt/zlib/* /opt/python3/
cp -rfp /opt/libffi/* /opt/python3/
cp ./Parser/pgen ./armpy/Parser/
touch -t 12312359 ./armpy/Parser/pgen
root@baoyu-ubuntu:/home/baoyu/libs/Python-3.7.11
-rwxr-xr-x 1 root root 294896 12月 31 2022 ./armpy/Parser/pgen*
export CFLAGS="-I/opt/python3/include -I/opt/python3/include/python3.7m -L/opt/python3/lib"
./configure CC=arm-linux-gnueabihf-gcc \
CXX=arm-linux-gnueabihf-g++ \
AR=arm-linux-gnueabihf-ar \
RANLIB=arm-linux-gnueabihf-ranlib \
--host=arm-linux-gnueabihf \
--build=i686-linux-gnu \
--target=arm-linux-gnueabihf \
--disable-ipv6 \
--prefix=/opt/python3 \
--with-ensurepip=yes \
--enable-optimizations \
ac_cv_file__dev_ptmx=yes \
ac_cv_file__dev_ptc=yes
修改Setup和Setup.dist,同上,取消注释指定ssl库的位置, 此外再取消关于zlib部分的注释 编译
make
make install
这时候make到最后可能会提示 failed to build _ctypes,看结果是因为没找到ffi的头文件 解决办法:把这句话加在configure前(亲测无效,仅提供失败案例)
export CFLAGS="-I/opt/python3/include -I/opt/python3/include/python3.7m -L/opt/python3/lib"
再次make的时候就会在这里找头文件 但是!!!还是失败了
移植至目标板
压缩编译好的python
cd /opt
tar zcvf python3.7.tar.gz python3
目标板解压
tar xzvf python3.7.tar.gz
测试
cd python3.7/bin
root@zynq:/media/sdcard/sdtest/python3.7/bin
Python 3.7.11
root@zynq:/media/sdcard/sdtest/python3.7/bin
Python 3.7.11 (default, Sep 6 2022, 13:57:22)
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import _bz2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named '_bz2'
>>> import _ssl
可见_ssl模块可以导入,bz2模块无法使用
目标板python添加_bz2
把libbz2.so.1.0.6和libbz2.so.1.0拷贝到目标板/usr/lib下 把_bz2.cpython-37m-arm-linux-gnueabihf.so拷贝至/media/sdcard/sdtest/python3.7/lib/python3.7/lib-dynload 测试
root@zynq:/media/sdcard/sdtest/python3.7/bin
Python 3.7.11 (default, Sep 6 2022, 13:57:22)
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import bz2
>>> import _bz2
>>>
成功 同理添加_ctypes
编译目标板第三方库
以numpy为例 添加库路径
cd ~
vi .bashrc
export PYTHONPATH=$PYTHONPATH:/opt/python3/lib/python3.7/site-packages
source .bashrc
编译numpy源码
cd 源码解压位置
export CROSS_COMPILE=arm-linux-gnueabihf- \
export CC="${CROSS_COMPILE}gcc" \
export CXX=arm-linux-gnueabihf-g++ \
export LDFLAGS="-L/opt/python3/lib" \
export LDSHARED="${CC} -shared" \
export CFLAGS="-I/opt/python3/include/python3.7m"
python3 setup.py install --prefix=/opt/python3
此时安装会提示缺少module【cython】,使用以下安装cython pip临时换源换源参考文档
pip install *** -i https://pypi.tuna.tsinghua.edu.cn/simple
python3 -m pip install cython -i https://pypi.tuna.tsinghua.edu.cn/simple
cyhton安装完成后,再次运行setup.py
python3 setup.py install --prefix=/opt/python3
可以看到一个numpy-1.8.2-py3.7-linux-i686.egg文件,同时还有easy-install.pth文件,将这两个文件拷贝至目标板python的site-packages即可使用。
附录
如果需要pip和setuptool的话,直接将主机/usr/local/lib/python3/site-packages下的pip和setuptool拷贝过去即可 测试:
root@zynq:/media/sdcard/sdtest
Python 3.7.11 (default, Sep 6 2022, 19:53:25)
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import zlib
>>> import _bz2
>>> import _ctypes
>>> import numpy
>>> import _ssl
>>> import pymodbus
>>>
root@zynq:/media/sdcard/sdtest
Package Version
---------- -------
numpy 1.18.2
pip 20.1.1
pymodbus 2.5.3
pyserial 3.4
setuptools 47.1.0
six 1.16.0
|