前言说明
本文是作者在win10下使用Qt6编译Quazip的过程记录,旨在阐明过程中出现的问题,已经解决的思路和方法,不是直截了当的教程。
你可以在这里直接下载已经改造完成的工程。
环境
· Win10
· CMake 3.23.0-rc2
· Qt Creator 6.0.2 Based on Qt 6.2.2 (MSVC 2019, 64 bit)
一次失败的尝试经历步骤
- 从Github下载最新的quazip-master
09ec1d1on 25 Jan
- 解压到某个目录,比如
F:\tgit\lib\quazip-master\quazip-1.2.0
- 根据官网的文档,执行CMake,结果失败,如下所示
(c) 2020 Microsoft Corporation. 保留所有权利。
C:\Users\fygame>F:
F:\>cd F:\tgit\lib\quazip-master\quazip-1.2.0
F:\tgit\lib\quazip-master\quazip-1.2.0>cmake -S . -B F:\tgit\qtprojects\quazip -D QUAZIP_QT_MAJOR_VERSION=6
-- Building for: Visual Studio 16 2019
CMake Warning at CMakeLists.txt:1 (project):
VERSION keyword not followed by a value or was followed by a value that
expanded to nothing.
CMake Error at CMakeLists.txt:1 (project):
VERSION not allowed unless CMP0048 is set to NEW
CMake Warning (dev) in CMakeLists.txt:
No cmake_minimum_required command is present. A line of code such as
cmake_minimum_required(VERSION 3.23)
should be added at the top of the file. The version specified may be lower
if you wish to support older CMake versions for this project. For more
information run "cmake --help-policy CMP0000".
This warning is for project developers. Use -Wno-dev to suppress it.
-- Configuring incomplete, errors occurred!
错误出现在F:\tgit\lib\quazip-master\quazip-1.2.0\CMakeLists.txt
的第一行,如下所示
project(QuaZip_Library VERSION ${QUAZIP_LIB_VERSION})
include(GNUInstallDirs) # configurable CMAKE_INSTALL_*DIR
提示如果要使用VERSION
,必须把CMP0048
设置为NEW
,按照提示修改如下:
cmake_policy(SET CMP0048 NEW)
project(QuaZip_Library VERSION ${QUAZIP_LIB_VERSION})
include(GNUInstallDirs) # configurable CMAKE_INSTALL_*DIR
删除缓存F:\tgit\qtprojects\quazip
,重新执行CMake命令:
F:\tgit\lib\quazip-master\quazip-1.2.0>cmake -S . -B F:\tgit\qtprojects\quazip -D QUAZIP_QT_MAJOR_VERSION=6
CMake Warning at CMakeLists.txt:2 (project):
VERSION keyword not followed by a value or was followed by a value that
expanded to nothing.
-- Selecting Windows SDK version 10.0.17763.0 to target Windows 10.0.19041.
-- The C compiler identification is MSVC 19.29.30140.0
-- The CXX compiler identification is MSVC 19.29.30140.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: D:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: D:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error at CMakeLists.txt:49 (add_library):
add_library ALIAS requires exactly one target argument.
CMake Error at CMakeLists.txt:51 (set_target_properties):
set_target_properties called with incorrect number of arguments.
CMake Error at CMakeLists.txt:57 (target_include_directories):
Cannot specify include directories for target "PUBLIC" which is not built
by this project.
CMake Error at CMakeLists.txt:63 (target_link_libraries):
target_link_libraries called with incorrect number of arguments
CMake Error at CMakeLists.txt:67 (target_compile_definitions):
Cannot specify compile definitions for target "PUBLIC" which is not built
by this project.
CMake Warning (dev) in CMakeLists.txt:
No cmake_minimum_required command is present. A line of code such as
cmake_minimum_required(VERSION 3.23)
should be added at the top of the file. The version specified may be lower
if you wish to support older CMake versions for this project. For more
information run "cmake --help-policy CMP0000".
This warning is for project developers. Use -Wno-dev to suppress it.
-- Configuring incomplete, errors occurred!
See also "F:/tgit/qtprojects/quazip/CMakeFiles/CMakeOutput.log".
之前的报错没有了,但是出现了更多的报错,根据提示,看看CMakeLists.txt
的第49行:
add_library(QuaZip::QuaZip ALIAS ${QUAZIP_LIB_TARGET_NAME})
set_target_properties(${QUAZIP_LIB_TARGET_NAME} PROPERTIES
VERSION ${QUAZIP_LIB_VERSION}
SOVERSION ${QUAZIP_LIB_SOVERSION}
OUTPUT_NAME ${QUAZIP_LIB_FILE_NAME}
PUBLIC_HEADER "${QUAZIP_HEADERS}"
)
${QUAZIP_LIB_TARGET_NAME}
这个变量并没有赋值的地方,而且此类报错解决了一个应该还会冒出来新的,感觉按照官方流程是走不通的,可能不兼容Qt6,或者不兼容CMake 3.23.0-rc2
。换了个官方声称CMake minimum version 3.15 is required to build QuaZip 1.0.
的CMake 1.0,也是一堆问题,算了,不试了,决定另辟蹊径。
第二次尝试
上面编译quazip-1.2.0
失败,于是按照这篇教程https://www.cnblogs.com/qiyawei/p/10695192.html,尝试编译quazip-0.7.3
- 从https://sourceforge.net/projects/quazip/下载
quazip-0.7.3
,解压到F:\tgit\qtprojects\quazip-0.7.3
- 在Qt Creator打开项目文件
F:\tgit\qtprojects\quazip-0.7.3\quazip.pro
- 在子项目
quazip/quazip.pri
和qztest/qztest.pro
文件中添加Qt安装目录下的QtZlib,如下图所示:
这里和上述那篇教程不同,此处使用
$$[QT_INSTALL_PREFIX]
来获得Qt安装目录,避免写死本机绝对路径,保证可移植性。经过测试,在WIN10下qmake对INCLUDEPATH
的斜杠方向敏感,需要使用system_path将其转换为windows路径的反斜杠,否则编译时找不到对应的头文件。
- 右键点击子项目
quazip
,选择构建"quazip"
,或者点击菜单构建>Build Subproject "quazip"
,出现一堆报错
报错的原因是这个项目是在Qt5环境下编写的,很多类型在Qt6已经无法直接使用。
关于QTextCodec
的报错
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazip.h:30: error: C1083: 无法打开包括文件: “QTextCodec”: No such file or directory
查看Qt官网这个类的介绍:
我用的是qmake,因此在
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazip.pro
中添加一行QT += core5compat
,如下图所示
重新构建,提示
:-1: error: Unknown module(s) in QT: core5compat
这是因为我没有安装组件,打开Qt安装目录下的MaintenanceTool.exe
· 使用账号密码登录
· 选择“添加或移除组件”
· 勾选
Qt 5 Compatibility Module
安装后重启Qt,重新构建,一般都可以解决。
但是我出现了一个新的错误
:-1: error: Unknown module(s) in QT: core5compat
:
这猜测这是因为我之前使用的是
Qt6.2.3
,而它已被6.2.4
所取代,我在添加组件时找不到6.2.3
对应的组件,所以我安装了6.2.4
的组件,看来这样Qt识别不出来。看来我只能把版本升级到6.2.4
了。
修改Qt引擎版本
继续使用MaintenanceTool.exe
安装6.2.4
的相关组件,安装好之后,重启Qt,打开菜单工具>选项>Kits>Qt Versions
可以看到Qt已经自动检测到
6.2.4
。
再选中左侧的项目,右键Desktop Qt 6.2.4 MSVC2019 64bit,将其enable并双击,此时可以看到构建套件已经出现了
6.2.4
,并触发了自动编译,关于QT: core5compat
的报错也消失了。
由此说明,因Qt存在多个版本,选择哪个版本应当小心,来看看我当初安装的
6.2.3
的说明:
6.2.3
并不是终版,终将被6.2.4
所代替。因此,6.2.4
出来后,你就没办法再安装6.2.3
的组件了。
关于tfUtf8的报错
F:\tgit\qtprojects\quazip-0.7.3\quazip\quagzipfile.cpp:60: error: C2039: "trUtf8": 不是 "QuaGzipFile" 的成员
F:\tgit\qtprojects\quazip-0.7.3\quazip\quagzipfile.h(39): note: 参见“QuaGzipFile”的声明
改成QObject::tr
对应的QuaGzipFile::tr
即可
关于Permissions的报错
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazipfileinfo.cpp:29: error: C2440: “初始化”: 无法从“int”转换为“QFlags”
把下图中的QFile::Permissions perm = 0;
改成
QFile::Permissions perm = QFile::Permissions();
关于created的报错
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazipnewinfo.cpp:137: error: C2039: "created": 不是 "QFileInfo" 的成员
D:\Qt\6.2.3\msvc2019_64\include\QtCore\qfileinfo.h(56): note: 参见“QFileInfo”的声明
把下图中的setFileNTFScTime(fi.created());
改成
setFileNTFScTime(fi.birthTime());
关于qSort的报错
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazipdir.cpp:393: error: C3861: “qSort”: 找不到标识符
..\..\quazip-0.7.3\quazip\quazipdir.cpp(393): note: “qSort”: 函数声明必须可用,因为所有参数都不依赖于模板参数
..\..\quazip-0.7.3\quazip\quazipdir.cpp(44): note: 此诊断出现在编译器生成的函数“bool QuaZipDirPrivate::entryInfoList(QStringList,QDir::Filters,QDir::SortFlags,TFileInfoList &) const”中
查看官方文档,qSort
这个函数只是为了兼容以前老的代码,Qt6现已废弃,需要换成std::qsort
。
修改办法是包装一个lambda表达式来使用现有的QuaZipDirComparator
,如下图所示:
然而,这样修改改动有点大,有没有办法简单地修改一下呢?既然std::qsort是为了兼容老的代码,那就直接把它换成
std::sort
吧,直接把qSort(list.begin(), list.end(), lessThan);
这句代码改成std::sort(list.begin(), list.end(), lessThan);
即可。如下图所示:
同样的道理,在子项目
qztest
中,把qSort(xxx);
之类的语句,改成std::sort(xxx.begin(), xxx.end())
。
其他报错
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazipdir.cpp:393: error: C3861: “qSort”: 找不到标识符
..\..\quazip-0.7.3\quazip\quazipdir.cpp(393): note: “qSort”: 函数声明必须可用,因为所有参数都不依赖于模板参数
..\..\quazip-0.7.3\quazip\quazipdir.cpp(44): note: 此诊断出现在编译器生成的函数“bool QuaZipDirPrivate::entryInfoList(QStringList,QDir::Filters,QDir::SortFlags,TFileInfoList &) const”中
把return compressDir(fileCompressed, dir, recursive, 0);
改为return compressDir(fileCompressed, dir, recursive, QDir::Filters());
把QString::SkipEmptyParts
改为Qt::SkipEmptyParts
把qrand
换成QRandomGenerator
,详见qrand、QRandomGenerator
把toTime_t
换成toSecsSinceEpoch
,详见QDateTime::toTime_t
编译成功
以上改完后就可以成功编译了,可以看到生成了对应的dll和lib文件。
参考资料
- qmake环境变量手册:https://doc.qt.io/qt-6/qmake-environment-reference.html
- qmake函数手册:https://doc.qt.io/qt-6/qmake-function-reference.html