CMake
						
						是一组允许构建、测试及打包应用程序的工具。就像 Qt,它可用于所有主流开发平台。它还被各种 IDE 所支持,包括
						
							Qt Creator
						
						.
					
此节将展示在 CMake 工程中,使用 Qt 的最基本方式。首先,创建基本控制台应用程序。然后,将工程扩展成 GUI 应用程序使用 Qt Widgets .
若想要知道如何采用 Qt 构建现有 CMake 工程,见文档编制 如何在命令行中采用 CMake 构建工程 .
要学习 CMake 快速入门基础,接受 采用 Cmake 构建:CMake 和 Qt 快速入门 课程在 Qt 学院。
						A
						
CMake
						
						工程是以 CMake 语言编写的文件定义。main 文件称为
						
CMakeLists.txt
						
						,通常放在实际程序源代码的相同目录下。
					
						这里是典型
						
CMakeLists.txt
						
						文件用于使用 Qt 以 C++ 编写的控制台应用程序:
					
cmake_minimum_required(VERSION 3.16)
project(helloworld VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Core)
qt_standard_project_setup()
qt_add_executable(helloworld
    main.cpp
)
target_link_libraries(helloworld PRIVATE Qt6::Core)
					
					让我们浏览一下内容。
cmake_minimum_required(VERSION 3.16)
						
cmake_minimum_required()
						
						specifies the minimum CMake version that the application requires. Qt itself requires at least CMake version 3.16, except on Apple platforms, or for static builds of Qt - the default in
						
							Qt for iOS
						
						and
						
							Qt for WebAssembly
						
						- where you need CMake 3.21.1 or newer.
					
project(helloworld VERSION 1.0.0 LANGUAGES CXX)
						
project()
						
						设置工程名称和默认工程版本。
						
LANGUAGES
						
						自变量告诉 CMake 程序是以 C++ 编写的。
					
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON)
						Qt 6 要求编译器支持 C++ 第 2017 或更高版本。实施这是通过设置
						
CMAKE_CXX_STANDARD
						
						,
						
CMAKE_CXX_STANDARD_REQUIRED
						
						变量将使 CMake 打印错误,若编译器太旧。
					
find_package(Qt6 REQUIRED COMPONENTS Core)
						这告诉 CMake 去查找 Qt 6,并导入
						
核心
						
						模块。继续没有意义若
						
CMake
						
						无法定位模块,因此,设置
						
REQUIRED
						
						标志以使 CMake 中止 (在这种情况下)。
					
						若成功,模块将设置一些 CMake 文档化变量在
						
							模块变量
						
						。此外,它还导入
						
Qt6::Core
						
						目标 (使用于下文)。
					
						For
						
find_package
						
						要取得成功,
						
CMake
						
						必须找到 Qt 安装。有不同方式可以告诉
						
CMake
						
						about Qt, but the most common and recommended approach is to set the CMake cache variable
						
CMAKE_PREFIX_PATH
						
						to include the Qt 6 installation prefix. Note that
						
							Qt Creator
						
						会透明地处理这种情况。
					
qt_standard_project_setup()
The qt_standard_project_setup command sets project-wide defaults for a typical Qt application.
						除其它事情外,此命令设置
						
CMAKE_AUTOMOC
						
						变量到
						
ON
						
						,指导 CMake 自动设置规则,以便 Qt 的
						
							MOC (元对象编译器)
						
						is called transparently, when required.
					
见 qt_standard_project_setup 参考了解细节。
qt_add_executable(helloworld
    main.cpp
)
					
					
						
							qt_add_executable()
						
						告诉 CMake 想要构建的可执行文件 (因此不是库) 称为
						
helloworld
						
						as a target. It is a wrapper around the built-in
						
add_executable()
						
						command, and provides additional logic to automatically handle things like linking of Qt plugins in static Qt builds, platform-specific customization of library names, and so on.
					
						应构建目标从 C++ 源文件
						
main.cpp
						
						.
					
Typically, you do not list header files here. This is different from qmake ,需要明确列出头文件,以便处理它们通过 MOC (元对象编译器) .
为创建库,见 qt_add_library .
target_link_libraries(helloworld PRIVATE Qt6::Core)
						最后,
						
target_link_libraries
						
						告诉 CMake
						
helloworld
						
						可执行文件利用
						
							Qt Core
						
						通过引用
						
Qt6::Core
						
						目标,导入通过
						
find_package()
						
						调用 (见上文)。这不仅将正确自变量添加到链接器,且还确保将正确包括目录、编译器定义传递给 C++ 编译器。
						
