Tabla de contenido
1. Breve introducción
1.1 Metas claras
Debido a que debe ejecutarse en una placa de desarrollo de Linux integrada, los archivos de la plataforma x86_64 deben compilarse de forma cruzada en archivos de arquitectura arm mediante compilación cruzada. Lo principal aquí es realizar una compilación cruzada del código fuente de Python y sus bibliotecas dependientes, y luego realizar una compilación cruzada en la plataforma QT de Ubuntu para crear un archivo ejecutable que utilice el lenguaje Python y pueda ejecutarse en la plataforma Linux integrada.
1.2 versión de Python y sus antecedentes
- Cadena de herramientas de compilación cruzada: gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf
- plataforma ubuntu: ubuntu18.04.1 64 bits
- versión de Python: python3.6.9
- Núcleo de placa de desarrollo de Linux integrado: NXP CORTEX-A7 IMX6ULL
1.3 Pasos
- Primero realice una compilación cruzada del código fuente de Python y sus bibliotecas dependientes.
- Portado a la placa de desarrollo de Linux
- Escribir verificación de demostración en la plataforma Qt de ubuntu
2. Compilación cruzada del código fuente de Python y sus bibliotecas dependientes
2.1 Pasos de compilación
- Compile de forma cruzada la biblioteca openssl, que probablemente será utilizada por la mayoría de las demás bibliotecas.
- Compile de forma cruzada la biblioteca zlib, que es una biblioteca dependiente necesaria para la instalación del código fuente de Python.
- Compilación cruzada de la biblioteca libffi
- Compile el código fuente de Python de forma cruzada.
Aquí hay un enlace del disco de red de Baidu. Puede descargar las bibliotecas relevantes del sitio web oficial o puede obtenerlas directamente desde aquí:
Enlace: https://pan.baidu.com/s/1mui3Vw8FfxnMUFSjFZhItA
Código de extracción: pwev
2.2 Compilación cruzada de openssl
- Descargue openssl, https://www.openssl.org/source/ . La versión que estoy usando aquí es openssl1.1.1.
(Nota: para facilitar la administración, todos los códigos fuente descargados se colocan en /home/book/pyarm/zlibarm/) - Descomprimir: tar -xzvf openssl-1.1.1.tar.gz
- cd openssl-1.1.1
- Configure el entorno de compilación: ./Configure no-asm compartido no-async linux-generic32 --prefix=/home/book/pyarm/opensslarm --cross-compile-prefix=arm-linux-gnueabihf- no-asm en la cruz -proceso de compilación
El código ensamblador no se utiliza para acelerar el proceso de compilación;
compartido genera una biblioteca de enlaces dinámicos.
no-async La cadena de herramientas de compilación cruzada no proporciona la
ruta de instalación de la biblioteca GNU C ucontext –prefix= (después de make y make install, los archivos include y lib relacionados con openssl se encuentran en este directorio. Puede elegir el directorio de instalación usted mismo) –cross-
compile -prefix= herramienta de compilación cruzada
linux-generic32 significa compilación cruzada en un sistema operativo de 32 bits - hacer
- hacer la instalación
2.3 Compilación cruzada de zlib
- Descargue zlib, http://zlib.net/ . La versión que estoy usando aquí es 1.2.11.
- Descomprimir: tar -xzvf zlib-1.2.11.tar.gz
- cd zlib-1.2.11
- Configure el compilador: export CC = arm-linux-gnueabihf-gcc (debido a que no hay ninguna opción para configurar el compilador en la configuración de zlib, configure la variable de entorno aquí)
- Configure el entorno de compilación: ./configure --prefix=/home/book/pyarm/zlibarm --enable-shared
- hacer
- hacer la instalación
2.4 Compilación cruzada de libffi
- Descargue libffi, https://sourceware.org/libffi/ . La versión que estoy usando aquí es 3.2.1
- Descomprimir: tar xvzf libffi-3.2.1.tar.gz
- cd libffi-3.2.1
- Configuración del archivo:./configure CC=arm-linux-gnueabihf-gcc --host=arm-linux-gnueabihf --build=x86_64-linux-gnu target=arm-linux-gnueabihf --enable-shared --prefix= /inicio/libro/pyarm/libffiarm
- hacer
- hacer la instalación
2.5 Python de compilación cruzada
-
Descargue Python, https://www.python.org/downloads/source/ . La versión que estoy usando aquí es 3.6.9
-
Descomprimir: tar xvf Python-3.6.9.tgz
-
cdPython-3.6.9
-
mkdir /home/book/arm-python (debido a que la compilación de Python depende de la biblioteca anterior, agregue un directorio aquí, y el include y lib compilados anteriormente se moverán a este directorio)
-
Copie los archivos de encabezado y las bibliotecas de enlaces de las bibliotecas relevantes compiladas anteriormente en /home/book/arm-python cp -rfp /
home/book/pyarm/zlibarm/* /home/book/arm-python cp
-rfp /home/ book /pyarm/libffiarm/* /home/book/arm-python
cp -rfp /home/book/pyarm/opensslarm/* /home/book/arm-python -
Texto CFLAGS: CFLAGS = “-I /home/book/arm-python -I /home/book/arm-python/include/python3.6m -L /home/book/arm-python/lib”
-
Establecer LDFLAGS: LDFLAGS="-L /home/book/arm-python/lib"
-
vi Modules/Setup.dist, modifique los archivos de encabezado y los archivos de biblioteca de las bibliotecas relevantes que se encuentran dentro.
Nota: Como puede ver en la imagen de arriba, la ruta a la biblioteca que configuramos es una ruta absoluta, por lo que cuando empaquetemos los archivos compilados en la placa de desarrollo más adelante, también deben colocarse en /home/book/arm-python. del directorio de la placa de desarrollo (si no, puede crearlo usted mismo)
(La razón es: el entorno virtual de Python registrará la ruta absoluta del compilador de Python ; por lo tanto, cuando se ejecuta el entorno virtual de Python en otros hosts, el entorno virtual seguirá buscando el compilador de Python en esta ruta absoluta. Por lo tanto, se debe crear el mismo directorio en la placa de desarrollo; de lo contrario, se producirán errores como archivos y módulos no encontrados) -
./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=x86_64-linux-gnu --target=arm-linux-gnueabihf --disable-ipv6 ac_cv_file__dev_ptmx=yes ac_cv_file__dev_ptc=yes --prefix=/home/book/arm-python --enable-shared --sin-ensurepip
-
hacer
-
hacer la instalación
3. Trasplante a la placa de desarrollo de Linux
- Comprima el directorio arm-python: cd /home/book tar cvf arm-python.tar arm-python
- Transfiera arm-python.tar al directorio /home/book de la placa de desarrollo mediante herramientas como FileZilla
- Descomprimir: tar xvf arm-python.tar
Resumen: Después de los pasos anteriores, se ha completado el trasplante de Python. También puede cd /home/book/arm-python/bin aquí y luego ./python3 para ingresar a la programación de la interfaz de Python. y use exit() para salir de la interfaz Python, regrese a la línea de comando.
4. Escriba una verificación de demostración en la plataforma Qt de Ubuntu
- Cree un nuevo proyecto en Qt-----La plantilla que elegí aquí es Aplicación (Qt)-----nombre: py_test, y la ruta de creación es /home/book/QT/my_qt/qt_python----- -detrás Varios pasos están predeterminados -----Finalmente verifique la cadena de herramientas de compilación cruzada----terminado.
- Cree un nuevo archivo: seleccione Python, Archivo Python ---- nombre: test_pyfile.py, no es necesario modificar la ruta ---- completo. (Después de la creación, puede ver el archivo test_pyfile.py en Otros archivos del proyecto)
- Agregue el siguiente código al archivo test_pyfile.py: (La función principal es pasar una cadena a través del parámetro a y luego devolver una cadena concatenada b)
def testpyfile(a):
b = a+'jiayou'
return b
# 这里必须空两行:
# python编码规范:类与类,类与函数,函数与函数之间空两行)
print(testpyfile("111"))
- Importe archivos de biblioteca y archivos de encabezado relacionados con Python en el archivo .pro
INCLUDEPATH += \
-I /home/book/arm-python/include/python3.6m/ \
-I /home/book/arm-python/include \
-I /home/book/arm-python/include/openssl
LIBS += \
-L /home/book/arm-python/lib/ -lpython3.6m \
-L /home/book/arm-python/lib/ -lssl \
-L /home/book/arm-python/lib/ -lcrypto \
-L /home/book/arm-python/lib/ -lz \
- Agregue el siguiente código en la función principal:
#include "mainwindow.h"
#include <QApplication>
#include "Python.h" //引入python头文件
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
Py_Initialize(); // 初始化Python
PyObject *pModule = nullptr;
PyObject *pLoadFunc = nullptr;
PyObject *pArgs = nullptr;
PyObject *pReturn = nullptr;
PyObject *str = nullptr;
const char *bytes = nullptr;
if(!Py_IsInitialized())
{
qDebug()<<"inititalize failed";
return -1;
}
else
qDebug()<<"inititalize success";
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('/home/book/QT/my_qt/qt_python/py_test')");
pModule = PyImport_ImportModule("test_pyfile");
if(!pModule)
{
PyErr_Print();
qDebug()<<"not loaded module";
return -1;
}
else
qDebug()<<"load module success";
pLoadFunc = PyObject_GetAttrString(pModule, "testpyfile");
if(!pLoadFunc)
{
PyErr_Print();
qDebug()<<"not loaded pLoadFunc";
return -1;
}
else
qDebug()<<"load pLoadFunc success";
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0 , Py_BuildValue("s", "xuheqing"));
pReturn = PyObject_CallObject(pLoadFunc, pArgs);
if(!pReturn)
{
qDebug()<<"no return value";
return -1;
}
str = PyObject_Str(pReturn);
bytes = PyUnicode_AsUTF8(str);
qDebug()<<bytes;
Py_Finalize();// 关闭 Python 脚本解释器
return a.exec();
}
Nota: La ruta absoluta se usa en PyRun_SimpleString("sys.path.append('/home/book/QT/my_qt/qt_python/py_test')") para agregar el archivo .py que escribimos nosotros mismos, por lo que debemos colocar el archivo en En el directorio /home/book/QT/my_qt/qt_python/py_test de la placa de desarrollo (si no, puede crearlo usted mismo). De lo contrario, cuando la placa de desarrollo se esté ejecutando, habrá un error que indicará que no se puede encontrar el módulo de archivo. ! !
-
Antes de compilar, sudo vi /home/book/arm-python/include/python3.6m/object.h y modifíquelo como se muestra a continuación. (Debido a que las ranuras se definen como claves en QT y las ranuras se usan como variables en python3, habrá conflictos durante la compilación).
-
Seleccione la herramienta de compilación cruzada, luego haga clic derecho en el proyecto py_test y haga clic en Construir para obtener el programa py_test que se puede ejecutar en la arquitectura arm.
-
Transfiera el archivo py_test al directorio / mnt de la placa de desarrollo a través de herramientas como FileZilla, primero chmod +x py_test, agregue operaciones ejecutables a py_test y luego ./py_test. En este momento, encontrará un error:
./py_test: error al cargar bibliotecas compartidas: libpython3.6m.so.1.0: no se puede abrir el archivo de objeto compartido: Norectory
Solución :
① Primero use el comandoecho $PATH
para mostrar la variable de entorno PATH actual. Mi variable de entorno es / bin:/sbin:/usr/bin:usr/sbin. Cuando ejecutamos el programa, el shell busca automáticamente estas rutas para el programa en función del valor de la variable PATH. Entonces puedeexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/book/arm-python/lib
agregar la ruta a la biblioteca relacionada con Python y ejecutarla.
(Nota: este es solo uno de los métodos y es solo una modificación temporal. Después de reiniciar la placa de desarrollo, es necesario restablecer la variable de entorno)
② vi /etc/profile. Agregado al final del archivoexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/book/arm-python/lib
. Luego reinicie la placa de desarrollo . Las variables de entorno en /etc/profile son válidas para todos los usuarios y se ejecutan cuando se inicia el sistema. Esta es una forma de que las variables de entorno sean válidas permanentemente. -
resultado de la operación