ホームページ  >  記事  >  バックエンド開発  >  Pythonにおけるサードパーティライブラリのクロスコンパイルの問題について

Pythonにおけるサードパーティライブラリのクロスコンパイルの問題について

WBOY
WBOY転載
2022-10-05 08:00:274167ブラウズ

この記事では、Python に関する関連知識を提供します。主にサードパーティ ライブラリのクロスコンパイルに関する問題を紹介します。クロスコンパイルとは、あるプラットフォーム上で別のプラットフォーム上で実行可能コードを生成することを指します。以下を見てみましょう。皆さんのお役に立てば幸いです。

Pythonにおけるサードパーティライブラリのクロスコンパイルの問題について

[関連する推奨事項: Python3 ビデオ チュートリアル ]

1. 序文:

Python に関するクロスオーバーインターネットコンパイルに関する記事は多いですが、Pythonのサードライブラリのクロスコンパイルに関する記事は比較的少なく、サードパーティライブラリのクロスコンパイルに関するタイトルが多いですが、実際にはクロスなしで使えるライブラリばかりです-compilation. 参照が強くありません。最近、Python とそのサードパーティ ライブラリのクロスコンパイルに落とし穴がたくさんあります。記録しましょう。

2. クロスコンパイルの概要:

1. クロスコンパイルとは: あるプラットフォーム上で別のプラットフォーム上で実行可能コードを生成します。

2. クロスコンパイルを行う理由: 組み込みシステムを開発する場合、プログラムが実行されるターゲット プラットフォームには通常、ストレージ スペースとコンピューティング能力が限られています。たとえば、一般的な ARM プラットフォームの静的ストレージ スペースは比較的小さいです。 . 小さく、CPU の演算能力が弱い。この場合、ARM プラットフォーム上でのネイティブ コンパイルは不可能となるため、この問題を解決するためにクロスコンパイル ツールが登場しました。クロスコンパイル ツールを使用すると、強力な CPU 機能と十分なストレージ制御 (PC など) を備えたホスト プラットフォーム上で、他のプラットフォーム用の実行可能プログラムをコンパイルできます。

3. Python とそのサードパーティ ライブラリのクロスコンパイルの背景

1. クロスコンパイル チェーン: rv1126-arm-buildroot-linux-gnueabihf-toolchain.tar.bz2

2. ターゲットボード (ターゲットホスト): armv7l

3. クロス編集用ホスト (ビルドホスト): ubuntu18-x86_64

4. Python バージョン: 3.5.2

5. numpy==1.18.5

4. クロスコンパイルの準備

ビルドホストは新しくインストールしたubuntu18の仮想マシンなので、 gcc

1. gcc をインストールします: sudo apt-get install gcc-8 -y

2. gcc-8 をデフォルトの gcc として指定します: sudo ln -s /usr/bin /gcc-8 /usr/bin/gcc

3. cmake をインストールします: sudo apt-get install make cmake -y

4. libffi- をインストールします。 Python をクロスコンパイルするための dev 必要な依存関係: sudo apt-get install libffi-dev

5. zip をインストールし、次のコマンドを使用して圧縮パッケージを解凍します: sudo apt-get install zip -y

5. Python とそのサードパーティのクロスコンパイル アイデア

1. ビルド ホスト上の zlib ライブラリをクロスコンパイルします。これは、Python ソース コードのインストールに必要な依存ライブラリです。

2. クロスコンパイルビルド ホスト上の openssl ライブラリ. これはソース コードのインストールではありませんが、必要な依存ライブラリですが、他のほとんどのライブラリはこのライブラリを使用する可能性があります

3. ビルド ホストに Python バージョンをインストールします。 python-build

になります。 4. ビルド ホスト上のターゲット ホスト上の Python バージョンをクロスコンパイルします。これを python-target

と呼びます。 5. target-python 実行仮想環境を構築します。ビルド ホスト上の Crossenv 経由

# 6. Crossenv 仮想環境で、pip を使用して、クロスコンパイルされたサードパーティ ライブラリを .whl 形式にパッケージ化します。

