Qt 6 Build System

CMake is the build system for Qt 6

The tool that's used to build Qt 6 is CMake.

CMake is

  • widely adapted and available.
    It's even shipped with Visual Studio these days.
  • supported by a thriving community.
    Many packages for third-party libraries are available.
  • stable and mature.
    Next year, it will get permission to consume alcohol beverages in the US.

CMake 3.18.4 was released recently. Please use that one for building Qt.

Use configure or plain CMake

Our beloved configure script still exists. It accepts most of the options you are used to from Qt 5.

At the moment the qmake build system is still in place. You can choose between building Qt with qmake or CMake. Pass -cmake to configure to use the CMake-based build.

Update: The CMake build system is now the default one.
There is no need to pass -cmake anymore to select the CMake build.
Pass -qmake to enable the qmake build, but be prepared that it is going to vanish anytime soon.

For the final release, expect that the qmake build system will vanish together with the need to pass -cmake.

For example, the following call configures Qt to be installed to ~/Qt/6.0.0 and turns off support for the QLCDNumber widget and skips the qtsvg repository:

configure -cmake -prefix /opt/Qt/6.0.0 -no-feature-lcdnumber -skip qtsvg

The configure script translates those arguments to the following CMake call:

cmake -GNinja -DCMAKE_INSTALL_PREFIX=/opt/Qt/6.0.0 -DFEATURE_lcdnumber=OFF -DBUILD_qtsvg=OFF /path/to/qt/sources

This is quite a mouthful, and illustrates the usefulness of our configure script.

With configure, we can pass extra arguments to CMake after the -- argument. The configure call above is equivalent to this:

configure -cmake -prefix ~/Qt/6.0.0 -no-feature-lcdnumber -- -DBUILD_qttools=OFF

After configuring, use cmake --build . or ninja to build the project.

We recommend to use CMake's Ninja generator. This is also configure's default.

You can specify the CMake generator by passing -cmake-generator <name> to use another generator and -cmake-use-default-generator to use CMake's default generator, i.e. no -G <generator> argument is passed.

Use cmake --install . to install Qt.

Cross-compiling Qt

To cross-compile a project with CMake, one must specify a toolchain file. This CMake-language file sets the right values for the platform name, used compiler/linker and a whole bunch of other toolchain-specific things.

The toolchain file concept is similar to qmake's mkspecs.

Read more about toolchain files in CMake's cross-compiling documentation.

Let's examine how to do an Android build of Qt on Linux.

configure -cmake -prefix /opt/Qt/6.0.0-android \
    -qt-host-path /opt/Qt/6.0.0 \
    -xplatform android-clang \
    -android-ndk ~/Android/android-sdk-tools/ndk-bundle \
    -android-sdk ~/Android/android-sdk-tools \
    -android-abis armeabi-v7a

The most notable difference is the -qt-host-path option. To cross-build Qt, you need to point to an already existing native build of your host platform. This is called the host Qt.

All the native host tools like moc, rcc and uic are run from there.

In Qt5, we built the host tools anew for every single cross-build. Re-using the host tools from an existing host Qt installation saves us from building the host tools for every cross-build over and over again and greatly simplifies Qt's build system.

The cross-built Qt does not build the host tools for the target platform, unless you set the CMake variable QT_BUILD_TOOLS_WHEN_CROSS_COMPILING to ON. Doing so is useful in embedded Linux environments.

The -xplatform android-clang argument merely influences the companion files that are generated to provide qmake-support for this cross-build.

The -android-ndk argument points to the NDK and selects the CMake toolchain file that's located in there.

The -android-sdk argument points to the SDK.

The -android-abis argument selects the ABI we're going to build. Note that multi-ABI builds are not yet implemented.

And to put everything together, the configure call above is translated into the following CMake call:

