Qt6基础篇(四)——解读Qt的CMakeLists

前言:
   开发c++ Qt6,有必要对CMakeLists有一些了解,方便管理和构建适合项目需求的工程。

1 CMakeLists

  通过Qt Creator创建了一个空窗体Demo,以下是其CMakeLists.txt。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
cmake_minimum_required(VERSION 3.5)         # 指定CMake的最低版本。

project(untitled VERSION 0.1 LANGUAGES CXX) # 指定工程名、项目版本号、语言类型。

set(CMAKE_AUTOUIC ON) # 启用自动转换.ui文件的功能。
set(CMAKE_AUTOMOC ON) # 启用自动处理.moc文件的功能。
set(CMAKE_AUTORCC ON) # 启用自动处理资源文件的功能。

set(CMAKE_CXX_STANDARD 17) # 设置C++项目的编译标准为C++17。
set(CMAKE_CXX_STANDARD_REQUIRED ON) # 指示CMake在编译项目时必须使用指定的C++标准版本。

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) # 指定库和组件。
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) # 根据版本动态的查找库和组件。跟上一行功能有重复的部分。

set(PROJECT_SOURCES # 指定源文件。
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) # 指定Qt6时生成的可执行文件。
qt_add_executable(untitled
MANUAL_FINALIZATION # 指示CMake不要自动调用最终的qt_auto_moc和qt_auto_rcc步骤。
${PROJECT_SOURCES}
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET untitled APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
if(ANDROID)
add_library(untitled SHARED
${PROJECT_SOURCES}
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(untitled
${PROJECT_SOURCES}
)
endif()
endif()

target_link_libraries(untitled PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) # 将Qt库中的Widgets模块链接到名为untitled的可执行文件目标。

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0) # Qt的版本若小于v6.1.0。
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.untitled) # 设置应用程序包标识符。
endif()
set_target_properties(untitled PROPERTIES # 设置目标属性。
${BUNDLE_ID_OPTION}
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)