6. クロスコンパイルの準備ツール

1. クロスコンパイル チェーンを解凍します: さまざまなプラットフォームの使用方法を説明します。 クロスコンパイル チェーンは異なりますが、考え方と手順は同じです。

tar jxvf rv1126-arm-buildroot-linux-gnueabihf-toolchain.tar.bz2

解凍すると、host という名前のフォルダーが作成されます。

2. ホスト ディレクトリを入力します: cd host

3. relocate-sdk.sh コマンドを実行します: ./relocate-sdk.sh ( allcross この手順はコンパイル チェーンに必要です)

4. クロスコンパイル チェーンを環境変数に追加します: vim /etc/profile

5. 最後に追加します:export PATH =$PATH:/home /host/bin 内のパスは、実際のパスに応じて変更できます。

## 6. 環境変数をリロードします:source /etc/profile

7. テスト: arm-buildroot-linux-gnueabihf-gcc -v

7. openssl-build

の準備 ここでは openssl-1.0.2g.tar.gz の圧縮パッケージを準備しました。ここでは openssl-1.1.1 を試しました。バージョンは Python3.5.2 には適しておらず、常に問題が発生するため、ここでは openssl-1.0.2 バージョンを使用します

1. ソース コード パッケージを解凍します。これらのソース コード パッケージはすべてあります。 /home パス: tar -xzvf openssl-1.0.2g.tar.gz

  2、对压缩包进行重命名,区分是在build主机上用的还是在target主机上用的,在build主机上用的我都统一在后面加上_build,在target主机上使用的统一在后面加上_target

mv openssl-1.0.2g openssl-1.0.2g-build

  3、cd openssl-1.0.2g-build

  4、设置编译环境:./config --prefix=/home/openssl-1.0.2g-build/openssl-build

    其中: --prefix是指定编译后的安装的路径

  5、执行编译安装:make && make install 此时在/home/openssl-1.0.2g-build里面就会有openssl-build文件夹  

  6、因为安装的ubuntu18中默认的openssl是1.1.1,我们需要换成我们的openssl-1.0.2g

    把以前的备份:sudo mv /usr/bin/openssl /usr/bin/openssl.old

  7、建立新的软连接:sudo ln -s /home/openssl-1.0.2g-build/openssl-build/bin/openssl /usr/bin/openssl

  8、编辑链接文件:vim /etc/ld.so.conf.d/libc.conf

  9、在libc.conf文件中添加:/usr/openssl-1.0.2g-build/openssl-build/lib

  10、重新加载配置:ldconfig

  11、测试:openssl version ,已经变成1.0.2g版本了

八、准备openssl-target

  1、同样是再次解压openssl源码包,这次解压的源码包用来交叉编译给target-python使用的:tar -xzvf openssl-1.0.2g.tar.gz

  2、更改名字:mv openssl-1.0.2g openssl-1.0.2g-target

  3、cd openssl-1.0.2g-target

  4、设置编译环境:./config no-asm --shared --cross-compile-prefix=arm-buildroot-linux-gnueabihf- --prefix=/home/openssl-1.0.2g-target/openssl-target

    解释:no-asm :加上no-asm 表示不使用汇编代码加速编译,不然会报错

       --cross-compile: 指定交叉编译链的前缀,这样在交叉编译openssl就会使用我们的交叉编译链进行交叉编译了

       --prefix: 已经是交叉编译后的路径

  5、在编译后生成的Makefile中有两处是 -m64 的标记要删除,因为交叉编译后是在32位的板子上运行,所以这一步也要改:sed -i 's/-m64//' Makefile

  6、执行编译安装:make && make install

  目前我们就把openssl-build和openssl-target都准备好了

九、准备zlib-build

  1、解压源码包:unzip zlib1211.zip

  2、改名:mv zlib-1.2.11 zlib-1.2.11-build

  3、cd zlib-1.2.11-build

  4、设置编译环境:./configure --prefix=/home/zlib-1.2.11-build/zlib-build

  5、执行编译安装:make && make install