cmake -DQT_HOST_PATH=/opt/Qt/6.0.0 \
    -DQT_QMAKE_TARGET_MKSPEC=android-clang \
    -DANDROID_SDK_ROOT=/home/jobor/Android/android-sdk-tools \
    -DCMAKE_TOOLCHAIN_FILE=/home/jobor/Android/android-sdk-tools/ndk-bundle/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI=armeabi-v7a \
    -DCMAKE_INSTALL_PREFIX=/opt/Qt/6.0.0-android \
    -G Ninja \
    /path/to/qt/source

Again, build with cmake --build . or just ninja.

Use cmake --install . to install Qt.

Building Qt-based Projects

Once you have installed Qt, you can use CMake or qmake to build your projects.

Business as usual with qmake:

mkdir ~/my-project-build
cd ~/my-project-build
/opt/Qt/6.0.0/bin/qmake
make

Note: This also works for cross-builds. There, qmake is a wrapper script that calls the qmake executable of the host Qt with a generated qt.conf that sets the right paths and mkspec.

Qt comes with a wrapper script called qt-cmake to offer a similar experience with CMake:

mkdir ~/my-project-build
cd ~/my-project-build
/opt/Qt/6.0.0/bin/qt-cmake
cmake --build .

qt-cmake calls CMake with the CMAKE_TOOLCHAIN_FILE variable set to a Qt-internal toolchain file that sets the right compiler and chainloads the "real" toolchain file in the cross-compiling case.

Note: If you find yourself needing to chainload a different toolchain file, pass -DQT_CHAINLOAD_TOOLCHAIN_FILE=<file-path> to qt-cmake.

qt-cmake does not set the CMake generator. If you always want to use Ninja - what we recommend - set the environment variable CMAKE_GENERATOR to Ninja.

Building Qt Modules

qt-configure-module is the tool of choice when building a Qt module separately against an installed Qt. The qt-configure-module script takes the same arguments a top-level Qt configure call would - restricted to the arguments that apply to the module we're currently configuring.

In the following example we first build and install qtbase, then qtdeclarative with the qml-network feature turned off.

mkdir ~/dev/qt/qtbase-build
cd ~/dev/qt/qtbase-build
../qtbase/configure -prefix /opt/Qt/6.0.0
cmake --build .
cmake --install .

mkdir ~/dev/qt/qtdeclarative-build
cd ~/dev/qt/qtdeclarative-build
/opt/Qt/6.0.0/bin/qt-configure-module ../qtdeclarative -no-qml-network
cmake --build .
cmake --install .

Building stand-alone Tests and Examples

If you're a Qt contributor, hacking on some part of Qt, you probably want to extend and run the autotests that cover that area. But most people always configure Qt with -nomake tests, because configuring and building tests takes some time.

There are two good news:

  1. Not building all tests is the default now! No need to pass -nomake tests anymore. The same goes for -nomake examples.
    If you really want to build all test and examples, pass the -make tests -make examples arguments. We believe that the new default will result in much less typed commandline characters, saving this scarce resource for more interesting invocations.
  2. It's easy to configure and build a single autotest or example.

And this is how you build and run the autotest for QProcess:

mkdir ~/dev/qt/tst_qprocess
cd ~/dev/qt/tst_qprocess
/opt/Qt/6.0.0/bin/qt-cmake-standalone-test ../qtbase/tests/auto/corelib/io/qprocess
cmake --build .
ctest -V

This uses the ctest tool that comes CMake, but you can also directly run the executable, of course.

Building an example works in a similar way:

mkdir ~/dev/qt/wiggly
cd ~/dev/qt/wiggly
/opt/Qt/6.0.0/bin/qt-cmake ../qtbase/examples/widgets/widgets/wiggly
cmake --build .
./wiggly

Porting qmake-based Projects to CMake

If you're looking for a way to easily port your qmake-based project to CMake, I have good and bad news for you.

The Good News

There is no immediate need to port your project to CMake.

QMake continues to work in Qt6.

The Bad News

There is no good porting tool available.

Qt itself was (and to a certain degree still is) ported to CMake using a Python script called pro2cmake.

