[原创]win10使用Qt6编译Quazip手记

前言说明

本文是作者在win10下使用Qt6编译Quazip的过程记录,旨在阐明过程中出现的问题,已经解决的思路和方法,不是直截了当的教程。
你可以在这里直接下载已经改造完成的工程。

环境

· Win10
· CMake 3.23.0-rc2
· Qt Creator 6.0.2 Based on Qt 6.2.2 (MSVC 2019, 64 bit)

一次失败的尝试经历步骤

  1. Github下载最新的quazip-master 09ec1d1on 25 Jan
  2. 解压到某个目录,比如F:\tgit\lib\quazip-master\quazip-1.2.0
  3. 根据官网的文档,执行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

  1. https://sourceforge.net/projects/quazip/下载quazip-0.7.3,解压到F:\tgit\qtprojects\quazip-0.7.3
  2. 在Qt Creator打开项目文件F:\tgit\qtprojects\quazip-0.7.3\quazip.pro
  3. 在子项目quazip/quazip.priqztest/qztest.pro文件中添加Qt安装目录下的QtZlib,如下图所示:
    image.png

这里和上述那篇教程不同,此处使用$$[QT_INSTALL_PREFIX]来获得Qt安装目录,避免写死本机绝对路径,保证可移植性。经过测试,在WIN10下qmake对INCLUDEPATH的斜杠方向敏感,需要使用system_path将其转换为windows路径的反斜杠,否则编译时找不到对应的头文件。

  1. 右键点击子项目quazip,选择构建"quazip",或者点击菜单构建>Build Subproject "quazip",出现一堆报错
    image.png

    报错的原因是这个项目是在Qt5环境下编写的,很多类型在Qt6已经无法直接使用。

关于QTextCodec的报错

F:\tgit\qtprojects\quazip-0.7.3\quazip\quazip.h:30: error: C1083: 无法打开包括文件: “QTextCodec”: No such file or directory

查看Qt官网这个类的介绍:

image.png

我用的是qmake,因此在F:\tgit\qtprojects\quazip-0.7.3\quazip\quazip.pro中添加一行QT += core5compat,如下图所示
image.png

重新构建,提示

:-1: error: Unknown module(s) in QT: core5compat

这是因为我没有安装组件,打开Qt安装目录下的MaintenanceTool.exe

image.png

· 使用账号密码登录
· 选择“添加或移除组件”
· 勾选Qt 5 Compatibility Module
image.png

安装后重启Qt,重新构建,一般都可以解决。
但是我出现了一个新的错误:-1: error: Unknown module(s) in QT: core5compat
image.png

这猜测这是因为我之前使用的是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

image.png

可以看到Qt已经自动检测到6.2.4
image.png

再选中左侧的项目,右键Desktop Qt 6.2.4 MSVC2019 64bit,将其enable并双击,此时可以看到构建套件已经出现了6.2.4,并触发了自动编译,关于QT: core5compat的报错也消失了。
由此说明,因Qt存在多个版本,选择哪个版本应当小心,来看看我当初安装的6.2.3说明:
image.png

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<QFileDevice::Permission>”

把下图中的QFile::Permissions perm = 0;


改成QFile::Permissions perm = QFile::Permissions();
image.png

关于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());

image.png

改成setFileNTFScTime(fi.birthTime());
image.png

关于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

image.png

修改办法是包装一个lambda表达式来使用现有的QuaZipDirComparator,如下图所示:

image.png

然而,这样修改改动有点大,有没有办法简单地修改一下呢?既然std::qsort是为了兼容老的代码,那就直接把它换成std::sort吧,直接把qSort(list.begin(), list.end(), lessThan);这句代码改成std::sort(list.begin(), list.end(), lessThan);即可。如下图所示:
image.png

同样的道理,在子项目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,详见qrandQRandomGenerator
toTime_t换成toSecsSinceEpoch,详见QDateTime::toTime_t

编译成功

以上改完后就可以成功编译了,可以看到生成了对应的dll和lib文件。


image.png

参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容