CMake Manual

CMake 是一种工具, 有助于简化跨平台的开发项目的构建过程. CMake 自动生成构建系统, 例如 Makefile 和 Visual Studio 项目文件.

CMake 是一个第三方工具, 详见 官方文档. 本手册的其余部分详细介绍如何将 Qt 5 和 CMake 结合. 使用 Qt5 所需的最低版本是 CMake 2.8.3, 但是推荐使用 3.1.0.

开始使用

使用 CMake 构建时, 第一个要求是使用 find_package 配置 Qt 的库和头文件. 然后可以使用这些库和头文件构建基于 Qt 的库和应用程序.

CMake 2.8.11 中使用 Qt 库和头文件的推荐方法是使用 target_link_libraries 命令. 在 CMake 2.8.11 及更高版本中, 这个命令自动添加适当的包含目录, 编译定义, 位置无关代码标志及指向 Windows 上 qtmain.lib 库链接.

要构建 helloworld GUI 可执行程序, 经典做法是:


  cmake_minimum_required(VERSION 2.8.11)

  project(testproject)

  # Find includes in corresponding build directories
  set(CMAKE_INCLUDE_CURRENT_DIR ON)
  # Instruct CMake to run moc automatically when needed.
  set(CMAKE_AUTOMOC ON)

  # Find the QtWidgets library
  find_package(Qt5Widgets)

  # Tell CMake to create the helloworld executable
  add_executable(helloworld WIN32 main.cpp)

  # Use the Widgets module from Qt 5.
  target_link_libraries(helloworld Qt5::Widgets)

注意: 若想自动链接到 Windows 的 qtmain.lib 库, 则要求 CMake 的最低版本是 2.8.11.

为了使 find_package 成功, 必须在 CMAKE_PREFIX_PATH 下找到 Qt 5, 或 必须在 CMake 缓存中将 Qt5<Module>_DIR 设置为 Qt5WidgetsConfig.cmake 文件目录. 使用 CMake 最简单的方法是在 CMAKE_PREFIX_PATH 环境变量中添加 Qt 5 的安装目录.

若需要, 设置 CMAKE_AUTOMOC 自动运行 moc. 详见 CMake AUTOMOC 文档

导入目标

为每个 Qt 模块创建导入目标. 首选的方法是导入目标的名称, 而不是在 CMake 命令(如, target_link_libraries)中使用 Qt5<Module>_LIBRARIES 等变量. 你可以使用 LOCATION 属性 获取库的实际路径:


  find_package(Qt5Core)

  get_target_property(QtCore_location Qt5::Core LOCATION)

注意: 在 CMake 代码中, 很少需要库的完整路径. 多数 CMake API 知道导入目标, 并可以自动使用它们, 而不需要完整路径.

Qt 5 中的每个模块的库都有一个具有命名约定 Qt5::<Module>.

导入目标使用Qt的配置创建. 也就是说, 如果 Qt 配置 -debug 开关, 则将使用 DEBUG 配置创建导入目标. 如果 Qt 配置 -release 开关, 则将使用 RELEASE 配置创建导入目标. 如果 Qt 配置 -debug-and-release 开关 (Windows上的默认配置), 则使用 RELEASE 和 DEBUG 配置创建导入目标.

如果你的项目自定义 CMake 构建配置, 则可能需要设置从自定义配置到调试或发布 Qt 配置的映射.


  find_package(Qt5Core)

  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")

插件也可作为 CMake 中的 IMPORTED 目标. Qt Network, Qt SQL, Qt GUI, Qt Widgets 模块都有相关插件. 使用 Qt5<Module>_PLUGINS 变量提供插件列表.


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

Using Qt 5 with CMake older than 3.1.0

Qt 5.7 要求支持 C++11. 从 3.1.0 版本开始, CMake 向 Qt5 模块目标隐式添加所需的最低编译器标志 (如. -std=gnu++11). 如果你使用 3.1.0 之前版本, 则需要将所需 -std=... 添加到自己链接的 Qt5 目标模块.

