Qt 项目编译错误排查与解决记录
项目信息
- 项目路径 :
D:\ai_xi_bai_projext_code\code\Chap01_Intro\samp1_1HelloWorld - Qt 版本:Qt 6.2.4 MSVC 2019 64bit
- 编译器:MSVC 2019 (Visual Studio 2019)
- 操作系统:Windows 11
通用背景:为什么需要在 .pro 中手动配置 SDK 路径?
本项目的编译环境(Qt 6.2.4 + MSVC 2019)由于安装方式或环境配置原因,qmake 未能自动检测到 Windows SDK 的路径,导致编译器和链接器不知道去哪里找 SDK 的头文件和库文件。因此必须在 .pro 文件中手动指定 SDK 路径。
Windows SDK 的目录结构如下:
C:\Program Files (x86)\Windows Kits\10\
├── Include\10.0.19041.0\
│ ├── ucrt\ ← C 运行时头文件(stddef.h, crtdbg.h, stdio.h ...)
│ ├── um\ ← 用户模式 API 头文件(windows.h, shellapi.h ...)
│ └── shared\ ← 共享头文件
├── Lib\10.0.19041.0\
│ ├── ucrt\x64\ ← C 运行时库(libucrt.lib ...)
│ └── um\x64\ ← 用户模式 API 库(shell32.lib, user32.lib ...)
└── bin\10.0.19041.0\
└── x64\ ← SDK 工具(rc.exe, mt.exe ...)
下面三个错误,根源都是 .pro 中手动配置的 SDK 路径不完整 ------只配了 ucrt,缺少 um 和 shared。
错误一:C1083 找不到 UCRT 头文件(stddef.h / crtdbg.h / yvals.h)
错误现象
cstddef:12: error: C1083: 无法打开包括文件: "stddef.h": No such file or directory
yvals.h:12: error: C1083: 无法打开包括文件: "crtdbg.h": No such file or directory
cstddef:12: error: C1083: 无法打开包括文件: "stddef.h": No such file or directory
根因
这三个是编译阶段的错误,比链接错误更早出现。
stddef.h、crtdbg.h是 UCRT(Universal C Runtime) 的头文件- 它们被 MSVC 的
cstddef、yvals.h等 C++ 标准库头文件间接引用 - 只有把
$$SDK_ROOT/Include/$$SDK_VER/ucrt加入INCLUDEPATH,编译器才能找到它们
当 .pro 中未添加任何 SDK Include 路径时,编译器在默认搜索路径中找不到这些头文件,导致编译失败。这些错误先于链接错误出现,是排查的第一步。
错误二:LNK1104 找不到系统库(shell32.lib)
错误现象
:-1: error: LNK1104: 无法打开文件"shell32.lib"
根因
这是链接阶段 的错误。编译通过后,链接器需要将系统 API 库(如 shell32.lib)链接到可执行文件。
| Windows SDK Lib 子目录 | 包含内容 |
|---|---|
ucrt\x64\ |
C 运行时库(libucrt.lib 等) |
um\x64\ |
系统 API 库(shell32.lib、user32.lib、kernel32.lib 等) |
shell32.lib位于Lib\10.0.19041.0\um\x64\- 但
.pro中只添加了-L$$SDK_ROOT/Lib/$$SDK_VER/ucrt/x64(UCRT 库路径) - 缺少了
um/x64路径 ,链接器在 UCRT 目录下找不到shell32.lib
错误三:LNK1158 找不到 rc.exe
错误现象
:-1: error: LNK1158: 无法运行"rc.exe"
排查过程
-
确认 rc.exe 存在:
C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\rc.exe存在C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\rc.exe存在
-
检查 VS 2019 MSVC 工具链目录:
D:\visual_studio_2019\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\下没有rc.exe
-
检查 PATH 环境变量:
- PATH 中未包含 Windows SDK 的 bin 目录
根因
rc.exe(资源编译器)是 Windows SDK 的工具,不属于 MSVC。链接器在链接完成后需要用 rc.exe 将 manifest 嵌入 exe,但 PATH 中找不到 SDK bin 目录。
统一解决方案
第一步:修复 .pro 文件(解决错误一 + 错误二)
补全所有 3 个 SDK 子目录的 Include(编译用)和 Lib(链接用)路径:
qmake
SDK_ROOT = "C:/Program Files (x86)/Windows Kits/10"
SDK_VER = "10.0.19041.0"
# Include 路径 ------ 编译器找头文件用
INCLUDEPATH += $$SDK_ROOT/Include/$$SDK_VER/ucrt # C 运行时头文件(stddef.h 等)
INCLUDEPATH += $$SDK_ROOT/Include/$$SDK_VER/um # 系统 API 头文件
INCLUDEPATH += $$SDK_ROOT/Include/$$SDK_VER/shared # 共享头文件
# Lib 路径 ------ 链接器找 .lib 用
LIBS += -L$$SDK_ROOT/Lib/$$SDK_VER/ucrt/x64 # C 运行时库
LIBS += -L$$SDK_ROOT/Lib/$$SDK_VER/um/x64 # 系统 API 库(shell32.lib 等)
# 额外的编译选项
QMAKE_CXXFLAGS += /I"$$SDK_ROOT/Include/$$SDK_VER/ucrt"
QMAKE_CXXFLAGS += /I"$$SDK_ROOT/Include/$$SDK_VER/um"
QMAKE_CXXFLAGS += /I"$$SDK_ROOT/Include/$$SDK_VER/shared"
第二步:添加 SDK bin 到 PATH(解决错误三)
将以下路径添加到用户环境变量 PATH:
C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64
第三步:清理并重新构建
- 删除旧的 build 目录(让 qmake 重新生成 Makefile)
- 重启 Qt Creator(让新 PATH 生效)
- 重新 qmake -> Build
提示 :如果通过 Visual Studio 的 Developer Command Prompt for VS 2019 启动 Qt Creator,开发环境会自动配好所有 SDK 路径,从根本上避免以上三个错误。
经验总结
-
Windows SDK 目录结构要记清:
Include/下有ucrt/、um/、shared/三个子目录Lib/下同样有ucrt/、um/两个子目录bin/下有rc.exe等工具
-
手动配置 SDK 路径时 :必须同时添加 Include 和 Lib 的所有必要子目录(ucrt + um + shared),缺一不可
-
三个错误的本质是同一问题:
- 缺
ucrtInclude → 编译报 C1083(找不到 stddef.h, crtdbg.h) - 缺
umLib → 链接报 LNK1104(找不到 shell32.lib) - 缺
binPATH → 链接后报 LNK1158(找不到 rc.exe)
- 缺
-
出问题看 Makefile :
.pro修改后运行 qmake 会生成 Makefile,Makefile.Debug 里的LIBS、INCPATH等变量直接反映最终编译配置,是排查的关键 -
最佳的启动方式 :通过 Developer Command Prompt for VS 启动 Qt Creator,SDK 路径、环境变量全都自动配好,可以彻底避免此类问题
现在每次运行都会标红一次,再次运行才可以成功
cpp
SDK_ROOT = "C:/Program Files (x86)/Windows Kits/10"
SDK_VER = "10.0.19041.0"
INCLUDEPATH += $$SDK_ROOT/Include/$$SDK_VER/ucrt
INCLUDEPATH += $$SDK_ROOT/Include/$$SDK_VER/um
INCLUDEPATH += $$SDK_ROOT/Include/$$SDK_VER/shared
LIBS += -L$$SDK_ROOT/Lib/$$SDK_VER/ucrt/x64
LIBS += -L$$SDK_ROOT/Lib/$$SDK_VER/um/x64
只保留以上代码即可,删除,下面这三行
cpp
QMAKE_CXXFLAGS += /I"$$SDK_ROOT/Include/$$SDK_VER/ucrt"
QMAKE_CXXFLAGS += /I"$$SDK_ROOT/Include/$$SDK_VER/um"
QMAKE_CXXFLAGS += /I"$$SDK_ROOT/Include/$$SDK_VER/shared"