VS2022+静态编译QT5.6.0+VMP编译完整笔记

准备工作:

1. 在Qt官网下载Qt库的源码。

qt-opensource-windows-x86-msvc2015_64-5.6.0.exe

安装过程中选择需要源代码。

2.下载并安装Python。

3. 下载并安装Perl。

4. 下载并安装Ruby。版本对应如下:

命令行下进入QT源码:

configure -prefix "D:\Qt5.6.0\5.6\msvc2022_64_static" -static -static-runtime -release -nomake examples -nomake tests -skip qtwebengine -opensource -confirm-license -qt-pcre -qt-pcre -qt-freetype –opengl desktop -opengl es2

其中由于QT5.6与VS2022有些地方不匹配,nmake会报下列错误。

D:\Qt5.6.0\5.6\Src\qtbase\src\tools\qlalr

compress.cpp

.\compress.cpp(45): error C2039: "binary_function": 不是 "std" 的成员

e:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\iostream(18): note: 参见“std ”的声明

.\compress.cpp(45): error C2504: “binary_function”: 未定义基类

.\compress.cpp(45): error C2143: 语法错误: 缺少“,”(在“<”的前面)

.\compress.cpp(53): error C2039: "binary_function": 不是 "std" 的成员

e:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\iostream(18): note: 参见“std ”的声明

.\compress.cpp(53): error C2504: “binary_function”: 未定义基类

.\compress.cpp(53): error C2143: 语法错误: 缺少“,”(在“<”的前面)

.\compress.cpp(143): error C2039: "binary_function": 不是 "std" 的成员

e:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\iostream(18): note: 参见“std ”的声明

.\compress.cpp(143): error C2504: “binary_function”: 未定义基类

.\compress.cpp(143): error C2143: 语法错误: 缺少“,”(在“<”的前面)

解决方法:

只需要在源码compress.cpp中添加:

#include<functional>

D:\Qt5.6.0\5.6\Src\qtbase\src\testlib\ testlib.pro

qtesttable.cpp

.\qtesttable.cpp(135): error C2039: "unary_function": 不是 "std" 的成员

只需要在源码中添加:

#include<functional>

D:\Qt5.6.0\5.6\Src\qtdeclarative\src\src.pro

..\3rdparty\masm\wtf/MathExtras.h(157): error C2169: “log2”: 内部函数,不能定义

..\3rdparty\masm\wtf/MathExtras.h(163): error C2169: “log2f”: 内部函数,不能定义

..\3rdparty\masm\wtf/MathExtras.h(215): error C2169: “lrint”: 内部函数,不能定义

将这三个函数注释掉。

D:\Qt5.6.0\5.6\Src\qt3d\src\core\core.projobs\dependencyhandler.cpp(63): error C2039: "unary_function": 不是 "std" 的成员

D:\Qt5.6.0\5.6\Src\qtbase\include\QtCore\../../src/corelib/tools/qarraydatapointer.h(208): note: 参见“std”的声明

jobs\dependencyhandler.cpp(63): error C2504: “unary_function”: 未定义基类

jobs\dependencyhandler.cpp(63): error C2143: 语法错误: 缺少“,”(在“<”的前面)

jobs\dependencyhandler.cpp(80): error C2039: "unary_function": 不是 "std" 的成员

D:\Qt5.6.0\5.6\Src\qtbase\include\QtCore\../../src/corelib/tools/qarraydatapointer.h(208): note: 参见“std”的声明

jobs\dependencyhandler.cpp(80): error C2504: “unary_function”: 未定义基类

jobs\dependencyhandler.cpp(80): error C2143: 语法错误: 缺少“,”(在“<”的前面)

jobs\dependencyhandler.cpp(91): error C2039: "binary_function": 不是 "std" 的成员

D:\Qt5.6.0\5.6\Src\qtbase\include\QtCore\../../src/corelib/tools/qarraydatapointer.h(208): note: 参见“std”的声明

jobs\dependencyhandler.cpp(91): error C2504: “binary_function”: 未定义基类

jobs\dependencyhandler.cpp(91): error C2143: 语法错误: 缺少“,”(在“<”的前面)

解决方法:

只需要在源码中添加:

#include<functional>

完成上述修改后,

nmake

nmake install

得到QT5.6的静态库。

然后在VS2022中利用QT_VS_TOOLS设置。

这里有个大坑,我之前由于Qt在编译的时候将生成的库修改了文件夹名称发现在VS2015中QT VS TOOLS ADD VERSIONS完成后关闭后总是没有了,开始以为是QT_VS_TOOLS出问题了,卸载后下载低版本仍然是这个问题,VS2022中提示信息中绝对路径明显是我修改之前的路径,我才意识到问题所在,打开IDA发现果然将绝对路径写在qmake.exe中。