十、准备zlib-target

  1、解压源码包:unzip zlib1211.zip

  2、改名:mv zlib-1.2.11 zlib-1.2.11-target

  3、cd zlib-1.2.11-target

  4、设置交叉编译器:export CC=arm-buildroot-linux-gnueabihf-gcc 通过export 设置的环境变量都是临时一次性的,当shell窗口关闭了就失效了

  5、设置编译环境:./configure --prefix=/home/zlib-1.2.11-target/zlib-target --enable-shared

  6、执行编译安装:make && make install

  目前我们也已经包zlib-build和zlib-target准备好了

十一、准备ctypes-build

  这一步已经在准备工作中做了:sudo apt-get install libffi-dev

十二、准备ctypes-target

  1、解压源码包:tar -xzvf libffi-3.2.1.tar.gz

  2、改名:mv libffi-3.2.1 libffi-3.2.1-target

  3、cd libffi-3.2.1-target

  4、设置交叉编译器:export CC=arm-buildroot-linux-gnueabihf-gcc 如果这一步在准备zlib-target没有关闭shell窗口的时候,可以不用设置,因为已经设置过了,但是如果关了窗口就要重新设置了

  5、设置编译环境:./configure CC=arm-buildroot-linux-gnueabihf-gcc --host=arm-buildroot-linux-gnueabihf --build=x86_64-linux-gnu target=arm-buildroot-linux-gnueabihf --enable-shared --prefix=/home/libffi-3.2.1-target/libffi-target

  6、执行编译安装:make && make install

  目前ctypes-build和ctypes-target也准备好了

十三、编译python-build

  1、解压源码:tar xvf Python-3.5.2.tgz

  2、改名:mv Python-3.5.2 python-3.5.2-build

  3、cd /home/python-3.5.2-build

  4、修改 Modules/Setup.dist文件:vim Modules/Setup.dist

    a、修改关于openssl部分

    b、修改关于zlib部分

  5、将之前设置的交叉编译器改为默认的编译器:export CC= 这里=后面什么都不赋值就表示设置为空,这样就会去找默认的gcc了

  6、设置编译环境,./configure --prefix=/home/python-build --without-ensurepip

     --without-ensurepip:不安装pip,因为默认安装的pip版本太低了,所以一会我们自己安装pip

  7、执行安装编译:make && make install

  8、cd /home/python-build/bin

  9、下载pip文件:curl https://bootstrap.pypa.io/pip/3.5/get-pip.py -o get-pip.py -k

  10、安装pip: ./python3 get-pip.py

  11、将该python-build添加到环境变量,设置为build主机上默认的python: export PATH=/home/python-build/bin:$PATH

  12、安装Cython:pip3 install Cython

  13、测试:python3

