En Ubuntu, basado en la plataforma Qt, llame al archivo Python y compílelo de forma cruzada en la placa de desarrollo de Linux integrada para ejecutarlo.

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

  1. Cadena de herramientas de compilación cruzada: gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf
  2. plataforma ubuntu: ubuntu18.04.1 64 bits
  3. versión de Python: python3.6.9
  4. Núcleo de placa de desarrollo de Linux integrado: NXP CORTEX-A7 IMX6ULL

1.3 Pasos

  1. Primero realice una compilación cruzada del código fuente de Python y sus bibliotecas dependientes.
  2. Portado a la placa de desarrollo de Linux
  3. 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

  1. Compile de forma cruzada la biblioteca openssl, que probablemente será utilizada por la mayoría de las demás bibliotecas.
  2. Compile de forma cruzada la biblioteca zlib, que es una biblioteca dependiente necesaria para la instalación del código fuente de Python.
  3. Compilación cruzada de la biblioteca libffi
  4. 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

  1. 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/)
  2. Descomprimir: tar -xzvf openssl-1.1.1.tar.gz
  3. cd openssl-1.1.1
  4. 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
  5. hacer
  6. hacer la instalación

2.3 Compilación cruzada de zlib

  1. Descargue zlib, http://zlib.net/ . La versión que estoy usando aquí es 1.2.11.
  2. Descomprimir: tar -xzvf zlib-1.2.11.tar.gz
  3. cd zlib-1.2.11
  4. 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í)
  5. Configure el entorno de compilación: ./configure --prefix=/home/book/pyarm/zlibarm --enable-shared
  6. hacer
  7. hacer la instalación

2.4 Compilación cruzada de libffi

  1. Descargue libffi, https://sourceware.org/libffi/ . La versión que estoy usando aquí es 3.2.1
  2. Descomprimir: tar xvzf libffi-3.2.1.tar.gz
  3. cd libffi-3.2.1
  4. 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
  5. hacer
  6. hacer la instalación

2.5 Python de compilación cruzada

  1. Descargue Python, https://www.python.org/downloads/source/ . La versión que estoy usando aquí es 3.6.9

  2. Descomprimir: tar xvf Python-3.6.9.tgz

  3. cdPython-3.6.9

  4. 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)

  5. 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

  6. Texto CFLAGS: CFLAGS = “-I /home/book/arm-python -I /home/book/arm-python/include/python3.6m -L /home/book/arm-python/lib”

  7. Establecer LDFLAGS: LDFLAGS="-L /home/book/arm-python/lib"

  8. vi Modules/Setup.dist, modifique los archivos de encabezado y los archivos de biblioteca de las bibliotecas relevantes que se encuentran dentro.
    Insertar descripción de la imagen aquí
    Insertar descripción de la imagen aquí

    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)

  9. ./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

  10. hacer

  11. hacer la instalación

3. Trasplante a la placa de desarrollo de Linux

  1. Comprima el directorio arm-python: cd /home/book tar cvf arm-python.tar arm-python
  2. Transfiera arm-python.tar al directorio /home/book de la placa de desarrollo mediante herramientas como FileZilla
  3. 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

  1. 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.
  2. 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)
  3. 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"))
  1. 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   \
  1. 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. ! !

  1. 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).
    Insertar descripción de la imagen aquí

  2. 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.
    Insertar descripción de la imagen aquí
    Insertar descripción de la imagen aquí

  3. 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 comando echo $PATHpara 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 puede export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/book/arm-python/libagregar 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 archivo export 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.

  4. resultado de la operación
    Insertar descripción de la imagen aquí

5. Enlaces a documentos de referencia

  1. Compilación cruzada de bibliotecas de Python y de terceros.
  2. Programación híbrida QT+python en entorno ubuntu
  3. Py_Initialize: no se puede cargar el códec del sistema de archivos, se produce un error al llamar al script Python utilizando el entorno virtual Python C++

Supongo que te gusta

Origin blog.csdn.net/m0_43443861/article/details/127907530
Recomendado
Clasificación