User:Jimis
Notes on cross-compiling Qt 6.5 (including all submodules with examples) for both armhf and aarch64 architectures for Raspberry Pi OS
- We'll be using Clang-13 as the compiler and lld-13 as the linker. This is mostly to avoid building a toolchain, which would be required with GCC and binutils.
- We are copying the sysroot from a 64-bit installation of Raspberry Pi OS. However it will contain both 32-bit and 64-bit libraries, installed according to the Debian Multiarch HOWTO.
Host build
Cross-compiling Qt-6 requires that we perform a host build first in order to have tools like
moc
and
lupdate
available for the cross-build.
- Install the packages for the compiler and the linker, depending on the system. For OpenSUSE-Tumbleweed I needed to install
llvm13-libclang13 clang13-devel lld13
NOTE: Avoid having multiple versions of Clang installed (it caused linkage problems obscure enough to be detected only when the
lupdate
binaries were segfaulting!)
- Configure the host build. I use developer-build to not need installation.
cd $HOME/qt6-host-developer-build $SRC_DIR/configure -developer-build -linker lld -nomake tests -nomake examples \ -- -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13
Preparing the sysroot of Raspberry Pi OS with 32-bit and 64-bit libraries
To cross-compile for a system, you need to have all the system libraries and header files of the target copied into the host. This is called a sysroot.
To prepare that, the best way is to try compiling on the target itself. You don't need to actually complete the compilation, but at least the configuration step should be successful.
After lots of trial and errors, these are the packages that I installed on Raspberry Pi OS:
LIBDEPS="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\ libdrm-dev libdrm-etnaviv1 libdrm-freedreno1 libdrm-tegra0 libgl-dev libglx-dev mesa-common-dev\ libegl-dev libegl1-mesa-dev libgbm-dev libgles-dev libgles2-mesa-dev libglvnd-dev libopengl-dev libopengl0 libvulkan-dev mesa-vulkan-drivers\ libxcb-cursor-dev libxcursor-dev\ libssl-dev libjpeg-dev" sudo apt update sudo dpkg --add-architecture armhf # Install 64-bit libraries sudo apt install $LIBDEPS # Install 32-bit libraries sudo apt install crossbuild-essential-armhf echo $LIBDEPS | sed -E -e 's/ +|$/:armhf /g' | xargs sudo apt install
WARNING: do not install
clang-*-dev
on the target, it causes linking problems on tools like
lupdate
and is not required for a successful build.
Copy the sysroot to the host
On the x86_64 host:
SYSROOT=$HOME/sysroot-RPiOS/ rsync --info=progress2 -ar --copy-unsafe-links --delete -z --zc lz4 pi@rasbperry-pi:usr $SYSROOT/
This will copy all of
/usr
into the $SYSROOT directory, using fast compression for quicker transfer over the network. It will also replace symlinks that escape the directory with the actual file contents.
A workaround is needed for clang and ninja to avoid rebuilding everything on every rebuild attempt:
ln -s usr/lib $SYSROOT/lib ln -s usr/include $SYSROOT/include ln -s usr/arm-linux-gnueabihf $SYSROOT/arm-linux-gnueabihf