适用环境:CLion 2026.x · Qt 5.12.12(MinGW 或 MSVC 套件)· Windows 10/11 本文以本机实际跑通的配置为例,按"从零创建 → 构建 → 运行"的顺序整理,记录了每一步的做法、原理和踩过的坑。 正文以 MinGW 流程为主线;使用 Visual Studio(MSVC)时见附录 D。
CMakeLists.txt已支持两种工具链自动切换。 最后验证日期:2026-10-27
0. 核心原则:编译器和 Qt 套件的 ABI 必须匹配
Qt 的二进制库是用某种编译器(即某种 C++ ABI)构建的。你的项目必须用同一套编译器去链接它:
| Qt 套件 | 目录示例 | 必须搭配的编译器 |
|---|---|---|
| MinGW 版 | C:\Qt\Qt5.12.12\5.12.12\mingw73_64 |
MinGW-w64(GCC / g++) |
| MSVC 版 | C:\Qt\Qt5.12.12\5.12.12\msvc2017_64 |
MSVC(Visual Studio) |
为什么不能混用?
-
头文件是通用的,所以编译阶段能通过,看起来一切正常。
-
但链接阶段的符号名完全不同:
- GCC 用 Itanium 修饰名:
_ZN12QApplicationC1ERiPPci - MSVC 用 MSVC 修饰名:
??0QApplication@@QEAA@... - MSVC 的导入库是
.lib,MinGW 的是.a。
- GCC 用 Itanium 修饰名:
-
混用的结果是:链接失败(一堆 undefined reference) ;即使侥幸链接成功,运行时也会因为导入表解析失败而秒退(
0xC0000139)。 -
32 位和 64 位套件同样不能混用(会得到
0xC000007B)。
一句话:选了 MinGW 工具链就只用
mingw73_64;选了 MSVC 就只用msvc2017_64,从头到尾不能混。
1. 确认本机环境
本次成功运行时的配置:
| 项目 | 值 |
|---|---|
| CLion | 2026.2.4 |
| 编译器(MinGW 模式) | CLion 自带的 MinGW-w64(GCC 14,ToolSet 14.0 w64) |
| Qt 套件(MinGW 模式) | C:\Qt\Qt5.12.12\5.12.12\mingw73_64(由 GCC 7.3 构建) |
| 编译器(MSVC 模式) | VS 2017 Community(MSVC 14.16 / v141,Architecture amd64) |
| Qt 套件(MSVC 模式) | C:\Qt\Qt5.12.12\5.12.12\msvc2017_64 |
| Qt 自带 MinGW | C:\Qt\Qt5.12.12\Tools\mingw730_64(可选,用于"完全匹配"的场景) |
| 生成器 | Ninja(CLion 自带) |
| 构建类型 | Debug |
GCC 的 C++ ABI 向下兼容:用 GCC 14 编译、链接 Qt 5.12(GCC 7.3 构建)是可行的,实测通过。若追求完全一致,可以改用 Qt 自带的 MinGW 7.3,见附录 B。 MSVC 模式的工具链配置见附录 D。
2. 设置 PATH(最容易踩的坑)
2.1 为什么 PATH 会影响项目
即使 CMakeLists.txt 里已经写死了 Qt 路径,下面这些工具仍可能从 PATH 里按名字找 DLL:
windeployqt:部署 Qt DLL 时会解析依赖,PATH 中的同名 DLL 可能被优先命中;- 其他命令行工具(qmake、Qt Creator 相关组件等)。
两个套件里有大量完全同名 的文件(Qt5Cored.dll、Qt5Widgetsd.dll......),而 Windows 的查找规则是 PATH 从上到下,第一个匹配就生效。
2.2 正确的做法
原则:当前所使用的 Qt 套件的 bin 必须排在最前面(或者只保留它)。
MinGW 模式:
makefile
C:\Qt\Qt5.12.12\5.12.12\mingw73_64\bin ← 在上面
C:\Qt\Qt5.12.12\5.12.12\msvc2017_64\bin ← 在下面(可删)
MSVC 模式:
makefile
C:\Qt\Qt5.12.12\5.12.12\msvc2017_64\bin ← 在上面
C:\Qt\Qt5.12.12\5.12.12\mingw73_64\bin ← 在下面(可删)
最省事的做法:只保留当前套件对应的那一条,切换工具链时再更换。
修改方法:
Win + R→ 输入sysdm.cpl→ 回车- "高级" → "环境变量"
- 在"用户变量"和"系统变量"的
Path中编辑顺序 - 确定保存
⚠️ 改完 PATH 必须重启 CLion(甚至重启资源管理器/注销),因为已经运行的进程不会重新读取环境变量。
3. 在 CLion 中配置工具链
路径:File → Settings → Build, Execution, Deployment → Toolchains
-
确保存在一个 MinGW 工具链,并设为默认(Default):
- 使用 CLion 自带:Toolset 指向
...\CLion 2026.2.4\bin\mingw - 或使用 Qt 自带:Toolset 指向
C:\Qt\Qt5.12.12\Tools\mingw730_64(见附录 B)
- 使用 CLion 自带:Toolset 指向
-
再检查
Settings → Build, Execution, Deployment → CMake:- 选中
Debug这个 profile - Toolchain 必须指定为上面那个 MinGW 工具链
- 注意:只添加工具链是不够的,必须在 CMake profile 里选中它
- 选中
使用 Visual Studio(MSVC) 工具链时步骤相同:工具链选
Visual Studio,Qt 套件换为msvc2017_64。完整流程见附录 D。
4. 新建工程
-
File → New → Project -
选择 C++ Executable(或 Qt 模板),设置名称和位置,例如:
- 名称:
ClionCplusPlus - 位置:
E:\AI\Qt\ClionCplusPlus
- 名称:
-
在 Qt 安装路径的选项中,选择与工具链匹配的套件:
javascriptMinGW → C:/Qt/Qt5.12.12/5.12.12/mingw73_64 MSVC → C:/Qt/Qt5.12.12/5.12.12/msvc2017_64 -
创建完成后会得到
main.cpp和CMakeLists.txt。
4.1 main.cpp 示例
arduino
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QPushButton button("Hello world!", nullptr);
button.resize(200, 100);
button.show();
return QApplication::exec();
}
5. 写对 CMakeLists.txt(逐行注释版)
工程根目录的 CMakeLists.txt 与下面内容一致,可以直接对照阅读。
bash
# ============================================================
# ClionCplusPlus ------ CLion + Qt5 工程配置(MinGW / MSVC 通用)
# 注意:Qt 套件必须与编译器 ABI 匹配
# MinGW → mingw73_64 MSVC → msvc2017_64
# ============================================================
# CMake 最低版本;CLion 2026 自带 CMake 4.x(可降到 3.16 兼容旧环境)
cmake_minimum_required(VERSION 4.3)
# 工程名,后续可通过 ${PROJECT_NAME} 引用
project(ClionCplusPlus)
# 使用 C++17
set(CMAKE_CXX_STANDARD 17)
# Qt 必备的自动处理开关
set(CMAKE_AUTOMOC ON) # 自动运行 moc:处理带 Q_OBJECT 的类
set(CMAKE_AUTORCC ON) # 自动编译 .qrc 资源文件
set(CMAKE_AUTOUIC ON) # 自动运行 uic:处理 .ui 界面文件
# ------------------------------------------------------------
# Qt 套件路径(最容易出错的地方)
# MinGW 工具链 → C:/Qt/Qt5.12.12/5.12.12/mingw73_64
# MSVC 工具链 → C:/Qt/Qt5.12.12/5.12.12/msvc2017_64
# 切换工具链后要 Reset CMake 缓存,并删除旧的构建目录
# ------------------------------------------------------------
if (MSVC)
set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.12.12/5.12.12/msvc2017_64")
else ()
set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.12.12/5.12.12/mingw73_64")
endif ()
# 查找 Qt5 模块;REQUIRED 表示找不到直接报错
# 成功后 Qt5_DIR 会写入 CMakeCache.txt(优先级高于本文件中的路径)
find_package(Qt5 COMPONENTS
Core
Gui
Widgets
REQUIRED)
# 生成可执行文件 ClionCplusPlus.exe(Windows)
add_executable(ClionCplusPlus main.cpp)
# 链接用到的 Qt 模块
target_link_libraries(ClionCplusPlus
Qt5::Core
Qt5::Gui
Qt5::Widgets
)
# ============================================================
# Windows 下自动部署 Qt 运行时(DLL + platforms 插件)
# 不做这一步,exe 可能因缺少 Qt5Cored.dll / qwindowsd.dll 无法启动
# ============================================================
if (WIN32)
# 在 Qt 套件 bin 目录中查找 windeployqt
find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${CMAKE_PREFIX_PATH}/bin" NO_CACHE)
if (WINDEPLOYQT_EXECUTABLE)
# 链接完成后执行:自动按 Debug/Release 部署对应 DLL
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND "${WINDEPLOYQT_EXECUTABLE}" --no-translations
"$<TARGET_FILE:${PROJECT_NAME}>"
COMMENT "Deploying Qt runtime")
endif ()
endif ()
5.1 逐段说明
| 配置 | 作用 |
|---|---|
CMAKE_CXX_STANDARD 17 |
使用 C++17(Qt 5.12 至少需要 C++11) |
CMAKE_AUTOMOC/AUTORCC/AUTOUIC |
自动处理 Q_OBJECT、.qrc、.ui,Qt 项目必备 |
CMAKE_PREFIX_PATH |
告诉 find_package 去哪里找 Qt,必须与编译器 ABI 匹配 |
find_package(Qt5 ...) |
找到 Qt5 的 CMake 配置(会设置 Qt5_DIR) |
target_link_libraries |
链接 Core / Gui / Widgets 三个模块 |
windeployqt POST_BUILD |
构建后自动把 Qt DLL 和 platforms 插件部署到 exe 旁边 |
5.2 模板生成的坑
CLion 的 Qt 模板可能会生成一句无效的路径,例如:
bash
set(CMAKE_PREFIX_PATH "ClionCplusPlus") # ❌ 这是工程名,不是路径
它会导致:
find_package退化到从 PATH / 环境里猜测 Qt(于是可能猜到 MSVC 版);- POST_BUILD 的拷贝路径变成
ClionCplusPlus/../../bin/Qt5Core.dll这种不存在的路径。
务必把它改成真实的 Qt 套件路径。
另外,Qt 模板自带的手工拷贝 DLL 代码(add_custom_command ... copy Qt5Core.dll)在 MinGW Debug 下会拷成 release 版 DLL,容易导致运行时报错。建议直接删掉,改用上面的 windeployqt。
6. 重置 CMake 缓存(换 Qt 套件后必做)
这是本次调试中最隐蔽的坑。
6.1 现象
明明把 CMAKE_PREFIX_PATH 改成了 mingw73_64,重新 Reload,构建却仍然链接 msvc2017_64 的 .lib。
6.2 原因
find_package(Qt5) 第一次成功后,会把 Qt5_DIR 写进 CMakeCache.txt。 缓存变量的优先级高于 CMakeLists.txt 里的 CMAKE_PREFIX_PATH,所以:
- 只改 CMakeLists → 无效
- 只点 Reload CMake Project → 无效(缓存还在)
- 只有 Reset Cache 才会让
Qt5_DIR重新按新路径查找
6.3 正确操作
objectivec
Tools → CMake → Reset Cache and Reload Project
或者(更彻底):
lua
完全退出 CLion → 删除 cmake-build-debug 目录 → 重新打开工程
6.4 验证
构建目录下 CMakeCache.txt 里应该是:
bash
Qt5_DIR:PATH=C:/Qt/Qt5.12.12/5.12.12/mingw73_64/lib/cmake/Qt5
build.ninja 的链接行应该是 MinGW 的 .a 库,而不是 .lib。
7. 构建与运行
- 构建 :
Ctrl + F9(Build → Build Project) - 运行 :
Shift + F10(Run → Run) - 也可以直接点
main函数左边行号旁的绿色三角 → Run 'ClionCplusPlus'
点击
main.cpp里的绿色三角,本质上是"构建并运行ClionCplusPlus这个 target",和顶部工具栏的运行按钮完全一样,不需要特殊配置。
运行后应弹出:
┌──────────────────┐
│ Hello world! │
└──────────────────┘
8. Qt DLL 部署:windeployqt 的原理
8.1 为什么需要部署
Qt 程序运行时需要这些文件:
| 文件 | 作用 |
|---|---|
Qt5Cored.dll |
Qt Core(Debug 版带 d 后缀) |
Qt5Guid.dll |
Qt Gui |
Qt5Widgetsd.dll |
Qt Widgets |
platforms/qwindowsd.dll |
Windows 平台插件,没有它窗口起不来 |
libstdc++-6.dll 等 |
MinGW 编译器运行库(取决于工具链) |
Debug 和 Release 的 DLL 文件名不同 (Qt5Cored.dll vs Qt5Core.dll),不能混用。
8.2 用 windeployqt 自动部署
perl
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND "${WINDEPLOYQT_EXECUTABLE}" --no-translations
"$<TARGET_FILE:${PROJECT_NAME}>")
windeployqt 会:
- 扫描 exe,自动判断 Debug / Release;
- 复制对应的 Qt DLL;
- 复制
platforms、styles、imageformats等插件; - 默认对 MinGW 调试库做裁剪,减小体积。
8.3 两个注意事项
windeployqt不会覆盖已存在的同名文件。 所以一旦构建目录里被放进了错误 ABI 的 DLL,后续构建会一直沿用。 → 切换 Qt 套件 / 编译器后,重建前请删除cmake-build-debug整个目录。- POST_BUILD 只在目标重新链接时执行。 如果只是删掉了 DLL 而没有触发重新链接,部署步骤不会运行。 → 删掉
cmake-build-debug重新构建最省心。
9. 常见错误速查表
| 现象 | 根本原因 | 解决办法 |
|---|---|---|
Linking CXX executable ... FAILED,伴随大量 undefined reference to '_ZN12QApplication...' |
GCC 编译的目标文件去链接 MSVC 的 .lib(ABI 不匹配) |
检查 Qt5_DIR 是否指向当前工具链对应的套件(如 MinGW 工程却指向 msvc2017_64);改 CMAKE_PREFIX_PATH → Reset Cache |
改了 CMAKE_PREFIX_PATH 但构建仍链接旧 Qt |
Qt5_DIR 已写入 CMake 缓存,优先级更高 |
Tools → CMake → Reset Cache and Reload Project |
构建成功,但运行/双击后没有任何窗口,退出码 -1073741511 |
0xC0000139(STATUS_ENTRYPOINT_NOT_FOUND):构建目录里的 Qt DLL 是另一种 ABI(例如 MinGW 工程配到了 MSVC 版 DLL) |
删除 cmake-build-debug;确保 PATH 中当前所用套件排在最前面;重新构建 |
退出码 -1073741515 |
0xC0000135(DLL 未找到) |
检查 Qt5Cored.dll、libstdc++-6.dll 等是否在 exe 旁边 |
退出码 -1073741701 |
0xC000007B(Bad Image):32/64 位混用 |
工具链和 Qt 位数必须一致 |
弹窗 This application failed to start because no Qt platform plugin could be initialized |
缺少 platforms/qwindowsd.dll |
运行 windeployqt,或检查插件目录 |
直接双击 exe 报缺少运行库(MinGW:libstdc++-6.dll / libgcc_s_seh-1.dll;MSVC:vcruntime140d.dll / msvcp140d.dll) |
没有部署编译器运行库 | MinGW 从编译器 bin 复制到 exe 旁;MSVC 安装 VC 运行库;或给 windeployqt 加 --compiler-runtime |
| 修改 PATH 后 CLion 行为没变化 | 已运行的进程不会重新读取环境变量 | 完全重启 CLion(必要时注销系统) |
9.1 如何判断 DLL 是哪种 ABI
看 DLL 的导出符号名:
- 以
_ZN/_Z开头 → GCC(Itanium)修饰名 → MinGW 版 - 以
??0、??1、@等开头 → MSVC 修饰名 → MSVC 版
例如本次故障中,Qt5Widgetsd.dll 的全部 9011 个导出都是 ??0QPushButton@@...,而 exe 需要的是 _ZN11QPushButtonC1ERK7QStringP7QWidget,不匹配 → 加载失败。
10. 成功验收清单
构建完成后逐项检查:
clion-environment.txt中的工具链与所选一致(MinGW 为ToolSet: ... mingw,MSVC 为ToolSet: MSVC ...)CMakeCache.txt中Qt5_DIR指向当前工具链对应的套件(MinGW →mingw73_64,MSVC →msvc2017_64)build.ninja的链接行与工具链一致(MinGW 为libQt5Cored.a,MSVC 为Qt5Cored.lib)cmake-build-debug下存在ClionCplusPlus.exe- 存在
Qt5Cored.dll、Qt5Guid.dll、Qt5Widgetsd.dll - 存在
platforms\qwindowsd.dll - 运行后弹出 "Hello world!" 窗口,Run 窗口不出现
0xC0000139
11. 本机最终配置汇总
objectivec
【MinGW 模式】
Qt 套件 C:\Qt\Qt5.12.12\5.12.12\mingw73_64
Qt 编译器路径 C:\Qt\Qt5.12.12\Tools\mingw730_64(可选)
CLion 工具链 MinGW(CLion 自带 GCC 14 或 Qt 的 GCC 7.3)
PATH 顺序 mingw73_64\bin 在最前
【MSVC 模式】
Qt 套件 C:\Qt\Qt5.12.12\5.12.12\msvc2017_64
CLion 工具链 Visual Studio(VS 2017 Community,amd64,Platform 留空)
PATH 顺序 msvc2017_64\bin 在最前
【通用】
CMake 路径 CMakeLists.txt 按编译器自动选择(MSVC → msvc2017_64)
部署方式 windeployqt POST_BUILD(自动使用当前套件)
构建目录 E:\AI\Qt\ClionCplusPlus\cmake-build-debug
切换工具链 删除构建目录 / Reset Cache + 重启 CLion
附录 A:快速复现步骤(新机器)
- 安装 Qt,勾选需要的套件(MinGW 的
mingw73_64或 MSVC 的msvc2017_64)。 - 调整 PATH:把所用套件的
bin放在最前面(或只保留它)。 - 重启 CLion,配置对应工具链(MinGW 或 Visual Studio),并在 CMake profile 中选中。
- 新建工程,选择与工具链匹配的 Qt 套件目录。
CMakeLists.txt中按编译器自动选择CMAKE_PREFIX_PATH,并加入windeployqtPOST_BUILD。- 切换过工具链时:删除构建目录 /
Reset Cache and Reload Project。 Ctrl+F9构建,Shift+F10运行。
附录 B:使用 Qt 自带的 MinGW 7.3(完全匹配方案)
Qt 5.12.12 的 mingw73_64 是用 GCC 7.3 构建的。若想彻底避免版本跨度问题:
File → Settings → Build, Execution, Deployment → Toolchains- 点
+→ MinGW - Toolset 选择:
C:\Qt\Qt5.12.12\Tools\mingw730_64 - 到
Settings → Build, Execution, Deployment → CMake,在 Debug profile 里把 Toolchain 换成刚创建的 Tools → CMake → Reset Cache and Reload Project- 重新构建
附录 C:排查时值得看的文件
| 文件 | 说明 |
|---|---|
cmake-build-debug\CMakeCache.txt |
查看 Qt5_DIR、CMAKE_CXX_COMPILER 等最终生效值 |
cmake-build-debug\CMakeFiles\clion-environment.txt |
查看当前工具链(ToolSet / Ninja 路径) |
cmake-build-debug\build.ninja |
查看实际链接的库(.a 还是 .lib) |
cmake-build-debug.ninja_log |
查看哪些步骤真正执行过(有没有 link 记录) |
| Run 窗口的 exit code | 快速定位是链接、DLL 还是运行时问题 |
附录 D:切换到 Visual Studio(MSVC)工具链
Qt 的 msvc2017_64 套件是用 VS 2017 构建的。本机安装的是 VS 2017 Community(MSVC 14.16 / v141),与它完全匹配。
本机
C:\Program Files\Microsoft Visual Studio\18(VS 2026)没有安装 C++ 工作负载 (没有VC\Tools\MSVC目录),因此只能选 VS 2017。
D.1 配置 Visual Studio 工具链
-
File → Settings → Build, Execution, Deployment → Toolchains -
CLion 通常会自动检测到:
javaVisual Studio C:\Program Files (x86)\Microsoft Visual Studio\2017\Community -
检查选项:
- Architecture:
x64(amd64) - Platform / 平台:留空 (
store/uwp/onecore是 UWP/Store 目标,桌面 Qt 程序不能用) - 状态无红色报错(编译器与 Windows SDK 都已检测到)
- Architecture:
-
点工具链上方的上移箭头 / Make Default,设为默认
D.2 分配给 CMake profile(关键)
Settings → Build, Execution, Deployment → CMake → 选中 Debug →
- Toolchain:选择
Visual Studio - Build directory:保持
cmake-build-debug即可
只添加工具链或设为默认是不够 的,必须在 CMake profile 里明确选中它。 生效标志:
cmake-build-debug\CMakeFiles\clion-environment.txt中出现cl.exe(MSVC),而不是c++.exe(MinGW)。
D.3 Qt 路径自动适配
工程中的 CMakeLists.txt 已按编译器自动选择 Qt 套件:
scss
if (MSVC)
set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.12.12/5.12.12/msvc2017_64")
else ()
set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.12.12/5.12.12/mingw73_64")
endif ()
D.4 清理并重建
- 完全退出 CLion
- 调整 PATH:使用 MSVC 时,把
C:\Qt\Qt5.12.12\5.12.12\msvc2017_64\bin放到mingw73_64\bin之前(或只保留 msvc) - 删除整个
cmake-build-debug(换编译器必须重建,同时清掉旧 ABI 的 DLL) - 重新启动 CLion → 等 CMake configure 完成
Ctrl+F9构建 →Shift+F10运行
D.5 验证清单
| 检查项 | MSVC 模式下应为 |
|---|---|
clion-environment.txt |
ToolSet: MSVC x64 ... |
CMakeCache.txt → CMAKE_CXX_COMPILER |
.../VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64/cl.exe |
CMakeCache.txt → Qt5_DIR |
.../msvc2017_64/lib/cmake/Qt5 |
| 构建目录 DLL | Qt5Cored.dll 等来自 msvc2017_64 套件 |
D.6 注意事项
- Debug 版 MSVC 程序依赖
vcruntime140d.dll、msvcp140d.dll、ucrtbased.dll。在 CLion 内运行由 VS 环境提供;直接双击 exe 若报缺失,可改用 Release,或给windeployqt加--compiler-runtime。 - 切回 MinGW 时:把 CMake profile 的 Toolchain 改回 MinGW → 删除
cmake-build-debug→ Reset Cache → 把 PATH 里的 mingw 放回前面。
退出码换算:
-1073741511=0xC0000139,-1073741515=0xC0000135,-1073741701=0xC000007B。