Getting started with CMake | Build with CMake 6.1.3

- Qt 6.1
- Build with CMake
- Getting started with CMake
- Qt 6.1.3 Reference Documentation

Build with CMake ◦ Imported targets

# Getting started with CMake

`CMake` is a group of tools that allow to build, test, and package applications. Just like Qt, it is available on all major development platforms. It is also supported by various IDE's, including Qt Creator.

In this section we will show the most basic way to use Qt in a CMake project. We will walk through an example project that is utilizing Qt Widgets.

### Build a C++ GUI executable

A `CMake` project is defined by files written in the CMake language. The main file is called `CMakeLists.txt`, and is usually placed in the same directory as the actual program sources.

Here is a typical `CMakeLists.txt` file for an application written in C++ and using Qt and Qt Widgets:

     cmake_minimum_required(VERSION 3.16.0)

     project(helloworld VERSION 1.0.0 LANGUAGES CXX)

     set(CMAKE_CXX_STANDARD 17)
     set(CMAKE_CXX_STANDARD_REQUIRED ON)

     set(CMAKE_AUTOMOC ON)
     set(CMAKE_AUTORCC ON)
     set(CMAKE_AUTOUIC ON)

     find_package(Qt6 COMPONENTS Widgets REQUIRED)

     add_executable(helloworld
         mainwindow.ui
         mainwindow.cpp
         main.cpp
         resources.qrc
     )

     target_link_libraries(helloworld PRIVATE Qt6::Widgets)

Let's go through the content.

     cmake_minimum_required(VERSION 3.16.0)

`cmake_minimum_required()` specifies the minimum CMake version that the application requires. Qt itself requires at least CMake version 3.16.

     project(helloworld VERSION 1.0.0 LANGUAGES CXX)

`project()` sets a project name and the default project version. The `LANGUAGES` argument tells CMake that the program is written in C++.

     set(CMAKE_CXX_STANDARD 17)
     set(CMAKE_CXX_STANDARD_REQUIRED ON)

Qt 6 requires a compiler supporting C++ version 17 or newer. Enforcing this by setting the `CMAKE_CXX_STANDARD`, `CMAKE_CXX_STANDARD_REQUIRED` variables will let CMake print an error if the compiler is too old.

     set(CMAKE_AUTOMOC ON)
     set(CMAKE_AUTORCC ON)
     set(CMAKE_AUTOUIC ON)

Qt applications typically make use of the Meta-Object Compiler (moc), Resource Compiler (rcc), and User Interface Compiler (uic) that come with Qt. Setting the `CMAKE_AUTOMOC`, `CMAKE_AUTORCC`, and `CMAKE_AUTOUIC` variables to `ON` will let CMake automatically set up rules so that the respective compilers are called transparently, when required.

     find_package(Qt6 COMPONENTS Widgets REQUIRED)

This tells CMake to look up Qt 6, and import the `Widgets` module. There is no point in continuing if `CMake` cannot locate the module, so we do set the `REQUIRED` flag to let CMake abort in this case.

If successful, the module will set some CMake variables documented in Module variables. It furthermore imports the `Qt6::Widgets` target that we use below.

For `find_package` to be successful, `CMake` must find the Qt installation. There are different ways you can tell `CMake` about Qt:

1. Set the `CMAKE_PREFIX_PATH` environment variable to include the Qt 6 installation prefix.
2. Set the CMake cache variable `CMAKE_PREFIX_PATH` to include the Qt 6 installation prefix.

Note that Qt Creator will handle this transparently for you.

     add_executable(helloworld
         mainwindow.ui
         mainwindow.cpp
         main.cpp
         resources.qrc
     )

`add_executable()` tells CMake that we want to build an executable (so not a library) called `helloworld` as a target. The target should be built from C++ code (`mainwindow.cpp`, `main.cpp`), a Qt Designer file (`mainwindow.ui`), and a Qt Resource System file (`resources.qrc`).

Note that you typically do not list header files here. This is different from qmake, where header files need to be explicitly listed so that they are processed by the Meta-Object Compiler (moc).

     target_link_libraries(helloworld PRIVATE Qt6::Widgets)

Finally, `target_link_libraries` tells CMake that the `helloworld` executable makes use of Qt Widgets by referencing the `Qt6::Widgets` target imported by the `find_package()` call above. This will not only add the right arguments to the linker, but also makes sure that the right include directories, compiler definitions are passed to the C++ compiler. The `PRIVATE` keyword is not strictly necessary for an executable target, but it is good practice to specify it. If `helloworld` was a library rather than an executable, then either `PRIVATE` or `PUBLIC` should be specified (`PUBLIC` if the library mentions anything from `Qt6::Widgets` in its headers, `PRIVATE` otherwise).

### Further reading

The official CMake Documentation is an invaluable source for working with CMake.

The book Professional CMake: A Practical Guide provides a great introduction to the most relevant CMake features.

Build with CMake ◦ Imported targets