如果你使用 Qt 5.7 和高于 3.1.0 版本, 并且需要更新的 C++ 标准版本, 那么, 你需要使用 CMake 方式选择标准版本, 或指定所需功能, 让 CMake计算标志. 如:


  set(CMAKE_CXX_STANDARD 14)

另见 CMake cmake-compile-features 文档

Using Qt 5 with CMake older than 2.8.12

使用较旧的 CMake 时, 还需要将 Qt5<Module>_EXECUTABLE_COMPILE_FLAGS 添加到 CMAKE_CXX_FLAGS, 以便在必要时将 -fPIC 标志添加到编译标志 (这是 Qt 5 的默认设置).

Using Qt 5 with CMake older than 2.8.11

在 2.8.11 之前的 CMake 中, 使用 Qt 库和头文件的推荐方式是使用 qt5_use_modules 宏.

注意: 在使用 qt5_use_modules 之前, CMake 需要使用 find_package 查找 Qt 模块. 有关 CMake 支持的完整选项, 参见 CMake find_package 文档.

qt5_use_modules 宏封装了使用 Qt 模块所需的所有变量用法. 如果尚未找到, 它会自动查找命令行上提供给它的模块.


  find_package(Qt5Widgets)

  add_executable(helloworld WIN32 main.cpp)

  qt5_use_modules(helloworld Widgets)

Using Qt 5 with CMake older than 2.8.9

如果使用 2.8.9 版本之前的 CMake , 则 qt5_use_modules 宏不可用. 尝试使用它会导致错误.

要将 Qt 5 与 2.8.9 版本之前的 CMake 一起使用, 需要使用 target_link_libraries, include_directories, add_definitions 命令, 并使用 qt5_generate_mocqt5_wrap_cpp 手动指定 moc 要求:


  cmake_minimum_required(VERSION 2.8.3)

  project(testproject)

  # Find includes in corresponding build directories
  set(CMAKE_INCLUDE_CURRENT_DIR ON)

  # Find the QtWidgets library
  find_package(Qt5Widgets)

  # Add the include directories for the Qt 5 Widgets module to
  # the compile lines.
  include_directories(${Qt5Widgets_INCLUDE_DIRS})

  # Use the compile definitions defined in the Qt 5 Widgets module
  add_definitions(${Qt5Widgets_DEFINITIONS})

  # Add compiler flags for building executables (-fPIE)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")

  qt5_generate_moc(main.cpp main.moc)

  # Tell CMake to create the helloworld executable
  add_executable(helloworld main.cpp main.moc)

  #Link the helloworld executable to the Qt 5 widgets library.
  target_link_libraries(helloworld Qt5::Widgets)

Variable Reference

Module variables

调用 find_package 的结果是将导入的目标与 target_link_libraries 一起使用, 一些变量将填充配置构建所需的信息, 并且宏将可供使用. 每个模块的导入目标名称与前缀为 'Qt5::' 的模块名称相匹配, 如 Qt5::Widgets. 所有特定于包的变量都具有与包名称前缀一致的名称. 如, 如果 find_package(Qt5Widgets) 成功找到, 则下列变量可用:

  • Qt5Widgets_VERSION 描述模块版本的字符串.
  • Qt5Widgets_VERSION_STRING 等价于 Qt5Widgets_VERSION. 已弃用, 使用 Qt5Widgets_VERSION 替代.
  • Qt5Widgets_LIBRARIES 与 target_link_libraries 命令一起使用的库列表.
  • Qt5Widgets_INCLUDE_DIRS 与 include_directories 命令一起使用的目录列表.
  • Qt5Widgets_DEFINITIONS 与 add_definitions 命令一起使用的定义列表.
  • Qt5Widgets_COMPILE_DEFINITIONS 与 COMPILE_DEFINITIONS 目标属性一起使用的定义列表.
  • Qt5Widgets_FOUND Boolean 描述模块是否成功找到的布尔值.
  • Qt5Widgets_EXECUTABLE_COMPILE_FLAGS 构建可执行程序时使用的标志字符串.

这些变量可用于调用 find_package 找到的所有包. 注意: 这些变量区分大小写.

Installation variables

