Python3 交叉编译 numpy pandas scipy scikit-learn

1. 概述

由于需要将Python3.7 和一些软件包交叉编译到 armv7 平台硬件,如果是arm64位的系统,很多包都有预编译好的版本,可直接下载。本文主要在基于 crossenv(https://github.com/benfogle/crossenv)环境下交叉编译。

2. 编译环境搭建

  • 创建编译环境路径 /home/ym/python-build,创建 /home/ym/python-build/install路径用于安装主机编译后的python, 创建路径/home/ym/python-build/install-arm用于安装交叉编译的python。
  • 下载python3 源码到 home/ym/python-build, 并解压,下载路径https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tar.xz
  • 编译主机安装 Docker 环境,不同的linux发行版本安装方式不同, Debian -> apt, Redhat -> yum,我安装的版本是
    在这里插入图片描述
  • 在编译路径下创建一个 Dockerfile 文件:
FROM ubuntu:18.04                                                                                                          
ENV TZ=Asia/Shanghai
ENV LANG=en_US.UTF-8RUN sed -i -e 's|archive.ubuntu.com|mirrors.tuna.tsinghua.edu.cn|g' \               -e 's|security.ubuntu.com|mirrors.tuna.tsinghua.edu.cn|g' \                    /etc/apt/sources.list            RUN apt update && apt install -y vim curl proxchains gcc \                           build-essential crossbuild-essential-armhf \              libsdl1.2-dev xterm mesa-common-dev zstd liblz4-tool libffi-dev \  cmake libssl-dev bc device-tree-compiler flex bison libncurses-dev \lzma liblzma-dev libbz2-dev gfortran libopenblas-dev liblapack-dev \gfortran-arm-linux-gnueabihfRUN rm -rf /etc/apt/apt.conf.d/docker-clean RUN mkdir -p /root/project                
WORKDIR /root   
CMD ["/bin/bash"]  
  • 基于 Dockerfile 构建容器
docker build -f Dockerfile -t ubuntu:python .
  • 运行容器,将编译路径python-build映射至容器路径/root/project路径下:
docker run -v /home/ym/python-build/:/root/project -it ubuntu:python

3. 编译主机版本 python

  • 进入python源码目录
./configure --prefix=/root/project/install && make && make install

4. 交叉编译目标板 python

  • 交叉编译 openssl
# Adapted from https://github.com/japaric/cross
set -exINSTALL_DIR=/root/project/openssl
mkdir -p $INSTALL_DIR
main() {local version=1.1.1llocal os=linux-armv4local triple=arm-linux-gnueabihf-local sysroot=$INSTALL_DIRlocal dependencies=(ca-certificatescurlm4makeperl)# NOTE cross toolchain must be already installedapt-get updatefor dep in ${dependencies[@]}; doif ! dpkg -L $dep; thenapt-get install --no-install-recommends -y $depfidonetd=$(mktemp -d)pushd $td[ -e ./openssl-$version.tar.gz ] || {curl -L https://www.openssl.org/source/openssl-$version.tar.gz -o ./openssl-$version.tar.gz}tar --strip-components 1 -xz -f ./openssl-$version.tar.gzAR=${triple}ar CC=${triple}gcc ./Configure \--prefix=${sysroot}/usr \--openssldir=${sysroot}/usr \shared \no-asm \$os \-fPIC \${@:4}make -j$(nproc)make install_sw# clean uppopdrm -rf $td#rm $0#cp /usr/local/arm/usr/lib/pkgconfig/* /usr/share/pkgconfig/}main "${@}"
  • 交叉编译 bzip2, zlib, lzma 这些包会被python内建模块识别调用,并被 pandas 所依赖,同时需要把 zlib, lzma的动态库拷贝到目标板内核库的路径下。
  • lzma 下载地址https://xz.tukaani.org/xz-utils/#releases
  • 交叉编译libffi, 该包与 python ctypes 模块关联,注意交叉编译完成后需要将安装后的内容拷贝到交叉工具链的路径下(cp -rfp libffi/* /usr/arm-linux-gnueabihf/),并在 Python 配置选项中指定--with-system-ffi参数,交叉编译时 Python 自动构建 ctypes 模块,测试发现通过 LIBS 变量指定不会生效。
  • 创建一个 config.site 文件:
ac_cv_file__dev_ptc=no
ac_cv_buggy_getaddrinfo=no
ac_cv_file__dev_ptmx=no
  • 清除 python 源码相关环境(make distclean),运行下面脚本交叉编译目标版本 python-target(armv7),安装到路径/root/project/install-arm
#!/bin/sh
CROSS_COMPILE=arm-linux-gnueabihf
export CC=$CROSS_COMPILE-gcc
export CXX=$CROSS_COMPILE-g++
export AR=$CROSS_COMPILE-ar
export STRIP=$CROSS_COMPILE-strip
export LD=$CROSS_COMPILE-ld
export RANLIB=$CROSS_COMPILE-ranlib
export READELF=$CROSS_COMPILE-readelf
export PATH=$PATH:/root/project/install/bin
export CONFIG_SITE=/root/project/config.sitecd Python-3.7.2 && ./configure --enable-optimizations --with-openssl=/root/project/openssl/usr --with-system-ffi \LDFLAGS="-L/root/project/bzip2-1.0.8 -L/root/project/zlib/lib -L/root/project/lzma/lib" \LIBS="-lbz2 -lz -llzma" \--host=arm-linux-gnueabihf \--build=x86_64-linux-gnu \--target=arm-linux-gnueabihf \--disable-ipv6 \--without-pydebug \--without-dtrace \--prefix=/root/project/install-arm
make -j4 && make install

到此如果编译过程中没有出错的话,交叉编译后的 python 应该可以直接在 目标板上工作了,在目标板上创建一个 python 目录,将 install-arm 中的文件全部拷贝至该路径中,构建一个软连接 ln -sf /python/bin/python3.7 /usr/bin/python,然后在控制运行 python 查看是否正常:
在这里插入图片描述

5. 通过 crossenv 交叉编译 numpy,pandas

  • 如果只是想交叉编译 numpy 或者 pandas, 看到这一小节就行了,其中pandas 依赖 numpy。如果还要编译其他包请用第六节脚本编译的方法交叉编译 numpy.
1. 在主机环境下安装 crossenvcd  /root/project/install/bin./pip3 install crossenv
2. 使用crossenv创建 python-target 编译的虚拟环境./python3 -m crossenv /root/project/install-arm/bin/python3.7 cross_venv
3. 激活虚拟环境. cross_venv/bin/activate
注意没有代理可使用国内镜像如 pip install xx -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
4. 编译安装 numpybuild-pip -v install numpypip -v install numpy
5. 编译安装 pandasbuild-pip -v install pandaspip -v install pandas
注意pandas 依赖 dateutil,dateutil会使用目标板的时区信息,请检查目标板是否有 /usr/share/zoneinfo 和 /etc/localtime 文件,没有可能在导入 pandas 包时会报错,可将交叉编译后的 dateutil/zoneinfo/dateutil-zoneinfo.tar.gz 解压至 /usr/share/zoneinfo中,并创建软连接 ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime编译成功后可在 cross_venv/cross/lib/pythonVERSION/site-packages 路径下查看编译完后的包其中包主要分两类:1). package -> 对应包的实际文件2). package-VERSION-dist-info -> 包的信息 
6. 将对应的 package 拷贝到目标板 path/to/python/lib/pythonVERSION/site-package 路径下

在这里插入图片描述

  • 这里导入包的时候,可能会报一些库文件缺失,需要把对应的库拷贝到目标板库/lib的路径下。

6. 通过 crossenv 交叉编译 scikit-learn

  • 这里先列一下依赖项
  • scikit-learn:
    • NumPy
    • SciPy :
      • NumPy
      • openblas
    • joblib
    • threadpoolctl
  • 由于 SciPy 强依赖 numpy 中 openblas 包,openblas 是一个数学运算库,可用于加速 numpy 运算,如果只是单纯编译 numpy,那么 openblas 是一个可选项,但是如果需要编译 SciPy,openblas 就是一个强依赖项了,但是 openblas 是由 Fortran 语言编写,直接用 crossenv 环境编译会报错,下面用一个脚本来交叉编译 numpy 和 SciPy,编译之前,先用交叉工具链编译 openblas,并在虚拟环境中 build-pip/pip安装 Cython < 3 版本:
1. 确认以下几个包已安装apt-get install gfortran libopenblas-dev liblapack-dev -y
2. 安装 fortran 交叉编译工具apt-get install gfortran-arm-linux-gnueabihf
3. 交叉编译 OpenBLAS-0.3.22cd OpenBLAS-0.3.22 && make TARGET=ARMV7 HOSTCC=gcc BINARY=32 CC=arm-linux-gnueabihf-gcc FC=arm-linux-gnueabihf-gfortranmake TARGET=ARMV7 PREFIX=/root/project/openblas install
  • 交叉编译 scipy 脚本
#!/bin/bash####################
# Script to build numpy and scipy wheels for ARM. set -exOUTPUT=$PWD/output
WORKING=$OUTPUT/build
if [ ! -d "$WORKING" ];thenmkdir -p $WORKING
fiGFORTRAN=arm-linux-gnueabihf-gfortran
OPENBLAS_INSTALL_DIR=$PWD/openblasBUILD_PYTHON=$PWD/install/bin/python3
HOST_PYTHON=$PWD/install-arm/bin/python3NUMPY_URL=https://files.pythonhosted.org/packages/45/b7/de7b8e67f2232c26af57c205aaad29fe17754f793404f59c8a730c7a191a/numpy-1.21.6.zip
SCIPY_URL=https://files.pythonhosted.org/packages/a7/5c/495190b8c7cc71977c3d3fafe788d99d43eeb4740ac56856095df6a23fbd/scipy-1.3.3.tar.gz
NUMPY_VERSION=${NUMPY_URL##*/}
if [[ $NUMPY_VERSION =~ .zip* ]];thenNUMPY_DIR=${NUMPY_VERSION%%.zip*}
elif [[ $NUMPY_VERSION =~ .tar.gz* ]];thenNUMPY_DIR=${NUMPY_VERSION%%.tar.gz*}
fi
SCIPY_VERSION=${SCIPY_URL##*/}
SCIPY_DIR=${SCIPY_VERSION%%.tar.gz*}PYPI_MIRROR="-i http://pypi.douban.com/simple --trusted-host pypi.douban.com"
################################################################
# Set up crossenv
$BUILD_PYTHON -m pip install crossenv
CROSS_VENV=$PWD/install/bin/cross_venv
if [ ! -d "$CROSS_VENV" ];then$BUILD_PYTHON -m crossenv $HOST_PYTHON $CROSS_VENV
fi
. $CROSS_VENV/bin/activate
pip install wheel $PYPI_MIRRORBUILD_SITE=$PWD/install/bin/cross_venv/build/lib/python3.7/site-packages
CROSS_SITE=$PWD/install/bin/cross_venv/cross/lib/python3.7/site-packages################################################################
# Host-numpy
# Install so we get the libnpymath.a in the right place.
if [ ! -f "$NUMPY_VERSION" ];thencurl -OL $NUMPY_URL
fi
if [ ! -d "$NUMPY_DIR" ];thenif [[ $NUMPY_VERSION =~ .zip* ]];thenunzip $NUMPY_VERSIONelif [[ $NUMPY_VERSION =~ .tar.gz* ]];then tar xf $NUMPY_VERSIONfi
fi
cd $NUMPY_DIR
cat > site.cfg <<EOF
[openblas]
libraries = openblas
library_dirs = $OPENBLAS_INSTALL_DIR/lib
include_dirs = $OPENBLAS_INSTALL_DIR/include
extra_link_args = -lgfortran
EOF
F90=$GFORTRAN cross-python setup.py install
F90=$GFORTRAN cross-python setup.py bdist_wheel
cd ..################################################################
# Build-numpy. Need to patch _after_ install.
NUMPY_PIP_VERSION=${NUMPY_DIR##*-}
build-pip install -v numpy==$NUMPY_PIP_VERSION $PYPI_MIRROR
INI=$(find $BUILD_SITE -name 'npymath.ini')
LIBDIR=$(find $CROSS_SITE -path '*/numpy/core/lib')
INCDIR=$(find $CROSS_SITE -path '*/numpy/core/include')cat > $INI <<EOF
[meta]
Name=npymath
Description=Portable, core math library implementing C99 standard
Version=0.1[variables]
# Force it to find cross-build libs when we build scipy
libdir=$LIBDIR
includedir=$INCDIR[default]
Libs=-L\${libdir} -lnpymath
Cflags=-I\${includedir}
Requires=mlib[msvc]
Libs=/LIBPATH:\${libdir} npymath.lib
Cflags=/INCLUDE:\${includedir}
Requires=mlib
EOF#################################################################
# host-scipy
if [ ! -f "$SCIPY_VERSION" ];thencurl -OL $SCIPY_URL
fi
if [ ! -d "$SCIPY_DIR" ];thentar xf $SCIPY_VERSION
fi
cd $SCIPY_DIR
cat > site.cfg <<EOF
[openblas]
libraries = openblas
library_dirs = $OPENBLAS_INSTALL_DIR/lib
include_dirs = $OPENBLAS_INSTALL_DIR/include
extra_link_args = -lgfortran
EOFF90=$GFORTRAN python setup.py bdist_wheel
F90=$GFORTRAN cross-python setup.py install
cd ..
  • 交叉编译 scikit-learn: :
  • SciPy -> 先前利用脚本已经完成了交叉编译,现在使用 build-pip 安装 build 版本:
build-pip install -v scipy=1.3.3 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
  • joblib -> build-pip/pip 直接安装没有其他依赖
build-pip install joblib==0.11 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install joblib==0.11 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
  • threadpoolctl -> build-pip/pip 直接安装没有其他依赖
build-pip install threadpoolctl==2.0.0 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install threadpoolctl==2.0.0 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
  • 安装 scikit-learn:
build-pip install -v scikit-learn==1.0.2 --no-build-isolation -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install -v scikit-learn==1.0.2 --no-build-isolation -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

至此交叉编译全部完成,将对应的包拷贝到目标板查看
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/253960.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时光峰峦文物璀璨,预防性保护筑安全

在璀璨的历史长河中&#xff0c;珍贵文物如同时间的印记&#xff0c;承载着过往的辉煌。《人文山水时光峰峦——多彩贵州历史文化展》便是这样一场文化的盛宴&#xff0c;汇聚了众多首次露面的宝藏。然而&#xff0c;文物的保存对环境要求极为苛刻&#xff0c;温湿度波动都可能…

nodeJS 的 npm 设置国内高速镜像之淘宝镜像的方法

1、我们知道 nodeJS 是老外搞出来的&#xff0c;服务器放在了国外&#xff0c;国内的小朋友访问起来会比较慢&#xff0c;阿里巴巴的淘宝给出了有力支持&#xff0c;现在我们就将 nodeJS 的镜像地址切换为国内的淘宝镜像。 2、查看当前的镜像地址&#xff1a; npm get registr…

尚硅谷Ajax笔记

一天拿下 介绍二级目录三级目录 b站链接 介绍 ajax优缺点 http node.js下载配置好环境 express框架 切换到项目文件夹&#xff0c;执行下面两条命令 有报错,退出用管理员身份打开 或者再命令提示符用管理员身份打开 npm init --yes npm i express请求 <script>//引…

单片机无线发射的原理剖析

目录 一、EV1527编码格式 二、OOK&ASK的简单了解 三、433MHZ 四、单片机的地址ID 五、基于STC15W104单片机实现无线通信 无线发射主要运用到了三个知识点&#xff1a;EV1527格式&#xff1b;OOk&#xff1b;433MHZ。下面我们来分别阐述&#xff1a; EV1527是数据的编…

前端开发中不同语言【react-i18next】

目录 查看并设置语言 单页面&#xff1a;html lang ​编辑 浏览器 自定义翻译 原理/实现 react-i18next【hook只能在函数组件中】 设置 模块&#xff1a;staticData.ts 散(重复利用)&#xff1a;命名空间.json 应用 准备 html标签 查看并设置语言 单页面&#x…

网神 SecGate 3600 防火墙 route_ispinfo_import_save 文件上传漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

Excel——有效性、二级菜单联动

一、录入规范数据 1.手动输入序列录入有效性信息 选择需要录入有效性的所有单元格 选择【数据】——【有效性】——【有效性】 在【允许】输入的值之间选择【序列】 在【序列】输入框中输入想要选择的值&#xff0c;中间用逗号&#xff08;必须是英文逗号&#xff09;隔开 。…

同步和异步、阻塞与非阻塞

一、同步和异步的概念 首先同步和异步是访问数据的机制 同步&#xff1a;同步一般指主动请求并等待IO操作完成的方式异步&#xff1a;主动请求数据后便可以继续处理其它任务&#xff0c;随后等待IO操作完毕的通知 两者的区别&#xff1a;同步会一行一行执行代码&#xff0c;而…

Multisim14.0仿真(五十五)汽车转向灯设计

一、功能描述&#xff1a; 左转向&#xff1a;左侧指示灯循环依次闪亮&#xff1b; 右转向&#xff1a;右侧指示灯循环依次闪亮&#xff1b; 刹车&#xff1a; 所有灯常亮&#xff1b; 正常&#xff1a; 所有灯熄灭。 二、主要芯片&#xff1a; 74LS161D 74LS04D 74…

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式 基础(持续更新~)

具体操作&#xff1a; day2: 作用&#xff1a; 出现跨域问题 配相对应进行配置即可解决&#xff1a; IDEA连接的&#xff0c;在url最后加参数?useSSLfalse注意链接密码是123&#xff08;docker中mysql密码&#xff09; 注意&#xff0c;虚拟机中设置的密码和ip要和主机上…

GO语言集成开发 JetBrains GoLand 2023 中文

JetBrains GoLand 2023是一款专为Go语言开发者打造的集成开发环境&#xff08;IDE&#xff09;。它基于IntelliJ IDEA平台&#xff0c;提供了丰富的功能和工具&#xff0c;旨在提高开发效率和质量。GoLand 2023具备强大的Go语言支持&#xff0c;包括语法高亮、自动补全、代码提…

手把手教你设计接口自动化测试用例:提取接口信息并分析

随着市场需求的变化&#xff0c;大部分企业在招聘测试人员时&#xff0c;都会提出接口自动化测试的相关要求&#xff0c;为什么会这样呢&#xff1f; 目前&#xff0c;软件构架基本上都是前后端分离的&#xff0c;软件的主要功能由服务端提供。从整个软件测试市场来看&#xf…

【实训】网络系统集成课程实训(vlan、vrrp、nat)

目录 一 实训概述 1.1 实训目的 1.2 实训内容 二 实训原理 2.1 VLAN间划分及VLAN间通信 2.2 BGP&#xff0c;边界网关协议 BGP是运行于 TCP 上的一种自治系统的路由协议&#xff0c;用于在AS之间实现路由信息的交互。 2.2.1 VRRP原理 2.2.2 OSPF配置 三&#xff0e;实训…

Spring Boot + flowable 快速实现工作流

背景 使用flowable自带的flowable-ui制作流程图 使用springboot开发流程使用的接口完成流程的业务功能 文章来源&#xff1a;https://blog.csdn.net/zhan107876/article/details/120815560 一、flowable-ui部署运行 flowable-6.6.0 运行 官方demo 参考文档&#xff1a; htt…

C++ 调用lua 脚本

需求&#xff1a; 使用Qt/C 调用 lua 脚本 扩展原有功能。 步骤&#xff1a; 1&#xff0c;工程中引入 头文件&#xff0c;库文件。lua二进制下载地址&#xff08;Lua Binaries&#xff09; 2&#xff0c; 调用脚本内函数。 这里调用lua 脚本中的process函数&#xff0c;并…

安装Pytorch中的torchtext之CUDA版的正确方式

安装Pytorch和torchtext&#xff1a; Previous PyTorch Versions | PyTorch Installing previous versions of PyTorchhttps://pytorch.org/get-started/previous-versions/ 上面的命令如下&#xff1a; pip install torch2.1.2 torchvision0.16.2 torchaudio2.1.2 --index-…

小白都能看懂的力扣算法详解——链表(一)

&#xff01;&#xff01;本篇所选题目及解题思路均来自代码随想录 (programmercarl.com) 一 203.移除链表元素 题目要求&#xff1a;给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回新的头节点。 203.…

数据库管理-第145期 最强Oracle监控EMCC深入使用-02(20240205)

数据库管理145期 2024-02-05 数据库管理-第145期 最强Oracle监控EMCC深入使用-02&#xff08;20240205&#xff09;1 监控方式2 度量配置3 阻塞4 DG监控总结 数据库管理-第145期 最强Oracle监控EMCC深入使用-02&#xff08;20240205&#xff09; 作者&#xff1a;胖头鱼的鱼缸&…

Java后端技术助力,党员学习平台更稳定

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Text Mesh Pro图文混排如何对任何图片都能实现

1&#xff09;Text Mesh Pro图文混排如何对任何图片都能实现 2&#xff09;Unity iOS平台的小图占用特别大的内存 3&#xff09;只在编辑器内&#xff0c;纹理不开启Read&Write情况下&#xff0c;如何获取纹理所有颜色值 4&#xff09;准备在海外发行游戏&#xff0c;有哪些…