rcc: Teach rcc the --no-zstd option

It is needed when cross-building Qt using CMake, where the zstd
feature might have different values between the host and target,
in which case the build system tells rcc not to use zstd when
the feature is disabled.

Amends d20c9805763ab3dc504ebf2cefd33499d89ef22c

Change-Id: I9dc55b59b1be5272b79aa5f1e2daf2b516a157d6
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
Alexandru Croitor 2020-03-09 19:16:28 +01:00
parent 39ad96033c
commit 14546d1816
4 changed files with 33 additions and 7 deletions

View File

@ -272,6 +272,16 @@ function(QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE target resourceName)
list(APPEND rccArgs ${rcc_OPTIONS})
endif()
# When cross-building, we use host tools to generate target code. If the host rcc was compiled
# with zstd support, it expects the target QtCore to be able to decompress zstd compressed
# content. This might be true with qmake where host tools are built as part of the
# cross-compiled Qt, but with CMake we build tools separate from the cross-compiled Qt.
# If the target does not support zstd (feature is disabled), tell rcc not to generate
# zstd related code.
if(NOT QT_FEATURE_zstd)
list(APPEND rccArgs "--no-zstd")
endif()
# Process .qrc file:
add_custom_command(OUTPUT "${generatedSourceCode}"
COMMAND "@QT_CMAKE_EXPORT_NAMESPACE@::rcc"

View File

@ -180,6 +180,9 @@ int runRcc(int argc, char *argv[])
QCommandLineOption nocompressOption(QStringLiteral("no-compress"), QStringLiteral("Disable all compression. Same as --compress-algo=none."));
parser.addOption(nocompressOption);
QCommandLineOption noZstdOption(QStringLiteral("no-zstd"), QStringLiteral("Disable usage of zstd compression."));
parser.addOption(noZstdOption);
QCommandLineOption thresholdOption(QStringLiteral("threshold"), QStringLiteral("Threshold to consider compressing files."), QStringLiteral("level"));
parser.addOption(thresholdOption);
@ -252,6 +255,8 @@ int runRcc(int argc, char *argv[])
errorMsg = QLatin1String("Zstandard compression requires format version 3 or higher");
if (parser.isSet(nocompressOption))
library.setCompressionAlgorithm(RCCResourceLibrary::CompressionAlgorithm::None);
if (parser.isSet(noZstdOption))
library.setNoZstd(true);
if (parser.isSet(compressOption) && errorMsg.isEmpty()) {
int level = library.parseCompressionLevel(library.compressionAlgorithm(), parser.value(compressOption), &errorMsg);
library.setCompressLevel(level);

View File

@ -113,7 +113,8 @@ public:
uint flags = NoFlags,
RCCResourceLibrary::CompressionAlgorithm compressAlgo = CONSTANT_COMPRESSALGO_DEFAULT,
int compressLevel = CONSTANT_COMPRESSLEVEL_DEFAULT,
int compressThreshold = CONSTANT_COMPRESSTHRESHOLD_DEFAULT);
int compressThreshold = CONSTANT_COMPRESSTHRESHOLD_DEFAULT,
bool noZstd = false);
~RCCFileInfo();
QString resourceName() const;
@ -137,11 +138,13 @@ public:
qint64 m_nameOffset;
qint64 m_dataOffset;
qint64 m_childOffset;
bool m_noZstd;
};
RCCFileInfo::RCCFileInfo(const QString &name, const QFileInfo &fileInfo,
QLocale::Language language, QLocale::Country country, uint flags,
RCCResourceLibrary::CompressionAlgorithm compressAlgo, int compressLevel, int compressThreshold)
RCCResourceLibrary::CompressionAlgorithm compressAlgo, int compressLevel, int compressThreshold,
bool noZstd)
{
m_name = name;
m_fileInfo = fileInfo;
@ -155,6 +158,7 @@ RCCFileInfo::RCCFileInfo(const QString &name, const QFileInfo &fileInfo,
m_compressAlgo = compressAlgo;
m_compressLevel = compressLevel;
m_compressThreshold = compressThreshold;
m_noZstd = noZstd;
}
RCCFileInfo::~RCCFileInfo()
@ -267,11 +271,11 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
// Check if compression is useful for this file
if (data.size() != 0) {
#if QT_CONFIG(zstd)
if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best) {
if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best && !m_noZstd) {
m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zstd;
m_compressLevel = 19; // not ZSTD_maxCLevel(), as 20+ are experimental
}
if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zstd) {
if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zstd && !m_noZstd) {
if (lib.m_zstdCCtx == nullptr)
lib.m_zstdCCtx = ZSTD_createCCtx();
qsizetype size = data.size();
@ -471,7 +475,8 @@ RCCResourceLibrary::RCCResourceLibrary(quint8 formatVersion)
m_useNameSpace(CONSTANT_USENAMESPACE),
m_errorDevice(0),
m_outDevice(0),
m_formatVersion(formatVersion)
m_formatVersion(formatVersion),
m_noZstd(false)
{
m_out.reserve(30 * 1000 * 1000);
#if QT_CONFIG(zstd)
@ -651,7 +656,8 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
child.isDir() ? RCCFileInfo::Directory : RCCFileInfo::NoFlags,
compressAlgo,
compressLevel,
compressThreshold)
compressThreshold,
m_noZstd)
);
if (!arc)
m_failedResources.push_back(child.fileName());
@ -667,7 +673,8 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
RCCFileInfo::NoFlags,
compressAlgo,
compressLevel,
compressThreshold)
compressThreshold,
m_noZstd)
);
if (!arc)
m_failedResources.push_back(absFileName);

View File

@ -109,6 +109,9 @@ public:
int formatVersion() const { return m_formatVersion; }
void setNoZstd(bool v) { m_noZstd = v; }
bool noZstd() const { return m_noZstd; }
private:
struct Strings {
Strings();
@ -170,6 +173,7 @@ private:
QIODevice *m_outDevice;
QByteArray m_out;
quint8 m_formatVersion;
bool m_noZstd;
};
QT_END_NAMESPACE