via Docker
Creating cross-compilation toolchains for Qt targeting other architectures takes some time. We automated it with a Dockerfile, so that we can cross-compile Qt6 apps to OrangePi devices without first spending half a day getting everything setup correctly.
This article covers how to use that Dockerfile. Previously, we shared a Dockerfile for cross-compiling a static Qt5 targeting Windows.
You have:
Orangepizero2w_1.0.0_ubuntu_jammy_server_linux6.1.31.7z
651760c54dd6af2ecfad9f9b8d419411783032965a93f4703d73a6fdce2ecb04
MODULES=...
Our setup script does not fetch files from arbitrary URLs, nor does it add a custom
apt mirror. See pi_requirements.sh
and the Dockerfile
to verify what is installed.
There are 2 things you will need to do in order to get started:
Clone our repository to get started:
git clone https://github.com/kroketio/qt6-to-orangepi-zero2-3.git
cd qt6-to-orangepi-zero2-3.git
During the first step, Docker needs to connect to the device in order to do some setup and fetch the device's sysroot. You can
tell Docker the IP address of the device via PI_HOST=...
.
docker build -f Dockerfile --tag qt6:orangepizero2-3 \
--build-arg THREADS=8 PI_HOST=192.168.1.12 .
Available arguments:
Name | Description |
---|---|
THREADS |
Compilation threads passed to make -j . Default 8 |
MODULES |
A list of Qt6 modules that will be passed to ./init-repository . Comma separated. |
PI_HOST |
The IP address of the OrangePi device. |
PI_USER |
The username for the OrangePi device. Default is orangepi . |
PI_PASSWORD |
The password for the OrangePi device. Default is orangepi . |
This command runs for ~25min because Qt is installed twice (x86_64, ARM), as well as copying back and forth some files. Grab some coffee.
We now have a Docker image available under tag qt6:orangepizero2-3
. We can use this image to
cross-compile. As an example, we'll compile a QtQuick program from the Qt6 examples. This way we can confirm
that the rendering is handled by the GPU.
cd ~/
git clone https://code.qt.io/qt/qtdoc.git --depth 1 --branch 6.6.0
cp -R qtdoc/examples/demos/rssnews .
cd rssnews
# configure step, this is where you'll put your CMake definitions -DFOO=BAR for your own programs
docker run --rm -it -v $PWD:/app -w /app qt6:orangepizero2-3 bash -c \
'qt-cmake -Bbuild -DCMAKE_PREFIX_PATH=/z2w/target/ .'
The output should look something like this:
-- The CXX compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/aarch64-linux-gnu-g++-11 - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Performing Test HAVE_STDATOMIC
-- Performing Test HAVE_STDATOMIC - Success
-- Found WrapAtomic: TRUE
-- Performing Test HAVE_EGL
-- Performing Test HAVE_EGL - Success
-- Found EGL: /z2w/sysroot/usr/include (found version "1.5")
-- Performing Test HAVE_GLESv2
-- Performing Test HAVE_GLESv2 - Success
-- Found GLESv2: /z2w/sysroot/usr/include
-- Found XKB: /z2w/sysroot/usr/lib/aarch64-linux-gnu/libxkbcommon.so (found suitable version "1.4.0", minimum required is "0.5.0")
-- Configuring done
-- Generating done
-- Build files have been written to: /app/build
Compile the program:
# compile step
docker run --rm -it -v $PWD:/app -w /app qt6:orangepizero2-3 bash -c 'make -Cbuild -j8'
The output should look something like this:
[...]
[ 71%] Building CXX object CMakeFiles/rssnews.dir/main.cpp.o
[ 71%] Building CXX object CMakeFiles/rssnews.dir/rssnews_autogen/mocs_compilation.cpp.o
[ 85%] Building CXX object CMakeFiles/rssnews.dir/build/.rcc/qrc_rssnews.cpp.o
[100%] Linking CXX executable rssnews
make[2]: Leaving directory '/app/build'
[100%] Built target rssnews
make[1]: Leaving directory '/app/build'
make: Leaving directory '/app/build'
$ file build/rssnews
build/rssnews: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=f8069f385fd86e8cdc9018422540ece909d8ceff, for GNU/Linux 3.7.0, not stripped
Resulting in binary build/rssnews
. Finally, transfer this to the device:
scp build/rssnews root@192.168.1.12:
And execute it:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/qt6/lib/ ./rssnews -platform eglfs
Note LD_LIBRARY_PATH
to point to Qt6, and also -platform eglfs
because we are on Ubuntu server without a desktop environment.
Confirm that scrolling happens smoothly, as low FPS may indicate you forgot to turn on the GPU
via the orangepi-config
system utility (System -> Hardware -> GPU
+ reboot). The GPU on these devices are
disabled by default.
^ Running on a 1920x1080 touch display.
For additional information about the Dockerfile, an overview of the steps:
git clone
the Qt6 repo + any Qt modules to includeqt6/qtbase/mkspecs/devices/
)/usr/local/qt6/