-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 0d780b7
Showing
5 changed files
with
292 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
####################################################################### | ||
# Docker image generation for cross-compiling Qt 6 for Raspberry Pi 3 # | ||
####################################################################### | ||
|
||
# Based on: https://wiki.qt.io/Cross-Compile_Qt_6_for_Raspberry_Pi | ||
# |- https://wiki.qt.io/Building_Qt_6_from_Git | ||
# https://github.com/PhysicsX/QTonRaspberryPi/blob/main/README.md | ||
|
||
# Building Qt does not work on the newest Ubuntu (linker error), so let's use Ubuntu 20.04 | ||
FROM ubuntu:focal | ||
|
||
####################################################################### | ||
# PLEASE CUSTOMIZE THIS SECTION | ||
####################################################################### | ||
# The Qt version to build | ||
ARG QT_VERSION=6.3.1 | ||
# The Qt modules to build | ||
# I use QtQuick with QML, so the following three modules need to be built | ||
ARG QT_MODULES=qtbase,qtshadertools,qtdeclarative | ||
# How many cores to use for parallel builds | ||
ARG PARALLELIZATION=8 | ||
# Your time zone (optionally change it) | ||
ARG TZ=Europe/Berlin | ||
####################################################################### | ||
|
||
ARG CMAKE_GIT_HASH=6b24b9c7fca09a7e5ca4ae652f4252175e168bde | ||
ARG RPI_DEVICE=linux-rasp-pi3-g++ | ||
|
||
############################# | ||
# Prepare and update Ubuntu # | ||
############################# | ||
RUN apt update \ | ||
&& apt upgrade -y \ | ||
&& apt install sudo \ | ||
&& useradd -G sudo -m qtpi \ | ||
&& echo "%sudo ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers | ||
USER qtpi:qtpi | ||
WORKDIR /home/qtpi | ||
|
||
############################# | ||
# Install required packages # | ||
############################# | ||
# Qt | ||
RUN sudo DEBIAN_FRONTEND=noninteractive TZ="${TZ}" apt install -y make build-essential libclang-dev ninja-build gcc git bison python3 gperf pkg-config libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libatspi2.0-dev libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev \ | ||
# cross-compiler toolchain \ | ||
&& sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \ | ||
# package for building CMake \ | ||
&& sudo apt install -y libssl-dev \ | ||
# data transfer \ | ||
&& sudo apt install -y rsync wget | ||
|
||
####################### | ||
# Create working dirs # | ||
####################### | ||
RUN mkdir rpi-sysroot rpi-sysroot/usr rpi-sysroot/opt \ | ||
&& mkdir qt-host qt-raspi qthost-build qtpi-build | ||
|
||
################################################ | ||
# Copy sysroot into the image and fix symlinks # | ||
################################################ | ||
COPY --chown=qtpi:qtpi rpi-sysroot /home/qtpi/rpi-sysroot | ||
|
||
RUN wget https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py \ | ||
&& chmod u+x sysroot-relativelinks.py \ | ||
&& python3 sysroot-relativelinks.py rpi-sysroot | ||
|
||
################################## | ||
# Build a CMake version that can # | ||
# cope with our toolchain.cmake # | ||
################################## | ||
RUN git clone https://github.com/Kitware/CMake.git \ | ||
&& cd CMake \ | ||
&& git checkout ${CMAKE_GIT_HASH} \ | ||
&& ./bootstrap \ | ||
&& make \ | ||
&& sudo make install \ | ||
&& cd .. \ | ||
&& rm -rf CMake | ||
|
||
#################### | ||
# Clone Qt sources # | ||
#################### | ||
RUN git clone git://code.qt.io/qt/qt5.git qt6 \ | ||
&& cd qt6 \ | ||
&& git checkout v${QT_VERSION} \ | ||
&& perl init-repository --module-subset=${QT_MODULES} | ||
# Leave the qt6 folder in case you must look up sources later | ||
|
||
################# | ||
# Qt HOST build # | ||
################# | ||
RUN cd qthost-build \ | ||
&& ../qt6/configure -prefix $HOME/qt-host \ | ||
&& cmake --build . --parallel ${PARALLELIZATION} \ | ||
&& cmake --install . \ | ||
&& cd .. \ | ||
&& rm -rf qthost-build | ||
|
||
################### | ||
# Qt TARGET build # | ||
################### | ||
COPY --chown=qtpi:qtpi toolchain.cmake /home/qtpi/toolchain.cmake | ||
|
||
RUN cd qtpi-build \ | ||
&& ../qt6/configure -release -opengl es2 -nomake examples -nomake tests -qt-host-path $HOME/qt-host -extprefix $HOME/qt-raspi -prefix /usr/local/qt6 -device ${RPI_DEVICE} -device-option CROSS_COMPILE=aarch64-linux-gnu- -- -DCMAKE_TOOLCHAIN_FILE=$HOME/toolchain.cmake -DQT_FEATURE_xcb=ON -DFEATURE_xcb_xlib=ON -DQT_FEATURE_xlib=ON \ | ||
&& cmake --build . --parallel ${PARALLELIZATION} \ | ||
&& cmake --install . \ | ||
&& cd .. \ | ||
&& rm -rf qtpi-build | ||
|
||
######################################## | ||
# Syncing the Qt files back to the RPi # | ||
# is done in the docker container # | ||
######################################## | ||
COPY --chown=qtpi:qtpi _copyQtToRPi.sh /home/qtpi/copyQtToRPi.sh | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# Cross-compiling Qt 6 for the Raspberry Pi 3B (64-bit) | ||
|
||
## Preface | ||
|
||
This is a guide for cross-compiling Qt 6 for Raspberry Pi 3B (64-bit OS). | ||
To have a clean, defined, and reliable environment, I build Qt 6 using Docker. However, the build worked for me in a Virtual Machine, too. Just be sure to use a **Ubuntu 20.04 LTS (Focal Fossa)** VM if you don't use Docker since the build will fail with the latest Ubuntu version. | ||
|
||
This guide is heavily inspired by [1] and [2]. | ||
|
||
## Build | ||
|
||
In the following, your "computer" refers to as where you execute Docker (most Linux distributions will do), "host" refers to as the Docker environment (Ubuntu 20.04 LTS), and "target" refers to as the Raspberry Pi 3B (Raspbian 64-bit). | ||
|
||
### Raspberry Pi | ||
|
||
- Setup the Raspberry Pi using a 64-bit image of Raspbian (I used the *2022-04-04-raspios-bullseye-arm64.img.xz* image) from the official Raspberry Pi homepage). | ||
- Install the required software | ||
|
||
``` | ||
sudo apt update | ||
sudo apt full-upgrade | ||
sudo reboot | ||
sudo apt-get install libboost-all-dev libudev-dev libinput-dev libts-dev libmtdev-dev libjpeg-dev libfontconfig1-dev libssl-dev libdbus-1-dev libglib2.0-dev libxkbcommon-dev libegl1-mesa-dev libgbm-dev libgles2-mesa-dev mesa-common-dev libasound2-dev libpulse-dev gstreamer1.0-omx libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-alsa libvpx-dev libsrtp2-dev libsnappy-dev libnss3-dev "^libxcb.*" flex bison libxslt-dev ruby gperf libbz2-dev libcups2-dev libatkmm-1.6-dev libxi6 libxcomposite1 libfreetype6-dev libicu-dev libsqlite3-dev libxslt1-dev | ||
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libx11-dev freetds-dev libsqlite3-dev libpq-dev libiodbc2-dev firebird-dev libgst-dev libxext-dev libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync1 libxcb-sync-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxi-dev libdrm-dev libxcb-xinerama0 libxcb-xinerama0-dev libatspi2.0-dev libxcursor-dev libxcomposite-dev libxdamage-dev libxss-dev libxtst-dev libpci-dev libcap-dev libxrandr-dev libdirectfb-dev libaudio-dev libxkbcommon-x11-dev | ||
sudo mkdir /usr/local/qt6 | ||
``` | ||
|
||
- Enable the SSH service and make sure that you can connect from your computer to your RPi. | ||
|
||
### Computer | ||
|
||
First of all, install *rsync*, *ssh*, *git* and *docker* on your computer. I assume you have a basic understanding of Docker. | ||
|
||
Then, | ||
|
||
- Checkout this repository | ||
- Execute `./prepareSysroot.sh <RPI username> <RPI IP address>` | ||
This copies the Raspberry Pi's sysroot to your computer. Depending on your configuration, you may enter your RPi user's password three times. | ||
- Carefully look at the Dockerfile's "*PLEASE CUSTOMIZE THIS SECTION*" and edit it if necessary. | ||
- Execute `docker build --tag qtpi/qtpi:1.0 .` | ||
This will generate a Docker image while compiling and cross-compiling Qt. Since most of the process is done here, it will take some time. | ||
- When the last step succeeded, you now have the complete environment ready for compiling Qt applications for your host / your computer as well as your Raspberry Pi. | ||
- At last, you should run a Docker container from the newly generated Docker image: `docker run -it --rm qtpi/qtpi:1.0` | ||
From there, simply execute `~/copyQtToRPi.sh <RPI username> <RPI IP address>` | ||
to copy the Qt files to your Raspberry Pi. | ||
|
||
Inside the Docker container, the Qt host installation is located at **~/qt-host**, the Qt target installation at **~/qt-raspi** (see [1]). | ||
|
||
For compiling and executing sample applications on the host or target, see [2]. | ||
|
||
## References | ||
|
||
[1] https://wiki.qt.io/Cross-Compile_Qt_6_for_Raspberry_Pi | ||
|
||
[2] https://github.com/PhysicsX/QTonRaspberryPi/blob/main/README.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#!/bin/bash | ||
|
||
if [ "$#" -ne 2 ]; then | ||
echo "Parameter count does not match." | ||
exit -1 | ||
fi | ||
|
||
RPI_USERNAME=$1 | ||
RPI_IP_ADDR=$2 | ||
|
||
rsync -avz --rsync-path="sudo rsync" qt-raspi/* ${RPI_USERNAME}@${RPI_IP_ADDR}:/usr/local/qt6 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/bin/bash | ||
if [ "$#" -ne 2 ]; then | ||
echo "Parameter count does not match." | ||
exit -1 | ||
fi | ||
|
||
error() { | ||
echo "ERROR!" | ||
echo "COPYING THE SYSROOT DID NOT FINISH SUCCESSFULLY. PLEASE RETRY!" | ||
exit -1 | ||
} | ||
trap "error" ERR | ||
|
||
RPI_USERNAME=$1 | ||
RPI_IP_ADDR=$2 | ||
|
||
mkdir -p rpi-sysroot | ||
rm -rf rpi-sysroot/* | ||
|
||
rsync -avz --rsync-path="sudo rsync" --delete ${RPI_USERNAME}@${RPI_IP_ADDR}:/lib rpi-sysroot | ||
rsync -avz --rsync-path="sudo rsync" --delete ${RPI_USERNAME}@${RPI_IP_ADDR}:/usr/include rpi-sysroot/usr | ||
rsync -avz --rsync-path="sudo rsync" --delete ${RPI_USERNAME}@${RPI_IP_ADDR}:/usr/lib rpi-sysroot/usr | ||
|
||
echo "Success!" | ||
echo "Now go on with the docker image generation." | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
cmake_minimum_required(VERSION 3.18) | ||
include_guard(GLOBAL) | ||
|
||
set(CMAKE_SYSTEM_NAME Linux) | ||
set(CMAKE_SYSTEM_PROCESSOR arm) | ||
|
||
set(TARGET_SYSROOT /home/qtpi/rpi-sysroot) | ||
set(CMAKE_SYSROOT ${TARGET_SYSROOT}) | ||
|
||
set(ENV{PKG_CONFIG_PATH} $PKG_CONFIG_PATH:/usr/lib/aarch64-linux-gnu/pkgconfig) | ||
set(ENV{PKG_CONFIG_LIBDIR} /usr/lib/pkgconfig:/usr/share/pkgconfig/:${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig:${TARGET_SYSROOT}/usr/lib/pkgconfig) | ||
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT}) | ||
|
||
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc-9) | ||
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++-9) | ||
|
||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${TARGET_SYSROOT}/usr/include") | ||
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") | ||
|
||
set(QT_COMPILER_FLAGS "-march=armv8-a") | ||
set(QT_COMPILER_FLAGS_RELEASE "-O2 -pipe") | ||
set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed") | ||
|
||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) | ||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) | ||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) | ||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) | ||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) | ||
set(CMAKE_BUILD_RPATH ${TARGET_SYSROOT}) | ||
|
||
|
||
include(CMakeInitializeConfigs) | ||
|
||
function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING) | ||
if (_PREFIX MATCHES "CMAKE_(C|CXX|ASM)_FLAGS") | ||
set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT "${QT_COMPILER_FLAGS}") | ||
|
||
foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO) | ||
if (DEFINED QT_COMPILER_FLAGS_${config}) | ||
set(CMAKE_${CMAKE_MATCH_1}_FLAGS_${config}_INIT "${QT_COMPILER_FLAGS_${config}}") | ||
endif() | ||
endforeach() | ||
endif() | ||
|
||
|
||
if (_PREFIX MATCHES "CMAKE_(SHARED|MODULE|EXE)_LINKER_FLAGS") | ||
foreach (config SHARED MODULE EXE) | ||
set(CMAKE_${config}_LINKER_FLAGS_INIT "${QT_LINKER_FLAGS}") | ||
endforeach() | ||
endif() | ||
|
||
_cmake_initialize_per_config_variable(${ARGV}) | ||
endfunction() | ||
|
||
set(XCB_PATH_VARIABLE ${TARGET_SYSROOT}) | ||
|
||
set(GL_INC_DIR ${TARGET_SYSROOT}/usr/include) | ||
set(GL_LIB_DIR ${TARGET_SYSROOT}:${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/:${TARGET_SYSROOT}/usr:${TARGET_SYSROOT}/usr/lib) | ||
|
||
set(EGL_INCLUDE_DIR ${GL_INC_DIR}) | ||
set(EGL_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libEGL.so) | ||
|
||
set(OPENGL_INCLUDE_DIR ${GL_INC_DIR}) | ||
set(OPENGL_opengl_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libOpenGL.so) | ||
|
||
set(GLESv2_INCLUDE_DIR ${GL_INC_DIR}) | ||
set(GLIB_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libGLESv2.so) | ||
|
||
set(GLESv2_INCLUDE_DIR ${GL_INC_DIR}) | ||
set(GLESv2_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libGLESv2.so) | ||
|
||
set(gbm_INCLUDE_DIR ${GL_INC_DIR}) | ||
set(gbm_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libgbm.so) | ||
|
||
set(Libdrm_INCLUDE_DIR ${GL_INC_DIR}) | ||
set(Libdrm_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libdrm.so) | ||
|
||
set(XCB_XCB_INCLUDE_DIR ${GL_INC_DIR}) | ||
set(XCB_XCB_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libxcb.so) | ||
|