002-CMake 模板

auther: abinng date: 2026-03-18 17:19 createDate:2026-03-18 17:18

针对于 Qt6CMake 模板:

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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# ==============================================================================
# 1. 基础环境与工程设置
# ==============================================================================
# 规定使用此 CMakeLists 的最低 CMake 版本。Qt6 推荐 3.16 及以上。
cmake_minimum_required(VERSION 3.16)

# 定义项目名称为 ex01,并声明这是一个 C++ (CXX) 项目
project(ex01 CXX)

# 强制要求使用 C++17 标准(这是 Qt6 的硬性要求)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 预防万一,手动打开 MOC, UIC, RCC
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

# ==============================================================================
# 2. Qt 环境查找与配置
# ==============================================================================
# 指定你的 Qt SDK 路径。这告诉 CMake 去哪里找 Qt 的模块文件。
# 注意:如果路径发生改变,只需修改这里即可。
set(CMAKE_PREFIX_PATH "D:/Qt/6.5.3/mingw_64")

# 寻找 Qt6 库,REQUIRED 表示找不到就报错停止编译。
# COMPONENTS 后面跟着需要用到的 Qt 模块,这里引入了核心(Core)和界面(Widgets)模块。
find_package(Qt6 REQUIRED COMPONENTS Core Widgets)

# Qt6 引入的便捷指令:全局自动开启 MOC (元对象编译器)、UIC (UI文件转换) 和 RCC (资源文件转换)。
# 有了它,就不用手动处理 Qt 那些特殊的宏和文件了。
# 虽然有这个,我还是加上RCC的手动开启,就在上面的set(CMAKE_AUTORCC ON)
qt_standard_project_setup()

# ==============================================================================
# 3. 目标定义与链接
# ==============================================================================
# 将源码 (hello.cpp) 编译成名为 ex01 的可执行程序。
# qt_add_executable 是 CMake 原生 add_executable 的增强版,会处理 Qt 的一些初始化工作。
qt_add_executable(ex01
hello.cpp
)

# 将之前找到的 Qt 核心库和界面库链接到我们的 ex01 程序上。
target_link_libraries(ex01 PRIVATE Qt6::Core Qt6::Widgets)

# 设置目标属性
set_target_properties(ex01 PROPERTIES
WIN32_EXECUTABLE ON # Windows 下:作为图形界面程序运行,隐藏黑色的 CMD 控制台窗口
MACOSX_BUNDLE ON # macOS 下:打包成标准的 .app 应用程序包
)

# 旧版拷贝代码
# if (WIN32 AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
# set(DEBUG_SUFFIX)
# if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug")
# set(DEBUG_SUFFIX "d")
# endif ()
# set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}")
# if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
# set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
# if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
# set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
# endif ()
# endif ()
# if (EXISTS "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll")
# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E make_directory
# "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy
# "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll"
# "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
# endif ()
# foreach (QT_LIB Core Gui Widgets)
# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy
# "${QT_INSTALL_PATH}/bin/Qt6${QT_LIB}${DEBUG_SUFFIX}.dll"
# "$<TARGET_FILE_DIR:${PROJECT_NAME}>")
# endforeach (QT_LIB)
# endif ()

# 新版拷贝代码
# ==============================================================================
# 4. Windows 自动部署 (VSCode 调试环境搭建的灵魂)
# ==============================================================================
# 只有在 Windows 环境下才执行以下部署逻辑
if (WIN32 AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)

# 动态获取当前 Qt 版本下的 windeployqt.exe 工具的绝对路径
get_target_property(QT_QMAKE_EXECUTABLE Qt6::qmake IMPORTED_LOCATION)
get_filename_component(QT_BIN_DIR "${QT_QMAKE_EXECUTABLE}" DIRECTORY)
set(WINDEPLOYQT_EXECUTABLE "${QT_BIN_DIR}/windeployqt.exe")

# 如果成功找到了 windeployqt 工具
if (EXISTS "${WINDEPLOYQT_EXECUTABLE}")

# 在程序构建(编译)完成之后 (POST_BUILD),自动执行一条命令
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
# 执行 windeployqt.exe,分析刚刚生成的 .exe 文件
COMMAND "${WINDEPLOYQT_EXECUTABLE}"
# 添加以下参数可以屏蔽一些不必要的文件(如翻译文件),加快拷贝速度
--no-translations
--no-compiler-runtime
# 传入我们的目标文件绝对路径
"$<TARGET_FILE:${PROJECT_NAME}>"
COMMENT "正在运行 windeployqt 自动拷贝所需的 Qt DLL 和插件..."
)
else()
message(WARNING "未找到 windeployqt.exe 工具,程序可能因缺少 DLL 而无法直接运行。")
endif()

endif()