Docker Image for Qt Development and Continuous Integration on x64 and arm64
NOTE: this project now also includes Android builds of Qt. Refer to updated articles to know more.
It happens from time to time that I would benefit from having a simple Docker image with all the deps needed to build and run Qt apps on specific Qt versions. For instance, I may need to build some binary on Mac OS for Linux or I may need to have an image for some continuous integration system.
I had a look around and there are quite a few projects: some do not provide an arm build, some rely on the Qt official installer, that is a bit tricky to automate and tends to change often, some rely on distro-provided packages, that do not provide every version etc… I’d prefer to have a solid build procedure to build images for any Qt version I want. Also, my CI system runs on arm64, so I’d need a multiarch image, and therefore two different Qt builds. I thought it could be simpler to just build Qt on-the-fly in a Dockerfile but… turned out it is not that simple.
At first I created a Dockerfile to:
- install all the needed deps on Ubuntu focal;
- download Qt sources;
This proved to be a simple solution, but building Qt for arm on qemu or building on arm took way too much. So I though of a different solution. I created two images:
- carlonluca/qt-builder is an image with the proper tools to build Qt for x64 and cross-build Qt for arm64;
- carlonluca/qt-dev is an image with the proper tools to build and run Qt apps.
With the first image Qt can be built and cross-built in a few hours for both x64 and arm64, directly on x64. The builds are then injected into a second multiarch image. This is way faster than building on qemu.
Only one problem left: in Qt 5, crossbuilding Qt results in some Qt tools like qmake to be built for the host arch, which is unacceptable in this case. So, in the second image, a build of the only qtbase module is also needed to build arm64 binaries. Qt 6 works differently instead.
The code to build Qt and all the images are available at: https://github.com/carlonluca/docker-qt.
The image to build Qt is available at: https://hub.docker.com/repository/docker/carlonluca/qt-builder.
The image to use for app development is available at: https://hub.docker.com/repository/docker/carlonluca/qt-dev.
Continuous Integration on GitLab with Qt
An example of usage of the dev image is running continuous integration and unit tests on your code on Jenkins or GitLab. For example, I can now run my unit tests in my GitLab instance running on Raspberry Pi 4 with the following code (taken from my project https://github.com/carlonluca/lqobjectserializer):
variables: GIT_SUBMODULE_STRATEGY: recursive stages: - test_qt5 - test_qt6 Test_qt5: stage: test_qt5 image: name: "carlonluca/qt-dev:5.15.2" entrypoint: [""] script: - cd LQObjectSerializerTest - mkdir build - cd build - cmake ../qt5 - make - ./LQObjectSerializerTest - ./LGithubTestCase Test_qt6: stage: test_qt6 image: name: "carlonluca/qt-dev:6.1.2" entrypoint: [""] script: - cd LQObjectSerializerTest - mkdir build - cd build - cmake ../qt6 - make - ./LQObjectSerializerTest - ./LGithubTestCase
These images are still experimental though.
Have fun 😉