十四:编译python-targer

  1、解压源码包:tar xvf Python-3.5.2.tgz

  2、改名:mv Python-3.5.2 python-3.5.2-target

  3、cd python-3.5.2-target

  4、创建文件夹:mkdir /home/python-target

  5、将之前准备的openssl-targer、zlib-targer、cytpes-targer的头文件和链接库复制到/home/python-targer

    cp -rfp /home/zlib-1.2.11-target/zlib-target/* /home/python-target/

    cp -rfp /home/libffi-3.2.1-target/libffi-target/* /home/python-target/

    cp -rfp /home/openssl-1.0.2g-target/openssl-target/* /home/python-target/

  6、设置CFLAGS:CFLAGS="-I/home/python-target/include -I/home/python-target/include/python3.5m -L/home/python-target/lib"

  7、设置LDFLAGS:LDFLAGS="-L/home/python-target/lib"

  8、vim Modules/Setup.dist

  9、设置编译环境:注意这里我为了方便看,手动的给每个参数换行了,实际使用中不应该换行的

./configure CC=arm-buildroot-linux-gnueabihf-gcc 
CXX=arm-buildroot-linux-gnueabihf-g++ 
AR=arm-buildroot-linux-gnueabihf-ar 
RANLIB=arm-buildroot-linux-gnueabihf-ranlib 
--host=arm-buildroot-linux-gnueabihf 
--build=x86_64-linux-gnu 
--target=arm-buildroot-linux-gnueabihf 
--disable-ipv6 
ac_cv_file__dev_ptmx=yes 
ac_cv_file__dev_ptc=yes 
--prefix=/home/python-target 
--without-ensurepip

  10、编译:make HOSTPYTHON=/home/python-build/bin/python3 HOSTPGEN=/home/python-3.5.2-build/Parser/pgen

  11、执行:make install HOSTPYTHON=/home/python-build/bin/python3

  目前位置我们就在build主机上已经编译好了python-build和python-target

十五、通过crossenv交叉编译第三方库例如:numpy

  1、在build主机上使用python-build搭建python-target的虚拟环境,然后再虚拟环境中打包python-target的第三方库,这里以numpy为例:因为numpy是需要经过交叉编译才能使用的。

  2、cd /home/python-build/bin

  3、安装crossenv:./pip3 install crossenv

  4、使用crossenv代表python-target的虚拟环境:./python3 -m crossenv --without-pip /home/python-target/bin/python3 cross_venv

  5、cd cross_venv/cross/bin

  6、激活虚拟环境:source activate

  7、curl https://bootstrap.pypa.io/pip/3.5/get-pip.py -o get-pip.py -k

  8、./python3 get-pip.py

  9、在cross_venv这个虚拟环境中的安装Cython:./pip3 install Cython

  10、创建文件夹用来存放编译后的第三方:mkdir /home/target_lib

  11、创建requestments.txt:vim requirements.txt 里面写上numpy

  12、交叉编译第三方库成为.whl格式的安装包:./pip3 wheel --wheel-dir /home/target_lib -r requirements.txt

  13、验证:cd /home/target_lib

  14、注意,这里我们使用crossenv交叉编译后的numpy第三方库的后缀是linux_arm,而我们的目标板子是armv7l的,所以这里我们要手动的将

    numpy-1.18.5-cp35-cp35m-linux_arm.whl改为numpy-1.18.5-cp35-cp35m-linux_armv7l.whl。不然会报错。这个坑,一直坑了我一个月的时间,尝试了很多方法,不知道是编译链的问题,还是编译过程的问题。将交叉编译后的numpy的.whl文件移植到目标板子的中,总是报错,突然灵光一闪,就手动改个名字,居然可以了,这坑简直是巨坑,坑了一个月的时间。

十六、移植到目标板子

  将编译好的python-target打包 和 numpy-1.18.5-cp35-cp35m-linux_arm.whl(先不改名,移植到目标板子上在改名)移植到目标板子上

  1、压缩python-target:tar cvf python-target.tar python-target

  2、通过ftp工具,将python-target.tar和numpy-1.18.5-cp35-cp35m-linux_arm.whl ,移植到目标板子的/home下

  3、解压python-target:tar xvf python-target.tar

  4、cd /home/python-target/bin

  5、验证在目标板子上运行python3

  6、验证交叉编译的第三方

    1、先下载pip:curl https://bootstrap.pypa.io/pip/3.5/get-pip.py -o get-pip.py -k

    2、安装pip:./python3 get-pip.py

    3、配置pip源

      a、mkdir ~/.pip

      b、vi ~/.pip/pip.conf

      c、添加如下代码

[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple 
trusted-host = pypi.tuna.tsinghua.edu.cn

    4、验证pip

    5、通过pip安装未改名的numpy第三方库:这是会报错:numpy-1.18.5-cp35-cp35m-linux_arm.whl is not a supported wheel on this platform.

    6、改名:mv /home/numpy-1.18.5-cp35-cp35m-linux_arm.whl /home/numpy-1.18.5-cp35-cp35m-linux_armv7l.whl

     7、重新安装验证:        

到此python3及python需要的第三方库,类似numpy这样需要交叉编译的第三方库就完成了!其中其他库不一定都是完全一样的,但是大致流程是一样的可以参考借鉴。

【相关推荐:Python3视频教程

以上がPythonにおけるサードパーティライブラリのクロスコンパイルの問題についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjb51.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。