前言說明
本文是作者在win10下使用Qt6編譯Quazip的過程記錄,旨在闡明過程中出現(xiàn)的問題,已經解決的思路和方法,不是直截了當?shù)慕坛獭?br> 你可以在這里直接下載已經改造完成的工程。
環(huán)境
· 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
- 根據(jù)官網的文檔,執(zhí)行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!
錯誤出現(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
設置為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".
之前的報錯沒有了,但是出現(xiàn)了更多的報錯,根據(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}
這個變量并沒有賦值的地方,而且此類報錯解決了一個應該還會冒出來新的,感覺按照官方流程是走不通的,可能不兼容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,如下圖所示:
image.png
這里和上述那篇教程不同,此處使用
$$[QT_INSTALL_PREFIX]
來獲得Qt安裝目錄,避免寫死本機絕對路徑,保證可移植性。經過測試,在WIN10下qmake對INCLUDEPATH
的斜杠方向敏感,需要使用system_path將其轉換為windows路徑的反斜杠,否則編譯時找不到對應的頭文件。
- 右鍵點擊子項目
quazip
,選擇構建"quazip"
,或者點擊菜單構建>Build Subproject "quazip"
,出現(xiàn)一堆報錯
image.png
報錯的原因是這個項目是在Qt5環(huán)境下編寫的,很多類型在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,重新構建,一般都可以解決。
但是我出現(xiàn)了一個新的錯誤
:-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引擎版本
繼續(xù)使用MaintenanceTool.exe
安裝6.2.4
的相關組件,安裝好之后,重啟Qt,打開菜單工具>選項>Kits>Qt Versions
可以看到Qt已經自動檢測到
6.2.4
。再選中左側的項目,右鍵Desktop Qt 6.2.4 MSVC2019 64bit,將其enable并雙擊,此時可以看到構建套件已經出現(xiàn)了
6.2.4
,并觸發(fā)了自動編譯,關于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<QFileDevice::Permission>”
把下圖中的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”: 函數(shù)聲明必須可用,因為所有參數(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
這個函數(shù)只是為了兼容以前老的代碼,Qt6現(xiàn)已廢棄,需要換成std::qsort
。
修改辦法是包裝一個lambda表達式來使用現(xiàn)有的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”: 函數(shù)聲明必須可用,因為所有參數(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
,詳見qrand、QRandomGenerator
把toTime_t
換成toSecsSinceEpoch
,詳見QDateTime::toTime_t
編譯成功
以上改完后就可以成功編譯了,可以看到生成了對應的dll和lib文件。
參考資料
- qmake環(huán)境變量手冊:https://doc.qt.io/qt-6/qmake-environment-reference.html
- qmake函數(shù)手冊:https://doc.qt.io/qt-6/qmake-function-reference.html