include(GNUInstallDirs) # 包含GNU安装目录规范的脚本。
install(TARGETS untitled # 指定如何安装目标。
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(untitled) # 完成创建Qt可执行文件的最终步骤。
endif()

2 解析

  • set(CMAKE_AUTOUIC ON)
    含义:启用自动转换.ui文件的功能。
    作用:当设置为ON时,CMake会在构建过程中自动运行uic工具,将Qt Designer生成的.ui文件转换成C++源代码文件。这些源代码文件通常包含UI界面的定义,可以直接被编译器编译。

  • set(CMAKE_AUTOMOC ON)
    含义:启用自动处理.moc文件的功能。
    作用:当设置为ON时,CMake会在构建过程中自动运行moc工具,将带有Q_OBJECT宏的C++源文件生成对应的.moc文件。moc工具负责生成实现Qt元对象系统(Meta-Object System)所需的数据结构,这对于信号和槽机制(Signals and Slots)等Qt特性至关重要。

  • set(CMAKE_AUTORCC ON)
    含义:启用自动处理资源文件的功能。
    作用:当设置为ON时,CMake会在构建过程中自动运行rcc工具,将Qt的资源文件(.qrc文件)转换成C++源代码文件,这些文件包含了资源文件中所有资源的映射表。这样可以在运行时方便地访问这些资源,如图像、翻译文件等。

  • find_package()
    find_package() 是CMake中用于查找外部库的命令。它可以自动检测库的存在,并设置相应的变量,以便在构建过程中使用这些库。
    参数说明
    QT:库的名字,这里是Qt。
    NAMES:用于指定多个库名字的选项,这里指定了两个备选名字Qt6和Qt5。CMake会尝试按顺序查找这些名字。
    REQUIRED:表示如果找不到指定的库,则会导致CMake配置失败,并显示错误信息。
    COMPONENTS:用于指定库中的特定组件。在这里,指定了Widgets组件。

  • target_link_libraries(untitled PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) 是一条CMake命令,用于将Qt库中的Widgets模块链接到名为untitled的可执行文件目标。这条命令确保了在构建过程中,untitled可执行文件能够正确地链接到所需的Qt库组件。
    解释
    target_link_libraries:这是CMake的一个命令,用于将一个目标(如可执行文件或库)链接到其他库或目标上。
    untitled:这是要链接的目标名称,即之前通过qt_add_executable或其他命令创建的可执行文件目标。
    PRIVATE:这个关键字表示链接的库仅对当前目标可见,并不会传递给任何依赖于当前目标的目标。这意味着如果其他目标依赖于untitled,它们不会自动继承untitled链接的库。
    Qt${QT_VERSION_MAJOR}::Widgets:这是要链接的库名称。Qt${QT_VERSION_MAJOR}::Widgets表示链接Qt库中的Widgets模块,其中${QT_VERSION_MAJOR}是一个变量,包含了Qt的主要版本号(例如5或6)。这使得CMake能够根据当前系统中安装的Qt版本动态地选择正确的库。

  • include(GNUInstallDirs) 是CMake中的一条指令,用于包含GNU安装目录规范的脚本。这个脚本定义了一系列标准的安装路径,这些路径通常用于安装库、头文件、数据文件等。使用GNUInstallDirs可以确保你的项目遵循标准的文件安装布局,便于跨平台的安装和管理。
    作用
    GNUInstallDirs 主要有以下几个作用:
    标准化安装路径:提供了一组标准的安装路径,确保安装的文件位于预期的位置。
    跨平台兼容性:这些路径在不同的操作系统中通常是通用的,有助于提高项目的跨平台能力。
    简化配置:使用这些预定义的路径可以简化CMake脚本中的配置工作。
    定义的标准路径
    GNUInstallDirs 定义了一些常用的安装路径变量,例如:
    CMAKE_INSTALL_PREFIX:安装的基本前缀路径,默认通常是/usr/local。
    CMAKE_INSTALL_LIBDIR:库文件的安装路径。
    CMAKE_INSTALL_INCLUDEDIR:头文件的安装路径。
    CMAKE_INSTALL_DATADIR:数据文件的安装路径。
    CMAKE_INSTALL_BINDIR:可执行文件的安装路径。
    CMAKE_INSTALL_SBINDIR:系统管理员使用的可执行文件的安装路径。
    CMAKE_INSTALL_SYSCONFDIR:系统配置文件的安装路径。
    CMAKE_INSTALL_LOCALSTATEDIR:持久性的可修改数据的安装路径。
    CMAKE_INSTALL_SHAREDDIR:共享数据文件的安装路径。
    CMAKE_INSTALL_INCLUDEDIR:库的头文件的安装路径。
    CMAKE_INSTALL_LIBEXECDIR:库的可执行文件的安装路径。
    CMAKE_INSTALL_LOCALEXEC:本地化执行文件的安装路径。
    CMAKE_INSTALL_MANDIR:帮助文档的安装路径。
    CMAKE_INSTALL_INFODIR:info文档的安装路径。

  • install(TARGETS untitled …) 是CMake中的一个命令,用于指定如何安装目标(如可执行文件或库)。你提供的示例展示了如何为macOS应用程序设置不同的安装路径。下面详细解释这个命令及其参数,并提供一个完整的示例。
    详解
    你提供的install命令如下:
    cmake
    深色版本
    install(TARGETS untitled
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )
    参数解释
    TARGETS untitled:指定要安装的目标,这里是名为untitled的可执行文件。
    BUNDLE DESTINATION .:指定macOS应用程序的安装路径为当前目录(.)。
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}:指定库文件的安装路径为CMAKE_INSTALL_LIBDIR,通常为lib或lib64。
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}:指定可执行文件的安装路径为CMAKE_INSTALL_BINDIR,通常为bin。

  • qt_finalize_executable(untitled) 是CMake中Qt模块提供的一个函数,用于完成创建Qt可执行文件的最终步骤。这个函数通常是在使用qt_add_executable创建了一个Qt可执行文件之后调用的,以确保所有必要的Qt工具(如moc、uic和rcc)都被正确调用,并且所有生成的文件都已准备好用于编译。
    详解
    当你使用qt_add_executable创建一个Qt可执行文件时,通常需要调用一系列辅助函数来处理Qt特有的资源文件(如.ui文件和.qrc文件),并生成相应的源代码文件。这些步骤包括:
    调用moc工具:处理带有Q_OBJECT宏的源文件,生成元对象代码。
    调用uic工具:处理.ui文件,生成对应的C++源文件。
    调用rcc工具:处理.qrc资源文件,生成资源对象代码。
    qt_finalize_executable函数会确保这些步骤都已完成,并且所有生成的文件都已准备好用于编译。如果没有显式调用这个函数,CMake可能会忽略一些必要的处理步骤。