PRIVATE
						
						关键字对于可执行目标不是严格必要的,但指定它是良好实践。若
						
helloworld
						
						是库而不是可执行文件,那么
						
PRIVATE
						
						or
						
PUBLIC
						
						应该指定 (
						
PUBLIC
						
						若库提到的任何东西来自
						
Qt6::Core
						
						在其头中,
						
PRIVATE
						
						否则)。
					
在 last section we showed the CMakeLists.txt file for a simple console application. We will now create a GUI application that uses the Qt Widgets 模块。
这是完整工程文件:
cmake_minimum_required(VERSION 3.16)
project(helloworld VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Widgets)
qt_standard_project_setup()
qt_add_executable(helloworld
    mainwindow.ui
    mainwindow.cpp
    main.cpp
)
target_link_libraries(helloworld PRIVATE Qt6::Widgets)
set_target_properties(helloworld PROPERTIES
    WIN32_EXECUTABLE ON
    MACOSX_BUNDLE ON
)
					
					让我们回顾一下所做的改变。
find_package(Qt6 REQUIRED COMPONENTS Widgets)
						在
						
find_package
						
						调用,我们替换
						
核心
						
						with
						
小部件
						
						。这会定位
						
Qt6Widgets
						
						模块并提供
						
Qt6::Widgets
						
						目标,我们稍后链接到。
					
						注意,应用程序仍会链接
						
Qt6::Core
						
						,因为
						
Qt6::Widgets
						
						从属它。
					
qt_standard_project_setup()
						除了
						
CMAKE_AUTOMOC
						
						,
						
							qt_standard_project_setup
						
						设置
						
CMAKE_AUTOUIC
						
						变量到
						
ON
						
						。这会自动创建规则以援引 Qt 的
						
							uic (用户界面编译器)
						
						on
						
.ui
						
						源文件。
					
qt_add_executable(helloworld
    mainwindow.ui
    mainwindow.cpp
    main.cpp
)
					
					
						我们添加
						
							Qt Designer
						
						文件 (
						
mainwindow.ui
						
						) 及其相应 C++ 源文件 (
						
mainwindow.cpp
						
						) 到应用程序目标的源。
					
target_link_libraries(helloworld PRIVATE Qt6::Widgets)
						在
						
target_link_libraries
						
						命令,我们链接到
						
Qt6::Widgets
						
						而不是
						
Qt6::Core
						
						.
					
set_target_properties(helloworld PROPERTIES
    WIN32_EXECUTABLE ON
    MACOSX_BUNDLE ON
)
					
					最后,设置应用程序目标特性,效果如下:
见 CMake 文档编制 for more information about these target properties.
Projects that contain more than just one target will benefit from a clear project file structure. We will use CMake's 子目录特征 .
						由于我们计划采用更多目标扩展工程,所以将应用程序源文件移到子目录并创建新的
						
CMakeLists.txt
						
						in there.
					
<project root>
├── CMakeLists.txt
└── src
    └── app
        ├── CMakeLists.txt
        ├── main.cpp
        ├── mainwindow.cpp
        ├── mainwindow.h
        └── mainwindow.ui
					
					
						顶层
						
CMakeLists.txt
						
						包含整体工程设置,
						
find_package
						
						and
						
add_subdirectory
						
						调用:
					
cmake_minimum_required(VERSION 3.16) project(helloworld VERSION 1.0.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 REQUIRED COMPONENTS Widgets) qt_standard_project_setup() add_subdirectory(src/app)
Variables that are set in this file are visible in subdirectory project files.
						应用程序工程文件
						
src/app/CMakeLists.txt
						
						包含可执行目标:
					
qt_add_executable(helloworld
    mainwindow.ui
    mainwindow.cpp
    main.cpp
)
target_link_libraries(helloworld PRIVATE Qt6::Widgets)
set_target_properties(helloworld PROPERTIES
    WIN32_EXECUTABLE ON
    MACOSX_BUNDLE ON
)
					
					Such a structure will make it easy to add more targets to the project such as libraries or unit tests.
注意: Add your project build directory to the list of excluded directories of any anti-virus application that runs on your system.
随着工程增长,可能想要将部分应用程序代码转换成用于应用程序且可能单元测试的库。此节展示如何创建这种库。
						我们的应用程序目前将业务逻辑直接包含在
						
main.cpp
						
						。我们将代码提取到的新静态库称为
						
businesslogic
						
						在子目录
						
"src/businesslogic"
						
						as explained in the
						
							上一章节
						
						.
					
						为简单起见,库仅仅包含一个 C++ 源文件及其相应头文件,头文件包括在应用程序的
						
main.cpp
						
						:
					
