Get started with CMake

Start with find_package to locate the libraries and header files shipped with Qt. Then, you can use these libraries and header files with the target_link_libraries command to build Qt-based libraries and applications. This command automatically adds the appropriate include directories, compile definitions, the position-independent-code flag, and links to the qtmain.lib library on Windows, for example.

Build a GUI executable

To build a helloworld GUI executable, you need the following:

cmake_minimum_required(VERSION 3.1.0)

project(helloworld)

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

if(CMAKE_VERSION VERSION_LESS "3.7.0")
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()

find_package(Qt5 COMPONENTS Widgets REQUIRED)

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

target_link_libraries(helloworld Qt5::Widgets)

For find_package to be successful, CMake must find the Qt installation in one of the following ways:

  1. Set your CMAKE_PREFIX_PATH environment variable to the Qt 5 installation prefix. This is the recommended way.
  2. Set the Qt5_DIR in the CMake cache to the location of the Qt5Config.cmake file.

The CMAKE_AUTOMOC setting runs moc automatically when required. For more details, see CMake AUTOMOC documentation.

Imported targets

Imported targets are created for each Qt module. In CMake, commands such as target_link_libraries use imported target names instead of variables like Qt5<Module>_LIBRARIES. The actual path to the library can be obtained using the LOCATION property, as follows:

find_package(Qt5 COMPONENTS Core REQUIRED)

get_target_property(QtCore_location Qt5::Core LOCATION)

However, you rarely need the full location to the library as most CMake APIs can locate imported targets and use them automatically, instead of the full path. For this purpose, each module in Qt 5 has a library target with the Qt5::<Module> naming convention.

Imported targets are created with the same configurations as when Qt was configured. That is:

  • If Qt was configured with the -debug switch, an imported target with the DEBUG configuration is created.
  • If Qt was configured with the -release switch, an imported target with the RELEASE configuration is created.
  • If Qt was configured with the -debug-and-release switch, which is the default on Windows, then imported targets are created with both RELEASE and DEBUG configurations.

If your project has custom CMake build configurations, you have to map your custom configuration to either the debug or the release Qt configuration.

find_package(Qt5 COMPONENTS Core REQUIRED)

set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage")

# set up a mapping so that the Release configuration for the Qt imported target is
# used in the COVERAGE CMake configuration.
set_target_properties(Qt5::Core PROPERTIES MAP_IMPORTED_CONFIG_COVERAGE "RELEASE")

In CMake, plugins are also available as IMPORTED targets. The Qt Network, Qt SQL, Qt GUI, and Qt Widgets modules have plugins associated. They provide a list of plugins in the Qt5<Module>_PLUGINS variable.

foreach(plugin ${Qt5Network_PLUGINS})
  get_target_property(_loc ${plugin} LOCATION)
  message("Plugin ${plugin} is at location ${_loc}")
endforeach()

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.14/cmake-get-started.html