赞
踩
由于需要将Python3.7 和一些软件包交叉编译到 armv7 平台硬件,如果是arm64位的系统,很多包都有预编译好的版本,可直接下载。本文主要在基于 crossenv(https://github.com/benfogle/crossenv)
环境下交叉编译。
/home/ym/python-build
,创建 /home/ym/python-build/install
路径用于安装主机编译后的python, 创建路径/home/ym/python-build/install-arm
用于安装交叉编译的python。home/ym/python-build
, 并解压,下载路径https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tar.xz
Debian -> apt, Redhat -> yum
,我安装的版本是FROM ubuntu:18.04 ENV TZ=Asia/Shanghai ENV LANG=en_US.UTF-8 RUN 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 proxychains 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-gnueabihf RUN rm -rf /etc/apt/apt.conf.d/docker-clean RUN mkdir -p /root/project WORKDIR /root CMD ["/bin/bash"]
docker build -f Dockerfile -t ubuntu:python .
python-build
映射至容器路径/root/project
路径下:docker run -v /home/ym/python-build/:/root/project -it ubuntu:python
./configure --prefix=/root/project/install && make && make install
# Adapted from https://github.com/japaric/cross set -ex INSTALL_DIR=/root/project/openssl mkdir -p $INSTALL_DIR main() { local version=1.1.1l local os=linux-armv4 local triple=arm-linux-gnueabihf- local sysroot=$INSTALL_DIR local dependencies=( ca-certificates curl m4 make perl ) # NOTE cross toolchain must be already installed apt-get update for dep in ${dependencies[@]}; do if ! dpkg -L $dep; then apt-get install --no-install-recommends -y $dep fi done td=$(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.gz AR=${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 up popd rm -rf $td #rm $0 #cp /usr/local/arm/usr/lib/pkgconfig/* /usr/share/pkgconfig/ } main "${@}"
https://xz.tukaani.org/xz-utils/#releases
cp -rfp libffi/* /usr/arm-linux-gnueabihf/
),并在 Python 配置选项中指定--with-system-ffi
参数,交叉编译时 Python 自动构建 ctypes 模块,测试发现通过 LIBS 变量指定不会生效。ac_cv_file__dev_ptc=no
ac_cv_buggy_getaddrinfo=no
ac_cv_file__dev_ptmx=no
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.site cd 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 查看是否正常:
1. 在主机环境下安装 crossenv cd /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. 编译安装 numpy build-pip -v install numpy pip -v install numpy 5. 编译安装 pandas build-pip -v install pandas pip -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
的路径下。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.22
cd OpenBLAS-0.3.22 && make TARGET=ARMV7 HOSTCC=gcc BINARY=32 CC=arm-linux-gnueabihf-gcc FC=arm-linux-gnueabihf-gfortran
make TARGET=ARMV7 PREFIX=/root/project/openblas install
#!/bin/bash #################### # Script to build numpy and scipy wheels for ARM. set -ex OUTPUT=$PWD/output WORKING=$OUTPUT/build if [ ! -d "$WORKING" ];then mkdir -p $WORKING fi GFORTRAN=arm-linux-gnueabihf-gfortran OPENBLAS_INSTALL_DIR=$PWD/openblas BUILD_PYTHON=$PWD/install/bin/python3 HOST_PYTHON=$PWD/install-arm/bin/python3 NUMPY_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* ]];then NUMPY_DIR=${NUMPY_VERSION%%.zip*} elif [[ $NUMPY_VERSION =~ .tar.gz* ]];then NUMPY_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_MIRROR BUILD_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" ];then curl -OL $NUMPY_URL fi if [ ! -d "$NUMPY_DIR" ];then if [[ $NUMPY_VERSION =~ .zip* ]];then unzip $NUMPY_VERSION elif [[ $NUMPY_VERSION =~ .tar.gz* ]];then tar xf $NUMPY_VERSION fi 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" ];then curl -OL $SCIPY_URL fi if [ ! -d "$SCIPY_DIR" ];then tar 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 EOF F90=$GFORTRAN python setup.py bdist_wheel F90=$GFORTRAN cross-python setup.py install cd ..
build-pip install -v scipy=1.3.3 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
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
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
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
至此交叉编译全部完成,将对应的包拷贝到目标板查看
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。