VS2022 编译 Qt 5.7.1
2025-07-26 16:19:44

之前写过一篇 VS2017 编译 Qt 5.7.1 文章介绍了 Qt 的编译方式。为了支持 XP 系统,不得不使用 VS2017 来编译,这带来一个问题:无法享受 C++ 20 以后的现代式编程。
好在有 YY-Thunks 这个神器可以解决 XP 缺失一些 API 的问题。
总体的编译流程和之前差不多,只是一些配置细节不同。

准备

Qt 5.7.1:https://download.qt.io/new_archive/qt/5.7/5.7.1/submodules/
VC-LTL5 v5.2.2:https://github.com/Chuyu-Team/VC-LTL5/releases/tag/v5.2.2


其中 VC-LTL5 是可选的,用了它后可以让 Qt 和应用程序共享 crt 了,这样可以减少程序的体积。
不过要注意的是,引入 VC-LTL5 后如果模块(DLL)之间存在互相访问 C++ 数据类型的话,则双方都要引入 VC-LTL5,否则会引发内存访问异常。

编译 qtbase

我不喜欢下载完整的源码编译,太笨重了,我更喜欢按需编译,只编译用到的部分。
下载 qtbase-opensource-src-5.7.1.7z 并解压。

编辑 msvc-desktop.conf

DEFINES后追加_WIN32_WINNT=0x0501,避免使用 Vista 系统后才有的 Win32 API

1
DEFINES += UNICODE WIN32 _UNICODE _WIN32_WINNT=0x0501


要在 XP 系统上运行,则必须将子系统版本改为5.01,在任意位置插入QMAKE_SUBSYSTEM_SUFFIX=,5.01

1
2
3
QMAKE_LFLAGS_CONSOLE    = /SUBSYSTEM:CONSOLE
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS
QMAKE_SUBSYSTEM_SUFFIX = ,5.01

-MD改为-MT,这样编译出的 Qt DLL 文件就不依赖VC运行库了

1
2
3
QMAKE_CFLAGS_RELEASE    = -O2 -MT
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi
QMAKE_CFLAGS_DEBUG = -Zi -MTd

如果不希望产生 .pdb 文件,则可以将-Zi去掉,并找到QMAKE_LFLAGS_DEBUG

1
QMAKE_LFLAGS_DEBUG      = /DEBUG

改为

1
QMAKE_LFLAGS_DEBUG      = /DEBUG:NONE

编译

启动 VS2022 32位命令行工具

1
2
3
4
5
6
7
8
9
10
11
12
13
"%programfiles%\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\Build\vcvars32.bat" x86
cd C:\Qt\qtbase-opensource-src-5.7.1
mkdir build
cd build

# 启用 VC-LTL5
set WindowsTargetPlatformMinVersion=5.1.2600.0
"C:\VC-LTL-Binary-v5.2.2\VC-LTL helper for nmake.cmd"

# 编译
..\configure.bat -prefix "C:\qt5.7.1-vc144-i386" -platform win32-msvc2015 -confirm-license -opensource -debug-and-release -nomake examples -nomake tests -no-directwrite -no-angle -opengl desktop -mp
nmake
nmake install

_FILE_ID_128 类型重定义

这是第1个错误

1
C:\Qt\qtbase-opensource-src-5.7.1\src\corelib\io\qfilesystemengine_win.cpp(629): error C2011: “_FILE_ID_128”:“struct”类型重定义

找到qfilesystemengine_win.cpp629行:

1
2
3
4
5
6
// MinGW-64 defines FILE_ID_128 as of gcc-4.8.1 along with FILE_SUPPORTS_INTEGRITY_STREAMS
#if !(defined(Q_CC_MINGW) && defined(FILE_SUPPORTS_INTEGRITY_STREAMS))
typedef struct _FILE_ID_128 {
BYTE Identifier[16];
} FILE_ID_128, *PFILE_ID_128;
#endif // !(Q_CC_MINGW && FILE_SUPPORTS_INTEGRITY_STREAMS)

因为新SDK中已经有定义了,所以会提示重定义错误,直接删除这一段即可。

“binary_function”: 不是 “std” 的成员

这是第2个错误

1
C:\Qt\qtbase-opensource-src-5.7.1\src\tools\qlalr\compress.cpp(40): error C2039: "binary_function": 不是 "std" 的成员

解决方法:在compress.cpp中添加头文件#include <functional>

缺少 tmschema.h

这是第3个错误