此外, 还有其他几个可用变量, 这些变量与特定包无关, 而是与 Qt 有关.

  • QT_VISIBILITY_AVAILABLE 描述 Qt 是否使用隐藏可见性构建的布尔值.
  • QT_LIBINFIX 包含库名称中使用的中缀字符串.

Macro Reference

Qt5Core 宏

查找到 Qt5Core 后, 可用的宏变量.

MacroDescription
qt5_wrap_cpp(outfiles inputfile ... OPTIONS ...)Create moc code from a list of files containing Qt class with the Q_OBJECT declaration. Per-directory preprocessor definitions are also added. Options may be given to moc, such as those found when executing "moc -help".
qt5_add_resources(outfiles inputfile ... OPTIONS ...)Create code from a list of Qt resource files. Options may be given to rcc, such as those found when executing "rcc -help".
qt5_add_binary_resources(target inputfile ... OPTIONS ... DESTINATION ...)Create an RCC file from a list of Qt resource files. Options may be given to rcc, such as those found when executing "rcc -help". A destination may be given to use a different filename or path for the RCC file.
qt5_generate_moc(inputfile outputfile )Creates a rule to run moc on infile and create outfile. Use this if for some reason QT5_WRAP_CPP() isn't appropriate, e.g. because you need a custom filename for the moc file or something similar.
qt5_use_modules(target [LINK_PUBLIC|LINK_PRIVATE] module ... )Indicates that the target uses the named Qt 5 modules. The target will be linked to the specified modules, use the include directories installed by those modules, use the COMPILE_DEFINITIONS set by those modules, and use the COMPILE_FLAGS set by the modules. The LINK_PRIVATE or LINK_PUBLIC specifiers can optionally be specified. If LINK_PRIVATE is specified then the modules are not made part of the link interface of the target. See the documentation for target_link_libraries for more information.

Note that this macro is only available if using CMake 2.8.9 or later. This macro is obsolete. Use target_link_libraries with IMPORTED targets instead.

Qt5Widgets macros

Macros available when Qt5Widgets is found.

MacroDescription
qt5_wrap_ui(outfiles inputfile ... OPTIONS ...)Create code from a list of Qt designer ui files. Options may be given to uic, such as those found when executing "uic -help"

Qt5DBus macros

Macros available when Qt5DBus is found.

MacroDescription
qt5_add_dbus_interface(outfiles interface basename)Create the interface header and implementation files with the given basename from the given interface xml file and add it to the list of sources
qt5_add_dbus_interfaces(outfiles inputfile ... )Create the interface header and implementation files for all listed interface xml files the name will be automatically determined from the name of the xml file
qt5_add_dbus_adaptor(outfiles xmlfile parentheader parentclassname [basename] [classname])Create a dbus adaptor (header and implementation file) from the xml file describing the interface, and add it to the list of sources. The adaptor forwards the calls to a parent class, defined in parentheader and named parentclassname. The name of the generated files will be <basename>adaptor.{cpp,h} where basename defaults to the basename of the xml file. If <classname> is provided, then it will be used as the classname of the adaptor itself.
qt5_generate_dbus_interface( header [interfacename] OPTIONS ...)Generate the xml interface file from the given header. If the optional argument interfacename is omitted, the name of the interface file is constructed from the basename of the header with the suffix .xml appended. Options may be given to qdbuscpp2xml, such as those found when executing "qdbuscpp2xml --help"

Qt5LinguistTools macros

Macros available when Qt5LinguistTools is found.

MacroDescription
qt5_create_translation( qm_files directories ... sources ... ts_files ... OPTIONS ...)Out: qm_files In: Directories sources ts_files Options: flags to pass to lupdate, such as -extensions to specify Extensions for a directory scan. Generates commands to create .ts (via lupdate) and .qm (via lrelease) - files from directories and/or sources. The ts files are created and/or updated in the source tree (unless given with full paths). The qm files are generated in the build tree. Updating the translations can be done by adding the qm_files to the source list of your library/executable, so they are always updated, or by adding a custom target to control when they get updated/generated.
qt5_add_translation( qm_files ts_files ... )Out: qm_files In: ts_files Generates commands to create .qm from .ts - files. The generated filenames can be found in qm_files. The ts_files must exist and are not updated in any way.