Compilador cruzado para Raspberry Pi4



Quiero contarles cómo armé un compilador cruzado para Raspberry Pi4 usando crosstool-ng. Quizás alguien encuentre el tema demasiado primitivo y aburrido. Al principio, yo mismo pensé que podría ensamblar rápidamente un compilador cruzado, pero tuve que modificar y estudiar el problema, algunos de los matices fueron inesperados para mí. Entonces te diré qué y cómo lo hice.



Quizás la primera pregunta que debe hacerse es: "¿Para qué sirve un compilador cruzado?" De hecho, la Raspberry Pi4 es bastante rápida y puedes compilar programas directamente en ella. Si el proyecto es simple, entonces es muy posible hacerlo. Pero cuando el proyecto crece y se vuelve más complejo, entonces ya es mejor cambiar a la compilación cruzada. Entonces es más fácil resolver otros problemas, por ejemplo, puede organizar el autoensamblaje del proyecto en el servidor de integración. La compilación cruzada en una PC rápida puede aumentar significativamente la velocidad de compilación y puede encontrar mejores herramientas para editar programas en una PC.



Segunda pregunta: “¿Puedo utilizar un compilador cruzado listo para usar? ¿Por qué recoger el tuyo propio? " Para decirte la verdad, no he encontrado un compilador cruzado normal para Raspberry. ¿Quizás me veía mal? En github de Rasberryhay un proyecto de herramientas y hay varios compiladores cruzados, ¡pero son antiguos! Bueno, ¿qué hay ahí? Versión 4.9.3? De alguna manera no es serio. En la página de descarga de Linaro, solo veo la versión 7.5, ya mejor, pero, en primer lugar, en el sistema operativo Raspberry Buster, la versión 8.3 ya está, y en segundo lugar, el compilador de Linaro funcionó para mí solo después de algunos parches. Es un poco extraño ...



Fue después de intentar ejecutar el compilador de Linaro que pensé que probablemente podría construir mi propio compilador cruzado yo mismo. Ya tenía algo de experiencia con crosstool-ng. Estaba haciendo un compilador cruzado para Amber SoC .



¿Cuál es la complejidad del montaje? La herramienta crosstool-ng tiene muchas configuraciones diferentes que no siempre son claras. La construcción del compilador cruzado en mi computadora portátil toma aproximadamente 45 minutos. Si comete un error con la configuración, el compilador cruzado resultante de alguna manera no funciona de esa manera, no recopila algo o recopila, pero el binario resultante no se ejecuta en Raspberry. Después de verificar el compilador cruzado resultante, nuevamente tuve que cambiar algo en la configuración y volver a generarlo desde el principio. Bueno, hice algunos intentos hasta que funcionó como quería.



Quizás lo principal que realmente no entendí al principio es que el compilador debe coincidir con el sistema operativo. Parece un poco extraño, pero resulta así. De hecho, el sistema operativo ya contiene las bibliotecas estándar c / c ++. Exportan un conjunto de funciones. El código generado por el compilador cruzado debe contener llamadas a estas funciones de biblioteca. Por lo tanto, las versiones de las bibliotecas en el propio compilador cruzado y en el sistema operativo para el que se generará el código deben coincidir.



Intentemos crear un compilador cruzado.



El procedimiento será el siguiente:



1) Verifique que los siguientes paquetes estén instalados en nuestro sistema host (estoy usando Ubuntu 18):



gcc g++ gperf bison flex texinfo help2man make libncurses5-dev python3-dev autoconf automake libtool libtool-bin gawk wget bzip2 xz-utils unzip patch libstdc++6 rsync git

      
      





Si falta algo, debe instalarlo a través de sudo apt install.



2) Descargue la versión 1.24.0 de crosstool-ng desde su sitio web:



wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.24.0.tar.bz2 

      
      





3) Desempaquete el archivo resultante:



tar xjf crosstool-ng-1.24.0.tar.bz2 
cd crosstool-ng-1.24.0 

      
      





4) Armando crosstool-ng:



./configure
make
make install
      
      





5) Parchear crosstool-ng



Esta es una acción bastante extraña, pero sin ella no obtuve un buen resultado. Sin este parche, el compilador cruzado se negó por defecto a buscar bibliotecas en la carpeta / usr / lib / arm-linux-gnueabihf relativa a sysroot.



El parche debe obtenerse en la misma frambuesa.



En la raspberry pi4 con OS Buster instalado (esto es importante, estoy haciendo un compilador cruzado para este SO en particular), debe tomar las fuentes de binutils:



sudo apt install binutils-source
      
      





y ver /usr/src/binutils/patches/129_multiarch_libpath.patch







Este archivo lo colocamos en la carpeta crosstool-ng-1.24.0 / packages / binutils / 2.31.1 en nuestra computadora host. Es importante ponerlo en esta carpeta, ya que en el Raspberry Pi OS Buster en sí, la versión de binutils es 2.31.1. Verifique esto con un comando en la consola de la frambuesa:



ld --version
      
      





Además, debe verificar qué GLIB está en su sistema operativo para el apretón:



ldd --version
      
      





Tengo 2.28 en Buster, lo que significa que crosstool-ng en sí deberá configurarse en esta versión de GLIB 2.28, hay una versión diferente por defecto. Si esto no se hace, el compilador cruzado generará código que no se ejecutará en Raspberry en Buster OS; el binario puede referirse a funciones no existentes en bibliotecas externas.



6) Prepare la configuración inicial de crosstool-ng



Ya existen bastantes configuraciones típicas en el propio crosstool-ng. Incluso, hay una configuración muy similar a la que necesitamos para la Raspberry Pi3.