<project root>
├── CMakeLists.txt
└── src
    ├── app
    │   ├── ...
    │   └── main.cpp
    └── businesslogic
        ├── CMakeLists.txt
        ├── businesslogic.cpp
        └── businesslogic.h
					
					
						让我们查看一下库工程文件 (
						
src/businesslogic/CMakeLists.txt
						
						).
					
qt_add_library(businesslogic STATIC
    businesslogic.cpp
)
target_link_libraries(businesslogic PRIVATE Qt6::Core)
target_include_directories(businesslogic INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
					
					让我们浏览一下内容。
qt_add_library(businesslogic STATIC
    businesslogic.cpp
)
					
					
						The
						
							add_library
						
						command creates the library
						
businesslogic
						
						。稍后,将让应用程序链接到此目标。
					
						The
						
STATIC
						
						keyword denotes a static library. If we wanted to create a shared or dynamic library, we would use the
						
SHARED
						
						关键词。
					
target_link_libraries(businesslogic PRIVATE Qt6::Core)
						We have a static library and don't actually have to link other libraries. But as our library uses classes from
						
QtCore
						
						,添加依赖链接到
						
Qt6::Core
						
						。这会压入必要
						
QtCore
						
						include paths and preprocessor defines.
					
target_include_directories(businesslogic INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
					
					
						The library API is defined in the header file
						
businesslogic/businesslogic.h
						
						。通过调用
						
							target_include_directories
						
						,确保绝对路径
						
businesslogic
						
						directory is automatically added as an include path to all targets using our library.
					
						This frees us in
						
main.cpp
						
						from using relative paths to locate
						
businesslogic.h
						
						。取而代之,可以仅仅编写
					
#include <businesslogic.h>
最后,必须将库的子目录添加到顶层工程文件中:
add_subdirectory(src/app) add_subdirectory(src/businesslogic)
To use the library we created in the 上一章节 ,我们指导 CMake 链接到它:
target_link_libraries(helloworld PRIVATE
    businesslogic
    Qt6::Widgets
)
					
					
						This ensures that
						
businesslogic.h
						
						is found when main.cpp is compiled. Furthermore, the businesslogic static library will become a part of the
						
helloworld
						
						可执行文件。
					
						在 CMake 术语中,库
						
businesslogic
						
						specifies
						
							usage requirements
						
						(include 路径) 库 (应用程序) 的每个消费者都必须满足。
						
target_link_libraries
						
						command takes care of that.
					
We want to display some images in our application, so we add them using the Qt 资源系统 .
qt_add_resources(helloworld imageresources
    PREFIX "/images"
    FILES logo.png splashscreen.png
)
					
					The qt_add_resources command automatically creates a Qt resource containing the referenced images. From the C++ source code, you can access the images by prepending the specified resource prefix:
logoLabel->setPixmap(QPixmap(":/images/logo.png"));
The qt_add_resources command takes as the first argument either a variable name or a target name. We recommend to use the target-based variant of this command as shown in the example above.
						Translations of strings in a Qt project are encoded in
						
.ts
						
						files. See
						
							Qt 国际化
						
						了解细节。
					
						To add
						
.ts
						
						files to your project, use the
						
							qt_add_translations
						
						命令。
					
						The following example adds a German and a French translation file to the
						
helloworld
						
						目标:
					
qt_add_translations(helloworld
    TS_FILES helloworld_de.ts helloworld_fr.ts)
					
					
						This creates build system rules to automatically generate
						
.qm
						
						files from the
						
.ts
						
						files. By default, the
						
.qm
						
						files are embedded into a resource and are accessible under the
						
"/i18n"
						
						resource prefix.
					
						To update the entries in the
						
.ts
						
						file, build the
						
update_translations
						
						目标:
					
$ cmake --build . --target update_translations
						To trigger the generation of the
						
.qm
						
						files manually, build the
						
release_translations
						
						目标:
					
$ cmake --build . --target release_translations
						对于更多信息有关如何影响处理
						
.ts
						
						files and the embedding into a resource, see the
						
							qt_add_translations documentation
						
						.
					
						The
						
							qt_add_translations
						
						command is a convenience wrapper. For more fine-grained control of how
						
.ts
						
						files and
						
.qm
						
						files are handled, use the underlying commands
						
							qt_add_lupdate
						
						and
						
							qt_add_lrelease
						
						.
					
官方 CMake 文档编制 是使用 CMake 的宝贵资源。
官方 CMake 教程 covers common build system tasks.
书籍 专业 CMake:实践指南 提供 CMake 最相关特征的很好介绍。
构建采用 CMake 在命令行构建工程