1
C:\Qt\qtbase-opensource-src-5.7.1\src\widgets\styles\qwindowsxpstyle_p_p.h(64): fatal error C1083: 无法打开包括文件: “tmschema.h”: No such file or directory

这个头文件仅在 SDK v7.1A 中才有。可以从 v7.1A SDK 中提取出这个头文件,或从这里下载 https://github.com/tpn/winsdk-7/raw/refs/heads/master/v7.1A/Include/Tmschema.h 文件,将它放build\include目录中即可。

“NIIF_USER”: 未声明的标识符

这是第4个错误

1
2
3
4
C:\Qt\qtbase-opensource-src-5.7.1\src\widgets\util\qsystemtrayicon_win.cpp(262): error C2065: “NIIF_USER”: 未声明的标识符
C:\Qt\qtbase-opensource-src-5.7.1\src\widgets\util\qsystemtrayicon_win.cpp(270): error C2065: “NIF_SHOWTIP”: 未声明的标识符
C:\Qt\qtbase-opensource-src-5.7.1\src\widgets\util\qsystemtrayicon_win.cpp(283): error C2065: “NIF_SHOWTIP”: 未声明的标 识符
C:\Qt\qtbase-opensource-src-5.7.1\src\widgets\util\qsystemtrayicon_win.cpp(327): error C2065: “NOTIFYICON_VERSION_4”: 未声明的标识符

这3个宏是 Vista 后才有的,在qsystemtrayicon_win.cpp文件中追加即可:

1
2
3
4
5
6
7
8
9
10
11
#ifndef NIIF_USER
#define NIIF_USER 0x00000004
#endif

#ifndef NIF_SHOWTIP
#define NIF_SHOWTIP 0x00000080
#endif

#ifndef NOTIFYICON_VERSION_4
#define NOTIFYICON_VERSION_4 4
#endif

缺少 RtlCaptureStackBackTrace

这是第5个错误

1
C:\Qt\qtbase-opensource-src-5.7.1\src\testlib\qtestcase.cpp(1578): error C3861: “RtlCaptureStackBackTrace”: 找不到标识符

这个错误在以前的文章中提到过,在qtestcase.cpp文件中加入以下声明:

1
2
3
4
5
6
extern "C" __declspec(dllimport) USHORT WINAPI RtlCaptureStackBackTrace(
__in ULONG FramesToSkip,
__in ULONG FramesToCapture,
__out_ecount(FramesToCapture) PVOID *BackTrace,
__out_opt PULONG BackTraceHash
);

编译其他模块

qtbase只够满足编译最基础的 Qt 程序,缺少了设计师、预言家等工具,一般至少还需要编译配套工具和多语言:

  1. qttools-opensource-src-5.7.1.7z
  2. qttranslations-opensource-src-5.7.1.7z


编译模块的方法:进到模块根目录后依次执行

1
2
3
4
5
6
"%programfiles%\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\Build\vcvars32.bat" x86
set WindowsTargetPlatformMinVersion=5.1.2600.0
"C:\VC-LTL-Binary-v5.2.2\VC-LTL helper for nmake.cmd"
C:\qt5.7.1-vc144-i386\bin\qmake.exe -makefile -spec win32-msvc2015
nmake
nmake install

分发

使用configure -prefix "C:\qt5.7.1-vc144-i386" ...命令来配置Qt的编译时,这个绝对路径会被硬编码到编译出来的多个关键文件中,其中最重要的就是 qmake.exe。
当其他人将这个编译好的Qt包解压到其他路径(例如 D:\Qt\)下,然后尝试在Qt Creator中添加这个Qt时,Qt Creator会执行 D:\Qt\bin\qmake.exe 来查询Qt的配置信息。然而,qmake.exe 内部记录的路径仍然是编译时的 “C:\qt5.7.1-vc144-i386”。
Qt Creator发现 qmake 报告的路径和 qmake 自身的实际路径不符,并且在报告的路径下找不到必需的文件,因此判断这是一个损坏或无效的Qt版本,从而给出 “Invalid Qt version” 的错误。


解决方法,手动创建一个qt.conf文件放到bin目录下,文件内容是:

1
2
[Paths]
Prefix=..

这个配置文件会告诉bin目录中的所有Qt工具(如 qmake.exe, moc.exe, windeployqt.exe 等),Qt的根目录(Prefix)不再是编译时硬编码的绝对路径,而是当前目录的上一级目录。

上一页
2025-07-26 16:19:44
下一页