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.
The problem
While testing the cross-compiler, we noticed that the designer
library was
not being built.
The designer library is needed to build designer plugins, which allow loading,
dynamically at runtime, .ui
interface files that use custom widgets.
The error the customer got at runtime is: QFormBuilder was unable to create a custom widget of the class '…'; defaulting to base class 'QWidget'.
The library with the custom widget implementation was correctly linked, and
indeed the same custom widget was used by the application in other parts of its
interface not loaded via .ui
files.
It turns out that it is not sufficient, and to load custom widgets automatically, QUiLoader wants to read their metadata from plugin libraries containing objects that implement the QDesignerCustomWidgetInterface interface.
Sadly, building such a library requires using QT += designer
, and the
designer
library, that was not being built by Qt5's build system. This looks
very much like a Qt5 bug.
A work around would be to subclass
QUiLoader extending
createWidget
to teach it how to create the custom widgets we need.
Unfortunately, the customer has many custom widgets.
The investigation
To find out why designer was not being built, I added -d
to the qmake
invocation at the end of qtbase/configure
, and trawled through the 3.1G build
output.
The needle in the haystack seems to be here:
DEBUG 1: /home/build/armhf/qt-everywhere-src-5.15.0/qttools/src/designer/src/src.pro:18: SUBDIRS := uiplugin uitools lib components designer plugins DEBUG 1: /home/build/armhf/qt-everywhere-src-5.15.0/qttools/src/designer/src/src.pro:23: calling qtNomakeTools(lib components designer plugins)
As far as I can understand, qtNomakeTools
seems to be intended to disable
building those components if QT_BUILD_PARTS
doesn't contain tools
. For
cross-building, QT_BUILD_PARTS
is libs examples
, so designer
does not get
built.
However, designer
contains the library part needed for
QDesignerCustomWidgetInterface
and that really needs to be built. I assume that part should really be built as
part of libs
, not tools
.
The fixes/workarounds
I tried removing designer
from the qtNomakeTools
invocation at
qttools/src/designer/src/src.pro:23
, to see if
qttools/src/designer/src/designer/
would get built.
It did get built, but then build failed with designer/src/designer
and
designer/src/uitools
both claiming the designer
plugin.
I tried editing qttools/src/designer/src/uitools/uitools.pro
not to claim the
designer
plugin when tools
is not a build part.
I added the tweaks to the Qt5 build system as debian/patches.
2 hours of build time later...
make check
is broken:
make[6]: Leaving directory '/home/build/armhf/qt-everywhere-src-5.15.0/qttools/src/designer/src/uitools' make[5]: *** No rule to make target 'sub-components-check', needed by 'sub-designer-check'. Stop.
But since make check
doesn't do anything in this build, we can simply
override dh_auto_test
to skip that step.
Finally, this patch builds a new executable, of an architecture that makes dh_shlibdeps
struggle:
dpkg-shlibdeps: error: cannot find library libQt5DesignerComponentssystem.so.5 needed by debian/qtbase5system-armhf-dev/opt/qt5system-armhf/bin/designer (ELF format: 'elf32-little' abi: '0101002800000000'; RPATH: '') dpkg-shlibdeps: error: cannot find library libQt5Designersystem.so.5 needed by debian/qtbase5system-armhf-dev/opt/qt5system-armhf/bin/designer (ELF format: 'elf32-little' abi: '0101002800000000'; RPATH: '') …
And we can just skip running dh_shlibdeps
on the designer
executable.
The result is in the qt5custom git repository.