Heim >Backend-Entwicklung >Python-Tutorial >Zum Thema Cross-Compilation von Drittanbieter-Bibliotheken in Python
Dieser Artikel vermittelt Ihnen relevante Kenntnisse über die Cross-Kompilierung von Drittanbieter-Bibliotheken. Unter Cross-Compilation versteht man die Generierung von ausführbarem Code auf einer Plattform. hoffe es hilft allen.
[Verwandte Empfehlungen: Python3-Video-Tutorial ]
Es gibt viele Artikel über die Cross-Compilation von Python im Internet, aber es gibt relativ wenige Artikel über die Cross-Compilation des dritten Bibliothek von Python, und Viele Titel beziehen sich auf die Cross-Compilation von Drittanbieter-Bibliotheken, aber tatsächlich verwenden sie Bibliotheken, die ohne Cross-Compilation verwendet werden können und nicht sehr referenzierbar sind. In letzter Zeit gab es viel Kritik Cross-Compilation von Python und seinen Drittanbieter-Bibliotheken. Verdammt, nimm es auf!
1. Was ist Cross-Compilation: Generieren von ausführbarem Code auf einer Plattform auf einer anderen Plattform.
2. Warum Cross-Compile: Bei der Entwicklung eingebetteter Systeme verfügt die Zielplattform, auf der das Programm ausgeführt wird, normalerweise über begrenzten Speicherplatz und Rechenleistung. Beispielsweise verfügt die gängige ARM-Plattform über einen relativ kleinen statischen Speicherplatz und die CPU Schwache Rechenleistung. In diesem Fall ist eine native Kompilierung auf der ARM-Plattform nicht möglich. Um dieses Problem zu lösen, wurden Cross-Compilation-Tools entwickelt. Durch Cross-Compilation-Tools können wir ausführbare Programme für andere Plattformen auf Hostplattformen mit starker CPU-Leistung und ausreichender Speichersteuerung (z. B. PCs) kompilieren.
1. Cross-Compilation-Kette: rv1126-arm-buildroot-linux-gnueabihf-toolchain.tar.bz2
2. Zielplatine (Zielhost) : armv7l
3. Der Host, der Cross-Editing durchführt (Build-Host): ubuntu18-x86_64
4. Python-Version: 3.5.2
5. numpy==1.18.5
Der Build-Host ist, dass ich eine neue virtuelle Maschine von Ubuntu 18 neu installiert habe, also hat sie nicht einmal gcc
1. Installieren Sie gcc: sudo apt-get install gcc-8 -y
2. Geben Sie gcc-8 an als Standard-gcc: sudo ln -s /usr/bin/gcc-8 /usr/bin/gcc
3. Installieren Sie cmake: sudo apt-get install make cmake -y
4 . Erforderliche Abhängigkeiten für die Cross-Kompilierung von Python: sudo apt-get install libffi-dev
5. Installieren Sie zip und dekomprimieren Sie das komprimierte Paket mit: sudo apt-get install zip -y
1. Cross-Kompilierung auf der Build-Host-Zlib-Bibliothek, dies ist eine notwendige abhängige Bibliothek für die Python-Quellcode-Installation
2. Cross-Kompilierung der OpenSSL-Bibliothek auf dem Build-Host. Dies ist jedoch keine notwendige abhängige Bibliothek Für die Installation des Quellcodes können die meisten anderen Bibliotheken diese Bibliothek verwenden Den Build-Host nennen wir ihn „python-target“
5. Erstellen Sie auf dem Build-Host die laufende virtuelle Umgebung von target-python über crossenv
6. Verwenden Sie in der virtuellen Crossenv-Umgebung pip, um die Bibliothek von Drittanbietern zu packen und zu kompilieren in .whl-Form
6. Bereiten Sie das Cross-Compilation-Tool vor
1. Entpacken Sie die Cross-Compilation-Kette: Anweisungen Verschiedene Plattformen verwenden unterschiedliche Cross-Compilation-Ketten, aber die Ideen und Schritte sind die gleichen.
tar jxvf rv1126-arm-buildroot-linux-gnueabihf-toolchain.tar.bz2
3. Führen Sie den Befehl relocate-sdk.sh aus: ./relocate-sdk.sh (Nicht alle Cross-Compilation-Ketten erfordern diesen Schritt)
4 das Kreuz Fügen Sie die Kompilierungskette zur Umgebungsvariablen hinzu: vim /etc/profile
5. Fügen Sie am Ende hinzu: export PATH=$PATH:/home/host/bin Der Pfad hier kann entsprechend Ihrem tatsächlichen Pfad geändert werden.
6. Umgebungsvariablen neu laden: source /etc/profile7. Test: arm-buildroot-linux-gnueabihf-gcc -v
7. Openssl-build vorbereitenHier habe ich bereits Das komprimierte Paket von openssl-1.0.2g.tar.gz ist fertig. Hier habe ich die Version von openssl-1.1.1 ausprobiert, aber sie ist nicht für Python3.5.2 geeignet und macht immer Probleme, daher verwende ich hier die Version von openssl-1.0. 2
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版本了
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都准备好了
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
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准备好了
这一步已经在准备工作中做了:sudo apt-get install libffi-dev
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也准备好了
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
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
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视频教程 】
Das obige ist der detaillierte Inhalt vonZum Thema Cross-Compilation von Drittanbieter-Bibliotheken in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!