This is part of a series of posts on compiling a custom version of Qt5 in order
to develop for both amd64 and a Raspberry Pi.
I split building Qt5 for armhf development in two parts: one cross-build
environment to be installed on
amd64 develpment systems, and a runtime part
to be installed on the target
armhf hardware.
Building a Qt5 cross-building environment builds a mix of
armhf and
amd64
binares: the amd64 tools to use for cross-building, like
moc,
qmake,
plugins for Qt Creator, and so on; armhf headers and libraries to use at
cross-build time; armhf shared libraries to use at runtime.
The procedure I came up with builds a devel package for
amd64 development
machines, which contains everything, and a second package that extracts from it
only what is needed at runtime.
The cross-build environment is coinstallable both with the version of Qt
distributed with Debian, and with the
amd64 custom Qt development
package.
The current build is sadly using
-skip qtwebengine, because I have had no
success so far getting QtWebEngine to compile as part of a cross-build Qt
setup (the last road bump I can't overcome is
nss and nspr not being
coinstallable on amd64 and armhf, while both seem to be needed for it).
The resulting packaging is at
https://github.com/Truelite/qt5custom.
Set up sources
Open the source tarball, and add the amd64 packaging:
tar axf qt-everywhere-src-5.15.0.tar.xz
cp -a debian-cross qt-everywhere-src-5.15.0/debian
If needed, install the Qt license:
cp qt-license.txt ~/.qt-license
If debugging information are not needed in
armhf development, remove
--no-strip from
./configure invocation in the
rules file, to build
significantly smaller
.deb packages.
Install build dependencies
Install cross-compilers:
dpkg --add-architecture armhf
apt install crossbuild-essential-armhf
You can use
apt build-dep to install dependencies manually:
cd qt-everywhere-src-5.15.0
apt build-dep .
apt -a armhf build-dep .
Alternatively, you can create installable
.deb metapackages that depends on
the build dependencies:
apt install devscripts
mk-build-deps --host-arch amd64 debian-cross/control
mk-build-deps --host-arch armhf debian-cross/control
apt -f install qt-everywhere-cross-build-deps_5.15.0-1_amd64.deb qt-everywhere-cross-cross-build-deps_5.15.0-1_armhf.deb
Note that there are two sets of dependencies: one of
amd64 packages, and one
of
armhf packages.
Building the cross-build environment
After installing the build dependencies, you can build like this:
cd qt-everywhere-src-5.15.0
fakeroot debian/rules binary
In
debian/rules you can configure
NUMJOBS with the number of available
CPUs in the machine, to have parallel builds.
This will build a package with the cross-build development environment for
amd64, called
qtbase5custom-armhf-dev
Building the runtime environment
To generate the runtime package for
armhf, one needs to have the cross-build
package (
qtbase5custom-armhf-dev) installed in the system together with its
build dependencies.
At that point, the
armhf runtime package can be built using the
debian-armhf directory without further sources:
apt install crossbuild-essential-armhf debhelper qtbase5custom-armhf-dev*_amd64.deb qt-everywhere-src-cross-build-deps*_armhf.deb
mkdir runtime
cp -a debian-armhf runtime/debian
cd runtime
dpkg-buildpackage -a armhf
Building the runtime environment generates:
- a
libqt5custom package for armhf, installable on the target devices,
containing the runtime Qt libraries and depending on the packages that they
need to run;
- a
libqt5custom-dbgym package for armhf with debugging symbols, to use for
debugging on the target hardware.
If, while generating the cross-build environment,
--no-strip was removed, the
libqtcustom-dbgsym package with debugging symbols will not be generated.
Using the cross-build environment
These install their content in
/opt, and are coninstallable with the version
of Qt distributed in Debian, and with the
custom Qt packages for amd64.
One needs to be careful not to create programs that link, either directly or
indirectly, with more than one of these coinstalled Qt, because the in memory
layout of objects could be different and incompatible, causing unexpected
results.
Selecting which Qt version to use: qtchooser
These Qt custom packages integrate with
qtchooser to select the version of Qt
to use at compile time.
qtchooser --list-versions lists available versions. One can choose what to
use by exporting
QT_SELECT:
# apt install qtchooser qt5-qmake qt5-default
$ qtchooser --list-versions
4
5
qt4-x86_64-linux-gnu
qt4
qt5-x86_64-linux-gnu
qt5
qt5custom-x86_64-linux-gnu
qt5custom
qt5custom-armhf-x86_64-linux-gnu
qt5custom-armhf
$ qmake --version
QMake version 3.1
Using Qt version 5.11.3 in /usr/lib/x86_64-linux-gnu
$ export QT_SELECT=qt5custom-armhf
$ qmake --version
QMake version 3.1
Using Qt version 5.15.0 in /opt/qt5custom-armhf/lib
Cross-building software using custom Qt
One just needs to export
QT_SELECT=qt5custom-armhf in the environment, then
proceed to build normally:
export QT_SELECT=qt5custom-armhf
fakeroot ./debian/rules clean binary
Or:
export QT_SELECT=qt5custom-armhf
qmake file.pro
If switching from one Qt to another, it is possible that the makefiles created
by one qmake are not working well with the other. In that case, one can just
remove them and regenerate them.
The build result is ready to be copied into, and run in, the target
armhf
device.