Compilació creuada de Qt6.8.0 per Raspberry Pi 3/4/5 amb docker

De things.cat
Salta a: navegació, cerca

Idea

N'Ulas Dikme ha desenvolupat un sistema amb docker per a fer la compilació creuada de Qt6 per a Raspberry Pi.

Primer es crea un entorn de Raspbian per a emular la Raspberry Pi. Creació de la imatge:

docker buildx build --platform linux/arm64 --load -f DockerFileRasp -t raspimage .

Es fa un contenidor amb aquesta imatge i s'extreu l'arxiu rasp.tar.gz que es farà servir per a la nova imatge per a fer la compilació creuada:

docker create --name temp-arm raspimage
docker cp temp-arm:/build/rasp.tar.gz ./rasp.tar.gz

Es tracta de fer una imatge docker que contingui:

  • Un Debian 12 sense interacció per a evitar preguntes al fer la instal·lació
  • Les eines de compilació de la Raspberry Pi emulada fent servir rasp.tar.gz
  • Es crea des de zero CMake
  • Es compilen les Qt i les seves biblioteques
  • Es compila creuadament el codi del nostre projecte
  • Es generen els binaris de l'executable i les biblioteques

Un cop feta aquesta imatge es crea un contenidor per a tenir-hi accés. S'extreuen les biblioteques i el binari executable per passar-ho a la Raspberry Pi.

Dockerfile

Al Dockerfile original s'inclouen les biblioteques:

  • QtBase
  • QtShaderTools
  • QtDeclarative

I al Dockerfile modificat per a permetre la comunicaió mitjançant MQTT hi afegeixo:

En marxa

  • Aneu al directori a on hi ha l'arxiu Dockerfile i deseu el codi a compilar dins de la carpeta project (assegureu-vos de no copiar CMakeLists.txt.user ni la carpeta build).
  • Identifiqueu el nom de l'arxiu executable. Dins l'arxiu CMakeLists.txt hi ha qt_add_executable amb el nom de l'arxiu executable (nom_arxiu_executable):
qt_add_executable(nom_arxiu_executable
   main.cpp
)
  • Feu una imatge de docker d'un Debian 12, anomenada qtcrossbuild, capaç de fer la compilació creuada per a Raspberry Pi (el darrer . és important. Indica que el Dockerfile i la carpeta project són al directori des d'on executa l'ordre docker build):
docker build -t qtcrossbuild .

El primer cop a fer la imatge pot trigar al voltant de 4 hores. Un cop feta, el segon cop que es fa servir, habitualment canviant el contingut de la carpeta build, trigarà al voltant d'un minut, depenent de la complexitat del codi a compilar. Quan hi hagi actualitzacions del kernel al repositoris de Debian tornarà a trigar al voltant de 4 hores a fer-se la imatge.

  • Feu un contenidor temporal de la imatge qtcrossbuild per a poder copiar l'executable generat per a Raspberry Pi:
docker create --name contenidor_temporal qtcrossbuild
  • Copieu al vostre directori (si no ho heu canviat, seguiu al directori a on hi ha l'arxiu Dockerfile) l'executable generat per a Raspberry Pi que és a dins del contenidor:
docker cp contenidor_temporal:/build/project/nom_arxiu_executable ./nom_arxiu_executable
  • Copieu l'arxiu executable generat a la Raspberry Pi (canvieu pi pel vostre usuari i 192.168.1.XX per la IP de la vostra Raspberry Pi):
scp nom_arxiu_executable pi@192.168.1.XX:/home/pi/

o (canvieu raspberry pel hostname de la vostra Raspberry Pi):

scp nom_arxiu_executable pi@raspberry.local:/home/pi/
  • El primer cop que feu la compilació creuada també haureu de copiar a la Raspberry Pi les biblioteques necessàries per a que funcioni l'executable que heu compilat:
docker cp contenidor_temporal:/build/qt-pi-binaries.tar.gz ./qt-pi-binaries.tar.gz
scp qt-pi-binaries.tar.gz pi@192.168.1.XX:/home/pi/
ssh pi@192.168.1.XX
pi@raspberrypi:~ sudo mkdir /usr/local/qt6
pi@raspberrypi:~ sudo tar -xvf qt-pi-binaries.tar.gz -C /usr/local/qt6
pi@raspberrypi:~ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/qt6/lib/
  • Poseu en marxa l'executable generat a la Raspberry:
pi@raspberrypi:~ ./nom_arxiu_executable
  • Un cop heu fet totes les passes anteriors i tan sols esteu modificant el codi font de l'executable no us caldrà tornar a instal·lar les biblioteques. Un cop deseu el vostre codi dins de la carpeta project tan sols haureu de repetir aquest procés:
docker build -t qtcrossbuild .
docker create --name contenidor_temporal qtcrossbuild
docker cp contenidor_temporal:/build/project/nom_arxiu_executable ./nom_arxiu_executable
scp nom_arxiu_executable pi@raspberry.local:/home/pi/

És un procés prou ràpid (al voltant d'un minut) excepte quan hi ha actualitzacions del kernel als repositoris de Debian (que triga al voltant de quatre hores fer una nova imatge).

Font

Cross compilation of Qt6.8.0 For Raspberry pi 3/4/5 with Docker(Base and QML packages) and Remote Debugging with Vscode desenvolupat per Ulas Dikme