当使用qmake xxxx.pro生成的Makefile会使用库文件中写死的SDK安装路径(configure的-prefix参数指定的),这导致必须将SDK安装到特定的路径下不然找不到编译好的Qt库(可以利用qt.conf 文件进行修改,详见:https://blog.csdn.net/BGK112358/article/details/103321938)。

这也就是QT VS TOOLS ADD VERSIONS失败的原因。

VS2022中直接链接VS2015编译的QT静态库,同样首先需要在VS2022下重新编译libffi库,编译VMP成功。

严重性

代码

说明

项目

文件

禁止显示状态

详细信息

错误

LNK1181

无法打开输入文件“dxguid.lib”

VMProtect

E:\vmp_vs2022\vmp\vcproj\LINK

1

但是VS2022中链接VS2022编译的QT静态库,编译VMP会出现很多BUG:

BUG1:

1>LINK : fatal error LNK1181: 无法打开输入文件“dxguid.lib”

原因是VS2022我没有安装SDK,简单省事的办法,安装directx SDK,然后将其路径添加到LIB库路径。下。

BUG2:

严重性

代码

说明

项目

文件

禁止显示状态

详细信息

错误

LNK2001

无法解析的外部符号 __std_find_trivial_8

VMProtect

E:\vmp_vs2022\vmp\vcproj\Qt5Gui.lib(qopenglshaderprogram.obj)

1

严重性

代码

说明

项目

文件

禁止显示状态

详细信息

错误

LNK2001

无法解析的外部符号 __CxxFrameHandler4

VMProtect

E:\vmp_vs2022\vmp\vcproj\Qt5Core.lib(qmimemagicrule.obj)

1

该问题产生的原因是:微软为了用于减小 x64 上 C++ 异常处理(try/catch 和自动析构函数)的二进制大小。我为用于C++异常处理的数据开发了新的格式和处理,称为 FH4(__CxxFrameHandler4见下文),它比现有实现小 ~60%,从而为大量使用C++异常处理的程序总体二进制文件减少了 20%。在较新的 VS 版本中手动指定旧版本的VS(平台工具集),使用较新版本的 Visual Studio(默认使用)构建的链接(静态)库,可能会导致链接错误“未解析的外部符号FH3FH3FH4__CxxFrameHandler4"

解决方法是:

VS2019->Properties->C/C++->Command Line add ‘-d2FH4-‘

VS2019->Properties->Linker->Command Line add ‘-d2:-FH4-‘

我按照这个办法试验发现仍然不解决问题。

禁止在 VS 16.3+ 上使用 __CxxFrameHandler4(仅限 x64)https://developercommunity.visualstudio.com/content/problem/746534/visual-c-163-runtime-uses-an-unsupported-api-for-u.html

add_compile_flags(“/Zc:threadSafeInit-”)

if(ARCH STREQUAL “amd64” 和 MSVC_VERSION GREATER 1922)

add_compile_flags(“/d2FH4-”)

add_link_options(“/d2:-FH4-”)

#生成警告级别 3

add_compile_flags(“/W3”)

原因应该是VS2022下编译QT静态库时使用了__CxxFrameHandler4,或者VS2022有新的特性,为此,我更改工程平台工具集VS2022(V143),重新编译。

报错BUG3:

watermarks_window.obj : error LNK2001: 无法解析的外部符号 "class std::vector<struct PROCESS_ITEM,class std::allocator<struct PROCESS_ITEM> > __cdecl os::K32EnumProcesses(void)" (?K32EnumProcesses@os@@YA?AV?$vector@UPROCESS_ITEM@@V?$allocator@UPROCESS_ITEM@@@std@@@std@@XZ)

void WatermarksWindow::processEditDropDown()

std::vector<PROCESS_ITEM> processes = os::EnumProcesses();

错误原因在于Windows psapi.h中默认将EnumProcesses定义为宏K32EnumProcesses函数,解决方法:

将EnumProcesses重新命名为其它名称,解决该问题。

BUG4:

3>libGLESv2.lib(libGLESv2.obj) : error LNK2005: glBindTexture 已经在 Opengl32.lib(OPENGL32.dll) 中定义

3>libGLESv2.lib(libGLESv2.obj) : error LNK2005: glBlendFunc 已经在 Opengl32.lib(OPENGL32.dll) 中定义

3>libGLESv2.lib(libGLESv2.obj) : error LNK2005: glClear 已经在 Opengl32.lib(OPENGL32.dll) 中定义

3>libGLESv2.lib(libGLESv2.obj) : error LNK2005: glClearColor 已经在 Opengl32.lib(OPENGL32.dll) 中定义

3>libGLESv2.lib(libGLESv2.obj) : error LNK2005: glClearStencil 已经在 Opengl32.lib(OPENGL32.dll) 中定义

3>libGLESv2.lib(libGLESv2.obj) : error LNK2005: glColorMask 已经在 Opengl32.lib(OPENGL32.dll) 中定义

3>libGLESv2.lib(libGLESv2.obj) : error LNK2005: glCopyTexImage2D 已经在 Opengl32.lib(OPENGL32.dll) 中定义

解决该问题时,也走了很多弯路,最开始想的是工程只链接libGLESv2.lib或者Opengl32.lib,后来发现会导致其它错误,回忆了一下VS2015下没有这个问题,区别就是产生libGLESv2.lib的方法是-share参数,而且没有支持opengl,直接将VS2015编译生成的libEGL.lib和libGLESv2.lib拷贝过来,发现果然不报错误了。为了验证,在VS2022下configure -prefix "D:\Qt5.6.0\5.6\msvc2022_64_static2" -shared -release -nomake examples -nomake tests -skip qtwebengine -opensource -confirm-license

重新生成SDK静态库,但是发现必须需要libEGL.dll和libGLESv2.dll文件才能运行EXE(利用VS2015的libEGL.lib和libGLESv2.lib文件同样有这个问题),看来这个问题与VS2015和VS2022这个两个开发环境下支持OpenGL有关系了,收工了。

  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值