How to Compile Qt from Source Code on Linux

How to Compile Qt from Source Code on Linux

By Jeff Tranter

Happy New Year!

In previous blogs I have covered installing Qt and Qt Creator on Windows and on Linux using the Qt installer and pre-built binaries. In this post, aimed at developers with novice-level Qt skills, we'll look at how you can build Qt yourself from source code.

Rationale

Why would you want to build Qt from source? While the downloadable pre-compiled binaries are convenient and save time, you may want to build Qt using a different configuration from that provided by The Qt Company. You may, for example, want to enable or disable different options or modules to match the requirements of your platform and application.

Or, you may need to build Qt against a different C++ compiler or run-time library. If you want to test an Alpha release of Qt, these are typically only provided as source code. You may also want to build Qt from a development version in the git repository, which only provides source code, or with a specific patch or other change that you require.

Basic Steps

Here are the basic steps for building Qt on any platform:

  1. Download the source code archive.
  2. Extract the source code into a working directory.
  3. Install the required development packages and other build dependencies for Qt.
  4. Configure Qt for the desired options and ensure that all dependencies are met.
  5. Build Qt (i.e. compile and link).
  6. Install and test the new version.

ICS recommends Qt Commercial for support, maximum IP protection, and because we all should support the community. (The Qt Company offers a free 30-trial version of Qt Commercial.)

Let's walk through the process for doing this on a Linux desktop system showing in detail the commands used to perform all the steps. We will be building Qt natively to run on the desktop rather than as a cross-compiled version for developing code for an embedded target system.

Ubuntu Example

For this example will use 64-bit Ubuntu desktop Linux version 16.04.1 LTS. Ubuntu is one of the most popular desktop Linux distributions and this is the most recent LTS (long term support) release. If you are using another Linux distribution, the build process will be similar but some of the specific commands will be different.

We will build Qt version 5.7.1 which is the "recommended" Qt version at the time of writing. Other versions of Qt will follow a similar process.

Step 1. Download the source code archive

I find the easiest way to download Qt version is to browse to the download server and navigate to the appropriate directory. In our case we want to select http://download.qt.io/official_releases/qt/5.7/5.7.1/single to access the official source code release for Qt 5.7.1 as a single archive file.

You will see several files there that offer the release in different archive formats. We'll select qt-everywhere-opensource-src-5.7.1.tar.gz, which is suitable for Linux systems. Some of the other formats (like 7z) are smaller because they use an archive format with better compression, but use less-commonly available archiving tools that you may not have installed on your system. 

If you want to download the file directly from the Linux command line, you can use:

% wget http://download.qt.io/official_releases/qt/5.7/5.7.1/single/qt-everywhere-opensource-src-5.7.1.tar.gz

The file is 422 megabytes in size. The Qt download site will attempt to use a download mirror server that is geographically close to you, so download speed should be quite good, usually limited only by the speed of your Internet connection.

If you want to verify that the download was not corrupted, you can generate an MD5 checksum of the file after you download it:

% md5sum qt-everywhere-opensource-src-5.7.1.tar.gz
031fb3fd0c3cc0f1082644492683f18d  qt-everywhere-opensource-src-5.7.1.tar.gz

The file md5sums.txt in the same directory on the download server lists the correct checksums for each file so you can verify it against what you downloaded.

Step 2. Extract the source code into a working directory

The next step is to extract the files from the source archive. If you downloaded the tar.gz file above, then this command will work:

% tar xzf qt-everywhere-opensource-src-5.7.1.tar.gz

The files will be extracted into a directory which you can now cd to:

% cd qt-everywhere-opensource-src-5.7.1

Step 3. Install the required development packages and other build dependencies for Qt

Qt is dependent on a number of tools and libraries. Some, like a C++ compiler, are required. Others are optional and Qt will make use of them if present and disable certain features if absent. This will occur when Qt is configured.

Figuring out all of the correct dependencies to build Qt is often the hardest part of the build process. While the dependencies are typically all available as standard packages for your Linux distribution, it can take some time to identify and install all of the packages that are needed, especially on a clean system where you have never built Qt before.

On Ubuntu Linux the command line tool to install packages is apt-get. For Ubuntu 16.04.1 these were the packages that I found were needed to build Qt will all of the options I wanted:

% sudo apt-get install bison build-essential flex gperf ibgstreamer-plugins-base0.10-dev libasound2-dev libatkmm-1.6-dev libbz2-dev libcap-dev libcups2-dev libdrm-dev libegl1-mesa-dev libfontconfig1-dev libfreetype6-dev libgcrypt11-dev libglu1-mesa-dev libgstreamer0.10-dev libicu-dev libnss3-dev libpci-dev libpulse-dev libssl-dev libudev-dev libx11-dev libx11-xcb-dev libxcb-composite0 libxcb-composite0-dev libxcb-cursor-dev libxcb-cursor0 libxcb-damage0 libxcb-damage0-dev libxcb-dpms0 libxcb-dpms0-dev libxcb-dri2-0 libxcb-dri2-0-dev libxcb-dri3-0 libxcb-dri3-dev libxcb-ewmh-dev libxcb-ewmh2 libxcb-glx0 libxcb-glx0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-image0 libxcb-image0-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-present-dev libxcb-present0 libxcb-randr0 libxcb-randr0-dev libxcb-record0 libxcb-record0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-render0 libxcb-render0-dev libxcb-res0 libxcb-res0-dev libxcb-screensaver0 libxcb-screensaver0-dev libxcb-shape0 libxcb-shape0-dev libxcb-shm0 libxcb-shm0-dev libxcb-sync-dev libxcb-sync0-dev libxcb-sync1 libxcb-util-dev libxcb-util0-dev libxcb-util1 libxcb-xevie0 libxcb-xevie0-dev libxcb-xf86dri0 libxcb-xf86dri0-dev libxcb-xfixes0 libxcb-xfixes0-dev libxcb-xinerama0 libxcb-xinerama0-dev libxcb-xkb-dev libxcb-xkb1 libxcb-xprint0 libxcb-xprint0-dev libxcb-xtest0 libxcb-xtest0-dev libxcb-xv0 libxcb-xv0-dev libxcb-xvmc0 libxcb-xvmc0-dev libxcb1 libxcb1-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxext-dev libxfixes-dev libxi-dev libxrandr-dev libxrender-dev libxslt-dev libxss-dev libxtst-dev perl python ruby

On a different version of Ubuntu, some of the package names will likely differ. On a different Linux distribution you will typically need to use a different package installer program (e.g. yum on Fedora Core and CentOS and zypper on openSUSE).

Step 4. Configure Qt for the desired options and ensure that all dependencies are met

The next step is configuring Qt. This will identify the options of Qt that will be enabled and create the make files needed to build it. It is initiated by running the configure shell script. While configure has many options (which you can display by running configure -h), we will just use the defaults:

% ./configure

This will take some time, as many tests need to be run. Here is an abbreviated version of the output I saw on my system:

Which edition of Qt do you want to use ?
Type 'c' if you want to use the Commercial Edition.
Type 'o' if you want to use the Open Source Edition.
o
This is the Qt Open Source Edition.
You are licensed to use this software under the terms of
the GNU Lesser General Public License (LGPL) versions 3.
You are also licensed to use this software under the terms of
the GNU General Public License (GPL) versions 2.
Do you accept the terms of either license? yes
Creating qmake....Done.
Running configuration tests...
checking for C++14...  yes.
checking for alsa...  yes.
Done running configuration tests.
Configure summary
Build type:    linux-g++ (x86_64, CPU features: mmx sse sse2)
Build options:
Configuration .......... accessibility accessibility-atspi-bridge alsa audio-backend avx avx2 avx512bw avx512cd avx512dq avx512er avx512f avx512ifma avx512pf avx512vbmi avx512vl c++11 c++14 c++1z clock-gettime clock-monotonic compile_examples concurrent cups dbus doubleconversion egl eglfs egl_x11 enable_new_dtags evdev eventfd fontconfig full-config getaddrinfo getifaddrs glib harfbuzz iconv icu inotify ipv6ifname large-config largefile libudev linuxfb medium-config minimal-config mremap opengl openssl png poll_ppoll posix_fallocate precompile_header pulseaudio qpa qpa reduce_exports reduce_relocations release rpath shared small-config sse2 sse3 sse4_1 sse4_2 ssse3 system-freetype system-png system-zlib threadsafe-cloexec use_gold_linker xcb xcb-glx xcb-plugin xcb-render xcb-xlib xinput2 xkbcommon-evdev xkbcommon-qt xlib xrender 
Build parts ............ libs tools examples
Mode ................... release
Using C++ standard ..... c++1z
Target compiler supports:
SSE .................. SSE2 SSE3 SSSE3 SSE4.1 SSE4.2
Qt modules and options:
Qt D-Bus ............... yes (loading dbus-1 at runtime)
Qt Concurrent .......... yes
Qt GUI ................. yes
Qt Widgets ............. yes
Large File ............. yes
QML debugging .......... yes
Use system proxies ..... no
Support enabled for:
Accessibility .......... yes
ALSA ................... yes
Image formats: 
GIF .................. yes (plugin, using bundled copy)
JPEG ................. yes (plugin, using bundled copy)
OpenGL / OpenVG: 
EGL .................. yes
OpenGL ............... desktop
OpenVG ............... no
PCRE ................... system
QPA backends: 
DirectFB ............. no
EGLFS ................ yes
EGLFS X11 .......... yes
LinuxFB .............. yes
Mir client............ no
XCB .................. yes (system library)
EGL on X ........... yes
GLX ................ yes
MIT-SHM ............ yes
Session management ..... yes
SQL drivers: 
DB2 .................. no
tslib .................. no
udev ................... yes
xkbcommon-x11........... yes (bundled copy, XKB config root: /usr/share/X11/xkb)
xkbcommon-evdev......... yes
zlib ................... yes (system library)
Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into /usr/local/Qt-5.7.1
Prior to reconfiguration, make sure you remove any leftovers from
the previous build.

