Why Qt?

Qt is the defacto standard for cross-platform UI interfaces using C++. Of course, someone can argue that it is heavy to deploy, carries around a lot of legacy stuff, etc. Nevertheless, I would recommend using it even when your only use case is to open up only a blank window where you do all the rendering yourself since the framework has more than 20 years of experience in opening blank windows on many different platforms.

The following demo shows an application using Qt:

Qt5 and Bazel

Assuming you want to build a Qt5 project using Bazel: Luckily someone did already prepare some Bazel rules for this for you: bazel_rules_qt. Those rules target Qt5. Unfortunately, those rules have a few drawbacks (which can be seen also as an advantage depending on your mindset). One of the drawbacks of those rules is that they have the requirement of a pre-installed Qt version. That is in my opinion a bad choice, very annoying and not as hermetic as one might wish. You can see this issue on the corresponding bazel_rules_qt GitHub repository. The rules are tested on three different CI environments and in one of those it is currently failing (currently, the repo has 48 commits on the master branch - might change in the future and the problem might be fixed). Why does it fail? Because you have to install the Qt on each CI environment individually and for some reason on one of them it does not work. As a developer, you have also to install Qt on your local development machine. Everywhere you want to use those rules you have to make sure to preinstall Qt. As a developer, you should try to deliver the best build experience which means a bazel build should work out of the box without forcing someone to download and install Qt.

bazel_rules_qt in practice

uic issue

I installed on my Windows 10 x64 (Version 20H2) system Qt via:

python -m aqt install --outputdir C:\Qt 5.9.9 windows desktop win64_msvc2017_64

When doing

git clone https://github.com/justbuchanan/bazel_rules_qt.git
cd bazel_rules_qt
bazel build //...

I got the following error message:

ERROR: G:/dev/bazel_rules_qt/tests/qt_ui_library/BUILD:3:14: Action tests/qt_ui_library/ui_mainwindow.h failed: (Exit -1): uic failed: error executing command uic tests/qt_ui_library/mainwindow.ui -o bazel-out/x64_windows-fastbuild/bin/tests/qt_ui_library/ui_mainwindow.h. Note: Remote connection/protocol failed with: execution failed
Action failed to execute: java.io.IOException: ERROR: src/main/native/windows/process.cc(202): CreateProcessW("uic" tests/qt_ui_library/mainwindow.ui -o bazel-out/x64_windows-fastbuild/bin/tests/qt_ui_library/ui_mainwindow.h): Das System kann die angegebene Datei nicht finden.
(error: 2)

You need to add uic to the PATH environment variable. This usually happens by the standard Qt installer, but aqt does this not by default (maybe there is an option in aqt to do this).

Platform issue

When trying to start a Qt application using bazel run on Windows by installing Qt via the aqt Qt gives you the following errors message:

qt.qpa.plugin: Could not find the Qt platform plugin "windows" in ""
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

The workaround here is to copy to the Bazel Cache the platform folder deliverd by Qt.

Qt 6 and Bazel

I started an experiment to test if there is an easy way to get around installing Qt. I decided also to go for Qt6 (6.1.0) for this test. Since I do not want to repeat myself you can read everything relevant on my repo on GitHub: https://github.com/Vertexwahn/rules_qt6

To summarize, my experiment seems to be the right way to go. Anyways I face still some issues that should be fixed before this can go productive.

Summary

The current Open Source solutions to use Bazel and Qt have still some issues. You can either live with those problems or build on top of the existing solutions and contribute a better solution.