Build Qt on Linux (Debian)
Introduction
We will build the latest publicly available Qt5 library, 5.15.19, with Qt WebEngine on Debian Bookworm.
There are several reasons to build Qt yourself on Debian. First, even the repositories on the current Debian 13 (Trixie) only ship Qt5.15.15. Second, distribution builds do not include proprietary codecs like mp4.
Build Qt Lib
This process is carried out in one step. As in most other tutorials, we first build the Qt library and skip Qt WebEngine. The core library is a piece of cake compared to QWebEngine. Keeping the two parts separate makes troubleshooting much easier if something goes wrong.
Requirements for Qt-Lib
- Virtualization. I use Qemu-KVM and Parallels on Mac for ARM64.
- Debian 12 (Bookworm): Trixie also works, but since I like to build compatible AppImages, oldstable is the better choice.
- Qt5.15.19 from the Qt Archive
- At least 20 GB of free disk space and 8 GB of RAM for the Qt library build. QWebEngine needs considerably more, see below.
Preparing the OS
sudo apt install build-essential libssl-dev libgl1-mesa-dev libglu1-mesa-dev \
libxkbcommon-dev libxkbcommon-x11-dev '^libxcb.*-dev' libx11-xcb-dev \
libxrender-dev libxi-dev libfontconfig1-dev libfreetype6-dev \
libasound2-dev libcups2-dev libxtst-dev libxss1 libdrm-dev \
libnss3-dev libnspr4-dev libdbus-1-dev libatspi2.0-dev \
libclang-dev llvm python3 perl bison flex gperf ninja-build cmake \
nodejs pkg-config
Package explanations
- The first package set covers the build tools (build-essential, bison, flex, gperf), Python for the Qt build scripts, and libraries for audio (libasound2), printing (libcups2), and security certificates (libnss3). nodejs is needed later for QWebEngine.
- The second package set provides the full XCB and X11 development headers. Qt needs these to compile the platform abstraction (QPA) for X11. If any header is missing, configure or make will fail at exactly that point.
tar xvf qt-everywhere-opensource-src-5.15.19.tar.xz
I suggest creating a Qt directory and moving the extracted folder into Src.
mkdir -p Qt/5.15.19/
mv qt-everywhere-opensource-src-5.15.19 Qt/5.15.19/Src
This layout (Qt/Version/Src) matches what the official Qt installer uses. It makes it easier to keep several Qt versions side by side and to separate build output from source.
Build Steps for Qt-Lib
Open a terminal, create a shadow directory, and enter it.
Using a shadow build directory is very helpful when building Qt or C++ software in general. It keeps source code separate from build artifacts, allows multiple build configurations side by side, simplifies cleanup, and offers other advantages.
mkdir build_qt
cd build_qt
Now call the configure script from the source directory.
configure -c++std c++17 -opensource -confirm-license -nomake tests -nomake examples \
-ssl -openssl-runtime -make libs \
-prefix path/to/qt/5.15.19/clang_64 \
-skip qttranslations \
-skip qtwebengine \
-skip qtgamepad \
-skip qtdatavis3d \
-skip qtcharts \
-skip qtlottie \
-skip qtserialport \
-skip qt3d \
-skip qtscript \
-skip qtlocation \
-skip qtdoc \
-skip qtpurchasing \
-skip qtvirtualkeyboard \
-skip qtspeech
Configure Explanations
- -c++std c++17: Forces the C++17 standard for the build. garlic-player uses language features newer than Qt’s default standard.
- -opensource -confirm-license: Accepts the open source license non-interactively, required for automated builds.
- -nomake tests -nomake examples: Saves considerable time, since neither the Qt test suite nor the example programs are built.
- -ssl -openssl-runtime: Qt links against OpenSSL at runtime instead of bundling its own TLS implementation. The system library must be available at runtime.
- -make libs: Builds only the libraries of each module, not the tools or examples.
- -prefix path/to/qt/5.15.19/clang_64: Defines where
make installwill place the resulting Qt binaries. - -skip …: ActiveQt, SerialPort, Qt3D, and the other listed modules are not needed for garlic-player. Each skipped module reduces build time and dependencies. qtwebengine is skipped here on purpose, since it is built separately in the next section.
This step builds qmake and a few other base tools.
If something is missing or fails, configure will print a more or less detailed notice. If everything completes fine, continue to the next step.
Start make
Call make with multicore support. Increase the number if you have more cores and memory available.
make -j16
The number after -j sets the number of parallel compile jobs. A rough rule of thumb is one job per CPU core, limited by available RAM, since each compiler process can use several hundred MB up to a few GB of memory. On a typical 8-core machine with 16 GB RAM, this step takes roughly 30 to 60 minutes.
If everything goes well, install the compiled library into the -prefix directory.
make install
This also takes a few minutes.
Verify the installation
path/to/qt/5.15.19/clang_64/bin/qmake -v
This should print the Qt version and the compiler it was built with. If the command is not found, add the bin folder to your PATH:
export PATH=path/to/qt/5.15.19/clang_64/bin:$PATH
Or add this line to your ~/.bashrc or ~/.profile to make it permanent.
Requirements and Preparation for the Pain Queen QWebengine
Some additional software is required.
Install:
sudo apt install libxtst-dev libxcursor-dev libxcomposite-dev libxdamage-dev \
libxrandr-dev libpulse-dev libudev-dev libevent-dev libminizip-dev libxrandr-dev\
libwebp-dev libjsoncpp-dev libavcodec-dev libavformat-dev libavutil-dev libxdamage-dev \
libvpx-dev libsrtp2-dev libsnappy-dev libre2-dev libdrm-dev libxcomposite-dev libxcursor-dev
Package explanations QWebEngine is based on Chromium. Accordingly, these packages provide development headers for system services Chromium accesses: windowing and input (libxcursor, libxcomposite, libxrandr, libxtst), audio (libpulse, libasound2), hardware access (libudev, libpci, libegl1-mesa), and D-Bus for inter-process communication. gperf, bison, and nodejs are needed by Chromium’s own code generators.
Resources: Building QWebEngine is significantly more demanding than the Qt library. Expect to need at least 16 GB of RAM (32 GB recommended) and 50 to 60 GB of free disk space for the build directory alone. On lower-memory systems, reduce the number of parallel jobs to avoid the build crashing due to out-of-memory errors.
qmake path/to/qt-src/qtwebengine/qtwebengine.pro -- -no-webengine-jumbo-build -no-feature-webengine-system-ninja -proprietary-codecs
export NINJAFLAGS=-j16 # limit this if get crashes about memory exceeds
make -j16
Parameter explanations
- -no-webengine-jumbo-build: A jumbo build combines several C++ files into one large file before compiling, to save build time. This does not work reliably on every system, so it is disabled here. If you want shorter build times, you can test whether a jumbo build completes without issues on your machine.
- -no-feature-webengine-system-ninja: Uses the ninja binary bundled with the QWebEngine source instead of a separately installed version, avoiding version conflicts.
- -proprietary-codecs: Enables proprietary media codecs such as AAC, H.264, and MP3, which are not included in the standard build. Without this flag, QWebEngine cannot play back content using these formats.
- NINJAFLAGS=-j16: Limits the number of parallel Ninja jobs. Since a Chromium build is very memory-hungry, too many parallel jobs can exhaust available RAM and crash the build. Lower this value if you run into memory issues.
One cup of coffee will not be enough. Have something to eat ready, this build can take several hours depending on your hardware, comparable to 4 to 6 hours on a mid-range 8-core machine.
Once the build finishes, install the compiled libraries as well:
make install
Compile Linux ARM64
The build process for Linux ARM64 is identical to Linux x64. All commands, configure parameters, and package names stay the same, the only difference is that the build runs on an ARM64 environment (for example via Qemu-KVM or Parallels on Mac, as mentioned above under Requirements). A separate build run per target architecture is still required, since Qt and QWebEngine produce architecture-specific binaries. This describes native compilation on ARM64 hardware or a VM, not cross-compiling from an x64 host.
Troubleshooting
- configure fails with a missing header: Check the error message for the package name and install it, then re-run configure from the same shadow directory.
- make fails with “out of memory” or the process gets killed: Reduce the number of parallel jobs (
-jNandNINJAFLAGS) and try again. - qmake command not found after installation: The bin directory of the -prefix path is not in your PATH, see the verification step above.
- QWebEngine build stalls or crashes near the end: Usually caused by insufficient RAM. Close other applications, lower NINJAFLAGS, or add swap space.
- Linker errors about OpenSSL: Confirm that the -ssl -openssl-runtime configure flags were used and that the OpenSSL development package is installed.
Share Your Thoughts
If you have any ideas, suggestions for improvement, feel free to reach out. You can share your feedback by email or by giving my project a star on GitHub.