At this point configure should indicate if any required dependencies are missing. A typical error message is:

make: g++: Command not found

which should be obvious, indicating that the C+ compiler is not installed.

You will also want to check that the Qt options you desire are enabled. A critical one that I check for is the QPA back ends that are enabled. On a Linux desktop you typically use XCB (X11), so it should appear with a "yes":

QPA backends: 
DirectFB ............. no
EGLFS ................ yes
LinuxFB .............. yes
Mir client............ no
XCB .................. yes (system library)

Qt Quick also requires OpenGL, so it is good to check that OpenGL support is found if you want to use QML:

OpenGL / OpenVG: 
EGL .................. yes
OpenGL ............... desktop
OpenVG ............... no

If you are missing dependencies, you will need to identify the Ubuntu packages which provide them, install the packages, and then run configure again. This can be an iterative process the first time you build Qt.

Step 5. Build Qt (i.e. compile and link)

You can now perform the build by running make.

Most systems today have multiple CPU cores, so you will want to take advantage of using them. You can pass the -j option to make specifying how many jobs to run in parallel. One rule of thumb is to use the number of cores less one, which tends to make good use of the available cores while still allowing the system to be usable for interactive work. So for a 4 core system we might use:

% make -j4

This will take some time, anywhere from under an hour on a fast machine to many hours on a low-end computer. By default we are building all Qt modules, including some large ones like QtWebEngine, as well as all the Qt examples and demos.

On a computer with limited memory, say less than 4 GB, you may need to compile with only one parallel job and possibly close any memory-hungry applications like a web browser to avoid running out of memory. I've found this can happen when building QtWebEngine, as it has some large files that require a significant amount of memory to compile.

It is possible that the build can fail at this point due to some missing dependencies. If so, you will need to identify the missing packages, install them, and then continue building.

Once the build is successful you are ready to move on to the installation step.

Step 6. Install and test the new version

Install Qt by running:

% sudo make install

The default install location is /usr/local/Qt-5.7.1, which is reasonable and allows you to have multiple Qt versions installed without conflicts. You may want to use another location. If so, you can specify it using the -prefix command line option to configure. You may also want to add the binary directory (/usr/local/Qt-5.7.1/bin) to your search path so that you can run commands like qmake and assistant without always specifying the full path.

As a quick sanity test we can try launching Qt Designer and confirm that it comes up:

% /usr/local/Qt-5.7.1/bin/designer

Snapshot

We haven't yet built the documentation, which will be available from Qt Assistant. We can build and install it as follows:

% make docs
% sudo make install_docs

As a test, we can now launch Qt Assistant:

% /usr/local/Qt-5.7.1/bin/assistant

Snapshot

The first time it is launched it will take a few seconds to index the help files for searching.

We're done! Your new Qt install is ready to use. At this point you may wish to do some more testing, such as confirming that you can run some QML code using the qmlscene program. If you use the Qt Creator IDE, you should configure it to add the new Qt version and try building some of your own code or one of the Qt examples to verify that it works.

Conclusions

I hope this tutorial has encouraged you to try building Qt on your Linux desktop. One way to help the Qt project is to build and test Alpha, Beta, and Release Candidate builds — something you can do even if you aren't a Qt developer as long as you know how to build Qt from source. As I write this, Qt 5.8.0 is at Release Candidate status and can benefit from testing by users to find any issues before the final release.

References:

  1. Getting Started With Qt and Qt Creator on Windows, ICS blog post, www.ics.com/blog/getting-started-qt-and-qt-creator-windows
  2. Getting Started With Qt and Qt Creator on Linux, ICS blog post, www.ics.com/blog/getting-started-qt-and-qt-creator-linux
  3. Build Qt Sources / Linux X11, Qt Documentation website, doc.qt.io/qt-5/build-sources.html#linux-x11
  4. Qt for X11 Requirements, Qt Documentation website, doc.qt.io/qt-5/linux-requirements.html
  5. Qt for Linux/X11 - Building from Source, Qt Documentation website, doc.qt.io/qt-5/linux-building.html
  6. Building Qt 5 from Git, Qt Wiki, wiki.qt.io/Building_Qt_5_from_Git