前言說(shuō)明
本文是作者在win10下使用Qt6編譯Quazip的過(guò)程記錄,旨在闡明過(guò)程中出現(xiàn)的問(wèn)題侣诺,已經(jīng)解決的思路和方法裆泳,不是直截了當(dāng)?shù)慕坛獭?br> 你可以在這里直接下載已經(jīng)改造完成的工程。
環(huán)境
· Win10
· CMake 3.23.0-rc2
· Qt Creator 6.0.2 Based on Qt 6.2.2 (MSVC 2019, 64 bit)
一次失敗的嘗試經(jīng)歷步驟
- 從Github下載最新的quazip-master
09ec1d1on 25 Jan
- 解壓到某個(gè)目錄糜芳,比如
F:\tgit\lib\quazip-master\quazip-1.2.0
- 根據(jù)官網(wǎng)的文檔,執(zhí)行CMake千诬,結(jié)果失敗耍目,如下所示
(c) 2020 Microsoft Corporation. 保留所有權(quán)利。
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!
錯(cuò)誤出現(xiàn)在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
設(shè)置為NEW
莫辨,按照提示修改如下:
cmake_policy(SET CMP0048 NEW)
project(QuaZip_Library VERSION ${QUAZIP_LIB_VERSION})
include(GNUInstallDirs) # configurable CMAKE_INSTALL_*DIR
刪除緩存F:\tgit\qtprojects\quazip
傲茄,重新執(zhí)行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".
之前的報(bào)錯(cuò)沒(méi)有了,但是出現(xiàn)了更多的報(bào)錯(cuò)沮榜,根據(jù)提示盘榨,看看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}
這個(gè)變量并沒(méi)有賦值的地方,而且此類報(bào)錯(cuò)解決了一個(gè)應(yīng)該還會(huì)冒出來(lái)新的蟆融,感覺(jué)按照官方流程是走不通的草巡,可能不兼容Qt6,或者不兼容CMake 3.23.0-rc2
型酥。換了個(gè)官方聲稱CMake minimum version 3.15 is required to build QuaZip 1.0.
的CMake 1.0山憨,也是一堆問(wèn)題查乒,算了,不試了郁竟,決定另辟蹊徑玛迄。
第二次嘗試
上面編譯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打開(kāi)項(xiàng)目文件
F:\tgit\qtprojects\quazip-0.7.3\quazip.pro
- 在子項(xiàng)目
quazip/quazip.pri
和qztest/qztest.pro
文件中添加Qt安裝目錄下的QtZlib,如下圖所示:
這里和上述那篇教程不同讥蟆,此處使用
$$[QT_INSTALL_PREFIX]
來(lái)獲得Qt安裝目錄勒虾,避免寫死本機(jī)絕對(duì)路徑,保證可移植性瘸彤。經(jīng)過(guò)測(cè)試修然,在WIN10下qmake對(duì)INCLUDEPATH
的斜杠方向敏感,需要使用system_path將其轉(zhuǎn)換為windows路徑的反斜杠钧栖,否則編譯時(shí)找不到對(duì)應(yīng)的頭文件低零。
- 右鍵點(diǎn)擊子項(xiàng)目
quazip
,選擇構(gòu)建"quazip"
拯杠,或者點(diǎn)擊菜單構(gòu)建>Build Subproject "quazip"
掏婶,出現(xiàn)一堆報(bào)錯(cuò)
報(bào)錯(cuò)的原因是這個(gè)項(xiàng)目是在Qt5環(huán)境下編寫的,很多類型在Qt6已經(jīng)無(wú)法直接使用潭陪。
關(guān)于QTextCodec
的報(bào)錯(cuò)
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazip.h:30: error: C1083: 無(wú)法打開(kāi)包括文件: “QTextCodec”: No such file or directory
查看Qt官網(wǎng)這個(gè)類的介紹:
我用的是qmake雄妥,因此在
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazip.pro
中添加一行QT += core5compat
,如下圖所示重新構(gòu)建依溯,提示
:-1: error: Unknown module(s) in QT: core5compat
這是因?yàn)槲覜](méi)有安裝組件老厌,打開(kāi)Qt安裝目錄下的MaintenanceTool.exe
· 使用賬號(hào)密碼登錄
· 選擇“添加或移除組件”
· 勾選
Qt 5 Compatibility Module
安裝后重啟Qt,重新構(gòu)建黎炉,一般都可以解決枝秤。
但是我出現(xiàn)了一個(gè)新的錯(cuò)誤
:-1: error: Unknown module(s) in QT: core5compat
:這猜測(cè)這是因?yàn)槲抑笆褂玫氖?code>Qt6.2.3,而它已被
6.2.4
所取代慷嗜,我在添加組件時(shí)找不到6.2.3
對(duì)應(yīng)的組件淀弹,所以我安裝了6.2.4
的組件,看來(lái)這樣Qt識(shí)別不出來(lái)庆械∞崩#看來(lái)我只能把版本升級(jí)到6.2.4
了。
修改Qt引擎版本
繼續(xù)使用MaintenanceTool.exe
安裝6.2.4
的相關(guān)組件缭乘,安裝好之后沐序,重啟Qt,打開(kāi)菜單工具>選項(xiàng)>Kits>Qt Versions
可以看到Qt已經(jīng)自動(dòng)檢測(cè)到
6.2.4
。再選中左側(cè)的項(xiàng)目策幼,右鍵Desktop Qt 6.2.4 MSVC2019 64bit邑时,將其enable并雙擊,此時(shí)可以看到構(gòu)建套件已經(jīng)出現(xiàn)了
6.2.4
垄惧,并觸發(fā)了自動(dòng)編譯刁愿,關(guān)于QT: core5compat
的報(bào)錯(cuò)也消失了。由此說(shuō)明到逊,因Qt存在多個(gè)版本铣口,選擇哪個(gè)版本應(yīng)當(dāng)小心,來(lái)看看我當(dāng)初安裝的
6.2.3
的說(shuō)明:6.2.3
并不是終版觉壶,終將被6.2.4
所代替脑题。因此,6.2.4
出來(lái)后铜靶,你就沒(méi)辦法再安裝6.2.3
的組件了叔遂。
關(guān)于tfUtf8的報(bào)錯(cuò)
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: 參見(jiàn)“QuaGzipFile”的聲明
改成QObject::tr
對(duì)應(yīng)的QuaGzipFile::tr
即可
關(guān)于Permissions的報(bào)錯(cuò)
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazipfileinfo.cpp:29: error: C2440: “初始化”: 無(wú)法從“int”轉(zhuǎn)換為“QFlags<QFileDevice::Permission>”
把下圖中的QFile::Permissions perm = 0;
改成
QFile::Permissions perm = QFile::Permissions();
關(guān)于created的報(bào)錯(cuò)
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: 參見(jiàn)“QFileInfo”的聲明
把下圖中的setFileNTFScTime(fi.created());
改成
setFileNTFScTime(fi.birthTime());
關(guān)于qSort的報(bào)錯(cuò)
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazipdir.cpp:393: error: C3861: “qSort”: 找不到標(biāo)識(shí)符
..\..\quazip-0.7.3\quazip\quazipdir.cpp(393): note: “qSort”: 函數(shù)聲明必須可用,因?yàn)樗袇?shù)都不依賴于模板參數(shù)
..\..\quazip-0.7.3\quazip\quazipdir.cpp(44): note: 此診斷出現(xiàn)在編譯器生成的函數(shù)“bool QuaZipDirPrivate::entryInfoList(QStringList,QDir::Filters,QDir::SortFlags,TFileInfoList &) const”中
查看官方文檔争剿,qSort
這個(gè)函數(shù)只是為了兼容以前老的代碼已艰,Qt6現(xiàn)已廢棄,需要換成std::qsort
蚕苇。
修改辦法是包裝一個(gè)lambda表達(dá)式來(lái)使用現(xiàn)有的QuaZipDirComparator
哩掺,如下圖所示:
然而,這樣修改改動(dòng)有點(diǎn)大涩笤,有沒(méi)有辦法簡(jiǎn)單地修改一下呢嚼吞?既然std::qsort是為了兼容老的代碼,那就直接把它換成
std::sort
吧蹬碧,直接把qSort(list.begin(), list.end(), lessThan);
這句代碼改成std::sort(list.begin(), list.end(), lessThan);
即可舱禽。如下圖所示:同樣的道理,在子項(xiàng)目
qztest
中恩沽,把qSort(xxx);
之類的語(yǔ)句誊稚,改成std::sort(xxx.begin(), xxx.end())
。
其他報(bào)錯(cuò)
F:\tgit\qtprojects\quazip-0.7.3\quazip\quazipdir.cpp:393: error: C3861: “qSort”: 找不到標(biāo)識(shí)符
..\..\quazip-0.7.3\quazip\quazipdir.cpp(393): note: “qSort”: 函數(shù)聲明必須可用罗心,因?yàn)樗袇?shù)都不依賴于模板參數(shù)
..\..\quazip-0.7.3\quazip\quazipdir.cpp(44): note: 此診斷出現(xiàn)在編譯器生成的函數(shù)“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
片吊,詳見(jiàn)qrand、QRandomGenerator
把toTime_t
換成toSecsSinceEpoch
协屡,詳見(jiàn)QDateTime::toTime_t
編譯成功
以上改完后就可以成功編譯了,可以看到生成了對(duì)應(yīng)的dll和lib文件全谤。
參考資料
- qmake環(huán)境變量手冊(cè):https://doc.qt.io/qt-6/qmake-environment-reference.html
- qmake函數(shù)手冊(cè):https://doc.qt.io/qt-6/qmake-function-reference.html