Se puede ver una lista de todas las configuraciones posibles con el comando:



./ct-ng list-samples
      
      





Entonces la configuración seleccionada debe ser "activada" con el comando:



./ct-ng armv8-rpi3-linux-gnueabihf
      
      





Aparecerá un nuevo archivo de configuración .config, que define completamente las propiedades del futuro compilador cruzado. Ahora hay que corregirlo un poco. Puede editarlo manualmente, pero es más fácil de arreglar desde el menú:



./ct-ng menuconfig
      
      





El primer menú se ve así:







7) A continuación, cambie la opción extraña, posiblemente opcional.



Casi en todas partes donde al menos algo está escrito sobre la creación de un compilador cruzado para Raspberry, escriben para desmarcar la opción "Renderizar la cadena de herramientas como de solo lectura". Esta configuración se encuentra en el menú "Rutas y opciones varias". La documentación de crosstool-ng dice que, por defecto, el compilador resultante será de solo lectura para que el programa compilado no se instale inadvertidamente en el sysroot del propio compilador. En mi opinión, esta es una decisión perfectamente razonable. No sé por qué algún autor escribe para quitar la marca de aquí ...



8) Siguiente. Vaya al elemento "Opciones de destino" y establezca los valores de acuerdo con la captura de pantalla:







Debo decir que, de hecho, la Raspberry Pi4 tiene un procesador Cortex-A72 y este se puede asignar aquí en el menú. Sin embargo, guardé el Cortex-A53 para mí porque compilaré no solo para Pi4, sino también para Pi3. Aunque, la configuración exacta ya se puede especificar al iniciar el compilador gcc usando el parámetro de línea de comando -mcpu = cortex-a72



También quiero agregar que prefiero que el compilador cruzado tenga exactamente la misma tupla que el compilador en la placa Raspberry. Es decir, el compilador final será arm-linux-gueabihf y nada más. Es mas facil para mi Muchos paquetes existentes incluyen archivos cmake listos para usar, donde el compilador se asigna a arm-linux-gnueabihf. ¿No queremos arreglar todos estos archivos cmake a mano y escribir algo como armv8-mygcc-linux-gnueabihf allí? Para hacer esto, desactivo la opción "Omitir parte del proveedor de la tupla de destino".



9) Vaya al menú "Utilidades binarias" e instale la versión binutils 2.31.1 (¿Recuerda que todavía tenemos un parche para ello?)







10) Vaya al menú "Sistema operativo" e instale la versión 4.20 del kernel







De hecho, Raspberry Buster OS ya tiene un kernel 5.10, pero lo máximo es que solo puedes instalarlo 4.20



11) Ve al menú "C-libraries" e instala la versión GLIB 2.28







12) Ve al "C-compiler" menu







Instale la versión deseada del futuro compilador cruzado 8.3.0 y agregue la opción --enable-multiarch a la configuración del compilador de configuración extra de gcc principal. Es importante que el compilador cruzado encuentre las bibliotecas en sysroot a lo largo de la ruta / usr / lib / arm-linux-gnueabihf.

Ahora salimos de todos los menús, guardamos los cambios realizados cuando se nos solicite y comenzamos a construir.



13) El montaje se realiza con simples comandos:



export DEB_TARGET_MULTIARCH=arm-linux-gnueabihf 
./ct-ng build
      
      





Tendrá que esperar. Me tomó unos 45 minutos ensamblar mi computadora portátil. Después de compilar, su nuevo compilador cruzado se encuentra en la ruta ~ / x-tools / arm-linux-gnueabihf



Puede verificar qué rutas de biblioteca utilizará el compilador cruzado de forma predeterminada. ¿Se verá en la ruta / usr / lib / arm-linux-gnueabihf?



Para hacer esto, ejecute el comando:



~/x-tools/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ld --verbose | grep "SEARCH"

      
      





El comando debería devolver algo como esto:



SEARCH_DIR("=/usr/local/lib/arm-linux-gnueabihf"); SEARCH_DIR("=/lib/arm-linux-gnueabihf"); SEARCH_DIR("=/usr/lib/arm-linux-gnueabihf"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/home/nick/x-tools/arm-linux-gnueabihf/arm-linux-gnueabihf/lib");
      
      





Tenga en cuenta que las rutas comienzan con el signo "=". Esto significa que estas son rutas relativas a sysroot si se especifican al ejecutar gcc con la opción de línea de comando --sysroot = PATH_TO_YOUR_SYSROOT.



Probablemente eso es todo. Queda por decidir dónde obtener sysroot. La forma más sencilla es instalar todos los paquetes de desarrollo necesarios en la Raspberry Pi y luego, extrayendo la tarjeta SD del dispositivo, transferirla a la PC host. Pero también hay algunos matices.



Ahora que tenemos un compilador cruzado, podemos construir algún tipo de programa específico para el analizador. Por ejemplo, las demostraciones de usuario de la propia Raspberry:



git clone https://github.com/raspberrypi/userland.git
cd userland
export PATH=${HOME}/x-tools/arm-linux-gnueabihf/bin:$PATH
./buildme

      
      





El resultado de la compilación estará en la carpeta build / bin.



Al final del artículo, me gustaría dar una tabla de parámetros adicionales para compiladores de gcc al construir proyectos para diferentes versiones de raspberry:



Raspberry Pi 1:	-mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp (alias for vfpv2)
Raspberry Pi 2:  -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4                      
Raspberry Pi 3:	-mcpu=cortex-a53 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mneon-for-64bits
Raspberry Pi 4:	-mcpu=cortex-a72 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mneon-for-64bits

      
      





Espero que mi artículo sea de utilidad para alguien.



All Articles