The script is tailored to the structure of Qt module project files, and while it potentially could be useful to create a starting point for user projects, it is far from something we would recommed.

It might just bail out on encountering some clever qmake construct.
But if you're of the adventurous type, feel free to try it out, and make sure to pass the --is-example argument.

Conclusion

We hope that the switch to CMake is as smooth as possible for you and that Qt and CMake communities will benefit from each other.

Thanks for reading, and do not hesitate to try out the Qt CMake build and provide feedback in the comment section or in our bug tracker!


Blog Topics:

Comments

Commenting for this post has ended.

Felix
3 points
18 months ago
  • QML source code that has been compiled no longer has to be included with the application binary

I have been waiting for this one. Very nice

K
Kelteseth
2 points
18 months ago

Please fix the broken scroll speed in qml that was introduced in this release https://bugreports.qt.io/browse/QTBUG-116388

Felix
1 point
18 months ago

[What's New in Qt 6.6 | Qt 6.7|https://doc-snapshots.qt.io/qt6-dev/whatsnew66.html#qt-quick-module] In this section look at QTQUICKFLICKABLEWHEELDECELERATION . You can go back to the previous implementation. I think for the current implementation there are other improvements to be made. I'm going to look into it the coming week. From what I can see they tried to make scrolling directly proportional to the scrollwheel angle instead of using innertia with flickvelocity. I like that change but they made a mistake in that fix where if you scroll fast right now the displacement is less than when you scroll slow.

K
Kelteseth
0 points
18 months ago

But the new version should not ignore the flickDeceleration entirely, right? Doesn't matter what values you put in, it always stays the same. I tested this on Linux and Windows. If not, then the documentation is outdated because it does still state example values https://doc-snapshots.qt.io/qt6-dev/qml-qtquick-flickable.html#flickDeceleration-prop

Felix
0 points
18 months ago

As far as I understand it, it does ignore flickDeceleration for Mouse Movements specifically as they only position the view and do not rely on innertia anymore. My guess is the flick innertia only makes sense on a touch screen and those magic mouse touch inputs, but when you use a scrollWheel on a normal mouse that idea of flinging the paper just shouldn't apply. It's called a 'Scroll' wheel for a reason, the UX thought behind it was scrolling those old paper scrolls. With a touch screen when you flick you actually release your finger and the whole flickdeceleration is based on the UX idea of you pushing and releasing a surface with innertia.

O
Oliver Eftevaag
0 points
18 months ago

Yes, this was the intention behind it! Prior to 6.6, wheel events would call flick() internally, which essentially means that mouse wheel events would be treated the same as flicking with a finger. We didn't like it, which is why we changed it. I'm still not entirely happy with the new behavior, and plan on improving it further in a later release. I want it to feel similar to browsers and other common applications that have a scrollable area. Finger/Stylus based flicking will be left unchanged.

K
Kelteseth
1 point
18 months ago

So the Qt 6.6 version that was released on 04.10.23 is the final version? According to MaintenanceTool it is.

J
Jani Heikkinen
0 points
18 months ago

Yes, final version is build 4.10.23

Michael Cox
1 point
18 months ago

What's the licence for Qt Graphs?

M
Maurice Kalinowski
1 point
18 months ago

GPL3 / Commercial

Andrei Cherniaev
1 point
18 months ago

"except Wayland-based systems" Why? I will waiting Wayland...

J
Jøger Hansegård
0 points
18 months ago

Hi Andrei. Due to technical difficulties, screen capture on Wayland is not yet implemented, but this is something we will be looking into for future releases.

Andrei Cherniaev
0 points
18 months ago

In Qt we trust!

Leonardo Seiji Oyama
0 points
18 months ago

What is the latest usable version for open source users ? I see that I can only download 6.2.4 for now.

K
Kelteseth
1 point
18 months ago

6.3, 6.4, 6.5 and 6.6 are all downloadable for open source users. Try reinstalling Qt maintenance tool

Leonardo Seiji Oyama
0 points
18 months ago

I think that there is a problem with my account. Even when I try to install Qt to a new computer, the latest version available is 6.2.4.

J
Jani Heikkinen
0 points
18 months ago

Hi! There are no visibility restrictions for open-source users, so you should also be able to see the Qt 6.6.0 and earlier releases. Please create a bug report with an installation log ( start the online installer from the command line with --verbose) so we can study your problem more.

Muneer MA
0 points
18 months ago

I am also unable to see 6.6 listed in the maintenance tool. I can only see up-to 6.5.3. I currently have installed 6.5.0. I am using Linux x64.

M
Machine Koder (Alex Rössler)
0 points
18 months ago

Try re-installing the SDK.

Sandro Frenzel
0 points
18 months ago

Maybe you should also keep care of such serious bugs:

https://bugreports.qt.io/browse/QTBUG-87334

If you want to support responsive ui for mobile devices you should keep the basic stuff working.

R
Rampe
0 points
18 months ago

You are right. I tried to reproduce it on Qt 6.6.0, but maybe I did something differently or interpreted the result wrong, because with the example that was there I was not able to reproduce it. If you have tips and tricks to reproduce it please drop in the ticket! Thanks.

Ruslan Y
0 points
18 months ago

So, Qt for Python still doesn't work on Android and ARM64?

「Cristián」
1 point
18 months ago

Hey Ruslan, it will work on aarch64 (linux) once the wheels are out. It's taking a bit of extra time due to some last minute CI and dependencies issues. If you meant Apple Silicon ARM then it has been working since 6.2.2 Qt for Python works to deploy apps to Android since 6.5 https://www.qt.io/blog/taking-qt-for-python-to-android but 6.6 brings simpler steps to deploy your apps. Stay tuned :)

Ruslan Y
0 points
18 months ago

Thanks a lot! Sound very interesting because on https://wiki.qt.io/Qt_for_Python still present > Please notice that Android, iOS, and WebAssembly are not supported yet.

Bekzod Ilyasov (Yoko)
0 points
18 months ago

When I install Qt 6.6 on MacOS Catalina, I get an error during the installation process: (qt.qt6.660.clang64): Could not find the required QmakeOutputInstallerKey(qt.qt6.660.clang64_qmakeoutput) value on the installer object. The ConsumeOutput operation on the valid qmake needs to be called first.

J
Jani Heikkinen
0 points
18 months ago

Hi! macOS Catalina isn't supported in Qt 6.6.0, see https://doc.qt.io/qt-6/supported-platforms.html

M
Machine Koder (Alex Rössler)
0 points
18 months ago

The speed with which Qt development is moving lately is exciting, it's hard to keep up with all the new stuff.

Any chances that Qt for Python will support WASM via Pyodide sometime in their near future?

A
Ahimson2
0 points
18 months ago

Hi! I tried version 6.6 of Qt. Now when I want to capture an image or save a video to a file on Android 10 (Infinix), the application crashes, but on Windows 10 PC it works correctly. Why doesn't it work on mobile?

R
Rampe
0 points
18 months ago

Ouch.. hard to speculate the reason very accurately without further information. Do you mind to drop a bug into https://bugreports.qt.io ?

If you don't mind, please add the steps to reproduce (perhaps a screen record), an example app (or at least code snippet) and background information (adb shell getprop - at minimum the system.build and ro.product.model and ro.product.manufacturer) from you emulator or target device.

J
Junchong Tang
0 points
18 months ago

Most of the Windows retrieved by QWindowCapture::capturableWindows() display an abnormal black background, This api is still unavailable, at least on Windows 11.

J
Jøger Hansegård
0 points
18 months ago

Thank you for letting us know about this problem Junchong Tang. I created a bug report for this at https://bugreports.qt.io/browse/QTBUG-118536, but we need some more information from you. Could you please have a look and update it with all the details you may have?