Make RCC handle bigger binaries
Traditionally, RCC in "C mode" was meant to bundle small resources into a binary, like help texts or an occasional icon. RCC produces a .cpp file containing the actual data in a char array which is then passed to the compiler and linker as a normal source file. Larger resources should be compiled in RCC's binary mode and loaded at run time. Current Qt Quick use tries to deploy large hunks of data in "C mode", causing heavy compiler/system load. This patch works around the issue by splitting the process into three parts: 1. Create a C++ skeleton, as usual, but use a placeholder array with "easily compilable" (mostly NULs) data instead. 2. Compile the skeleton file. 3. Replace the placeholder data with the real binary data. time (qmake5 ; make clean ; make) takes 1.3 s real time for a 100 MB resource here, and there is still room for improving patching performance if really needed. Change-Id: I10a1645fd86a95a7d5663c89e19b05cb3b43ed1b Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com> Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
parent
7cbd9cffd3
commit
5395180fcb
@ -3,15 +3,27 @@ qtPrepareTool(QMAKE_RCC, rcc, _DEP)
|
|||||||
isEmpty(RCC_DIR):RCC_DIR = .
|
isEmpty(RCC_DIR):RCC_DIR = .
|
||||||
isEmpty(QMAKE_MOD_RCC):QMAKE_MOD_RCC = qrc
|
isEmpty(QMAKE_MOD_RCC):QMAKE_MOD_RCC = qrc
|
||||||
|
|
||||||
rcc.output = $$RCC_DIR/$${first(QMAKE_MOD_RCC)}_${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)}
|
|
||||||
!contains(QMAKE_RESOURCE_FLAGS, -root):!isEmpty(QMAKE_RESOURCE_ROOT):QMAKE_RESOURCE_FLAGS += -root $$QMAKE_RESOURCE_ROOT
|
!contains(QMAKE_RESOURCE_FLAGS, -root):!isEmpty(QMAKE_RESOURCE_ROOT):QMAKE_RESOURCE_FLAGS += -root $$QMAKE_RESOURCE_ROOT
|
||||||
!contains(QMAKE_RESOURCE_FLAGS, -name): QMAKE_RESOURCE_FLAGS += -name ${QMAKE_FILE_BASE}
|
!contains(QMAKE_RESOURCE_FLAGS, -name): QMAKE_RESOURCE_FLAGS += -name ${QMAKE_FILE_BASE}
|
||||||
|
|
||||||
rcc.commands = $$QMAKE_RCC $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
|
isEmpty(RCC_CXX):RCC_CXX = $$QMAKE_CXX $(CXXFLAGS)
|
||||||
rcc.depend_command = $$QMAKE_RCC_DEP -list $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN}
|
RCC_OUT_BASE = $$RCC_DIR/$${first(QMAKE_MOD_RCC)}_${QMAKE_FILE_BASE}
|
||||||
rcc.CONFIG += add_inputs_as_makefile_deps
|
RCC_CPP = $$RCC_OUT_BASE$${first(QMAKE_EXT_CPP)}
|
||||||
|
RCC_TMP = $${RCC_OUT_BASE}.tmp$${first(QMAKE_EXT_OBJ)}
|
||||||
|
RCC_OBJ = $$RCC_OUT_BASE$${first(QMAKE_EXT_OBJ)}
|
||||||
|
|
||||||
|
msvc: RCC_CXX_O_FLAG = "-Fo"
|
||||||
|
else: RCC_CXX_O_FLAG = "-o "
|
||||||
|
|
||||||
rcc.input = RESOURCES
|
rcc.input = RESOURCES
|
||||||
rcc.variable_out = SOURCES
|
rcc.CONFIG += add_inputs_as_makefile_deps
|
||||||
rcc.name = RCC ${QMAKE_FILE_IN}
|
rcc.name = RCC ${QMAKE_FILE_IN}
|
||||||
|
rcc.output = $$RCC_OBJ
|
||||||
|
rcc.depend_command = $$QMAKE_RCC_DEP -list $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN}
|
||||||
|
rcc.commands = \
|
||||||
|
$$QMAKE_RCC $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} -pass 1 -o $$RCC_CPP && \
|
||||||
|
$$RCC_CXX -c $$RCC_CPP $$RCC_CXX_O_FLAG$$RCC_TMP && \
|
||||||
|
$$QMAKE_RCC $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} -pass 2 -temp $$RCC_TMP -o ${QMAKE_FILE_OUT}
|
||||||
|
rcc.clean += $$RCC_CPP $$RCC_TMP
|
||||||
silent:rcc.commands = @echo rcc ${QMAKE_FILE_IN} && $$rcc.commands
|
silent:rcc.commands = @echo rcc ${QMAKE_FILE_IN} && $$rcc.commands
|
||||||
QMAKE_EXTRA_COMPILERS += rcc
|
QMAKE_EXTRA_COMPILERS += rcc
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
** Contact: http://www.qt-project.org/legal
|
** Contact: http://www.qt-project.org/legal
|
||||||
**
|
**
|
||||||
** This file is part of the tools applications of the Qt Toolkit.
|
** This file is part of the tools applications of the Qt Toolkit.
|
||||||
@ -123,6 +123,11 @@ int runRcc(int argc, char *argv[])
|
|||||||
outputOption.setValueName(QStringLiteral("file"));
|
outputOption.setValueName(QStringLiteral("file"));
|
||||||
parser.addOption(outputOption);
|
parser.addOption(outputOption);
|
||||||
|
|
||||||
|
QCommandLineOption tempOption(QStringList() << QStringLiteral("t") << QStringLiteral("temp"));
|
||||||
|
tempOption.setDescription(QStringLiteral("Use temporary <file> for big resources."));
|
||||||
|
tempOption.setValueName(QStringLiteral("file"));
|
||||||
|
parser.addOption(tempOption);
|
||||||
|
|
||||||
QCommandLineOption nameOption(QStringLiteral("name"), QStringLiteral("Create an external initialization function with <name>."), QStringLiteral("name"));
|
QCommandLineOption nameOption(QStringLiteral("name"), QStringLiteral("Create an external initialization function with <name>."), QStringLiteral("name"));
|
||||||
parser.addOption(nameOption);
|
parser.addOption(nameOption);
|
||||||
|
|
||||||
@ -141,6 +146,9 @@ int runRcc(int argc, char *argv[])
|
|||||||
QCommandLineOption binaryOption(QStringLiteral("binary"), QStringLiteral("Output a binary file for use as a dynamic resource."));
|
QCommandLineOption binaryOption(QStringLiteral("binary"), QStringLiteral("Output a binary file for use as a dynamic resource."));
|
||||||
parser.addOption(binaryOption);
|
parser.addOption(binaryOption);
|
||||||
|
|
||||||
|
QCommandLineOption passOption(QStringLiteral("pass"), QStringLiteral("Pass number for big resources"), QStringLiteral("number"));
|
||||||
|
parser.addOption(passOption);
|
||||||
|
|
||||||
QCommandLineOption namespaceOption(QStringLiteral("namespace"), QStringLiteral("Turn off namespace macros."));
|
QCommandLineOption namespaceOption(QStringLiteral("namespace"), QStringLiteral("Turn off namespace macros."));
|
||||||
parser.addOption(namespaceOption);
|
parser.addOption(namespaceOption);
|
||||||
|
|
||||||
@ -161,7 +169,6 @@ int runRcc(int argc, char *argv[])
|
|||||||
|
|
||||||
QString errorMsg;
|
QString errorMsg;
|
||||||
RCCResourceLibrary library;
|
RCCResourceLibrary library;
|
||||||
QString outFilename = parser.value(outputOption);
|
|
||||||
if (parser.isSet(nameOption))
|
if (parser.isSet(nameOption))
|
||||||
library.setInitName(parser.value(nameOption));
|
library.setInitName(parser.value(nameOption));
|
||||||
if (parser.isSet(rootOption)) {
|
if (parser.isSet(rootOption)) {
|
||||||
@ -178,6 +185,14 @@ int runRcc(int argc, char *argv[])
|
|||||||
library.setCompressThreshold(parser.value(thresholdOption).toInt());
|
library.setCompressThreshold(parser.value(thresholdOption).toInt());
|
||||||
if (parser.isSet(binaryOption))
|
if (parser.isSet(binaryOption))
|
||||||
library.setFormat(RCCResourceLibrary::Binary);
|
library.setFormat(RCCResourceLibrary::Binary);
|
||||||
|
if (parser.isSet(passOption)) {
|
||||||
|
if (parser.value(passOption) == QStringLiteral("1"))
|
||||||
|
library.setFormat(RCCResourceLibrary::Pass1);
|
||||||
|
else if (parser.value(passOption) == QStringLiteral("2"))
|
||||||
|
library.setFormat(RCCResourceLibrary::Pass2);
|
||||||
|
else
|
||||||
|
errorMsg = QLatin1String("Pass number must be 1 or 2");
|
||||||
|
}
|
||||||
if (parser.isSet(namespaceOption))
|
if (parser.isSet(namespaceOption))
|
||||||
library.setUseNameSpace(!library.useNameSpace());
|
library.setUseNameSpace(!library.useNameSpace());
|
||||||
if (parser.isSet(verboseOption))
|
if (parser.isSet(verboseOption))
|
||||||
@ -194,6 +209,9 @@ int runRcc(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString outFilename = parser.value(outputOption);
|
||||||
|
QString tempFilename = parser.value(tempOption);
|
||||||
|
|
||||||
if (projectRequested) {
|
if (projectRequested) {
|
||||||
return createProject(outFilename);
|
return createProject(outFilename);
|
||||||
}
|
}
|
||||||
@ -217,11 +235,21 @@ int runRcc(int argc, char *argv[])
|
|||||||
if (!library.readFiles(list, errorDevice))
|
if (!library.readFiles(list, errorDevice))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// open output
|
|
||||||
QFile out;
|
QFile out;
|
||||||
QIODevice::OpenMode mode = QIODevice::WriteOnly;
|
|
||||||
if (library.format() == RCCResourceLibrary::C_Code)
|
// open output
|
||||||
mode |= QIODevice::Text;
|
QIODevice::OpenMode mode = QIODevice::NotOpen;
|
||||||
|
switch (library.format()) {
|
||||||
|
case RCCResourceLibrary::C_Code:
|
||||||
|
case RCCResourceLibrary::Pass1:
|
||||||
|
mode = QIODevice::WriteOnly | QIODevice::Text;
|
||||||
|
break;
|
||||||
|
case RCCResourceLibrary::Pass2:
|
||||||
|
case RCCResourceLibrary::Binary:
|
||||||
|
mode = QIODevice::WriteOnly;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (outFilename.isEmpty() || outFilename == QLatin1String("-")) {
|
if (outFilename.isEmpty() || outFilename == QLatin1String("-")) {
|
||||||
// using this overload close() only flushes.
|
// using this overload close() only flushes.
|
||||||
@ -245,7 +273,17 @@ int runRcc(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return library.output(out, errorDevice) ? 0 : 1;
|
QFile temp;
|
||||||
|
if (!tempFilename.isEmpty()) {
|
||||||
|
temp.setFileName(tempFilename);
|
||||||
|
if (!temp.open(QIODevice::ReadOnly)) {
|
||||||
|
const QString msg = QString::fromUtf8("Unable to open temporary file %1 for reading: %2\n")
|
||||||
|
.arg(outFilename).arg(out.errorString());
|
||||||
|
errorDevice.write(msg.toUtf8());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return library.output(out, temp, errorDevice) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_CORE_EXPORT extern QBasicAtomicInt qt_qhash_seed; // from qhash.cpp
|
Q_CORE_EXPORT extern QBasicAtomicInt qt_qhash_seed; // from qhash.cpp
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
** Contact: http://www.qt-project.org/legal
|
** Contact: http://www.qt-project.org/legal
|
||||||
**
|
**
|
||||||
** This file is part of the tools applications of the Qt Toolkit.
|
** This file is part of the tools applications of the Qt Toolkit.
|
||||||
@ -77,7 +77,11 @@ void RCCResourceLibrary::write(const char *str, int len)
|
|||||||
|
|
||||||
void RCCResourceLibrary::writeByteArray(const QByteArray &other)
|
void RCCResourceLibrary::writeByteArray(const QByteArray &other)
|
||||||
{
|
{
|
||||||
m_out.append(other);
|
if (m_format == Pass2) {
|
||||||
|
m_outDevice->write(other);
|
||||||
|
} else {
|
||||||
|
m_out.append(other);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QString msgOpenReadFailed(const QString &fname, const QString &why)
|
static inline QString msgOpenReadFailed(const QString &fname, const QString &why)
|
||||||
@ -164,9 +168,10 @@ QString RCCFileInfo::resourceName() const
|
|||||||
|
|
||||||
void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
|
void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
|
||||||
{
|
{
|
||||||
const bool text = (lib.m_format == RCCResourceLibrary::C_Code);
|
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
|
||||||
|
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
|
||||||
//some info
|
//some info
|
||||||
if (text) {
|
if (text || pass1) {
|
||||||
if (m_language != QLocale::C) {
|
if (m_language != QLocale::C) {
|
||||||
lib.writeString(" // ");
|
lib.writeString(" // ");
|
||||||
lib.writeByteArray(resourceName().toLocal8Bit());
|
lib.writeByteArray(resourceName().toLocal8Bit());
|
||||||
@ -209,14 +214,17 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
|
|||||||
//data offset
|
//data offset
|
||||||
lib.writeNumber4(m_dataOffset);
|
lib.writeNumber4(m_dataOffset);
|
||||||
}
|
}
|
||||||
if (text)
|
if (text || pass1)
|
||||||
lib.writeChar('\n');
|
lib.writeChar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
|
qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
const bool text = (lib.m_format == RCCResourceLibrary::C_Code);
|
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
|
||||||
|
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
|
||||||
|
const bool pass2 = lib.m_format == RCCResourceLibrary::Pass2;
|
||||||
|
const bool binary = lib.m_format == RCCResourceLibrary::Binary;
|
||||||
|
|
||||||
//capture the offset
|
//capture the offset
|
||||||
m_dataOffset = offset;
|
m_dataOffset = offset;
|
||||||
@ -244,7 +252,7 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
|
|||||||
#endif // QT_NO_COMPRESS
|
#endif // QT_NO_COMPRESS
|
||||||
|
|
||||||
// some info
|
// some info
|
||||||
if (text) {
|
if (text || pass1) {
|
||||||
lib.writeString(" // ");
|
lib.writeString(" // ");
|
||||||
lib.writeByteArray(m_fileInfo.absoluteFilePath().toLocal8Bit());
|
lib.writeByteArray(m_fileInfo.absoluteFilePath().toLocal8Bit());
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
@ -252,8 +260,9 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
|
|||||||
|
|
||||||
// write the length
|
// write the length
|
||||||
|
|
||||||
lib.writeNumber4(data.size());
|
if (text || binary || pass2)
|
||||||
if (text)
|
lib.writeNumber4(data.size());
|
||||||
|
if (text || pass1)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
@ -267,27 +276,27 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
|
|||||||
j = 16;
|
j = 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (binary || pass2) {
|
||||||
for (int i = data.size(); --i >= 0; )
|
lib.writeByteArray(data);
|
||||||
lib.writeChar(*p++);
|
|
||||||
}
|
}
|
||||||
offset += data.size();
|
offset += data.size();
|
||||||
|
|
||||||
// done
|
// done
|
||||||
if (text)
|
if (text || pass1)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
|
qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
|
||||||
{
|
{
|
||||||
const bool text = (lib.m_format == RCCResourceLibrary::C_Code);
|
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
|
||||||
|
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
|
||||||
|
|
||||||
// capture the offset
|
// capture the offset
|
||||||
m_nameOffset = offset;
|
m_nameOffset = offset;
|
||||||
|
|
||||||
// some info
|
// some info
|
||||||
if (text) {
|
if (text || pass1) {
|
||||||
lib.writeString(" // ");
|
lib.writeString(" // ");
|
||||||
lib.writeByteArray(m_name.toLocal8Bit());
|
lib.writeByteArray(m_name.toLocal8Bit());
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
@ -295,13 +304,13 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
|
|||||||
|
|
||||||
// write the length
|
// write the length
|
||||||
lib.writeNumber2(m_name.length());
|
lib.writeNumber2(m_name.length());
|
||||||
if (text)
|
if (text || pass1)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
// write the hash
|
// write the hash
|
||||||
lib.writeNumber4(qt_hash(m_name));
|
lib.writeNumber4(qt_hash(m_name));
|
||||||
if (text)
|
if (text || pass1)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
@ -309,13 +318,13 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
|
|||||||
const QChar *unicode = m_name.unicode();
|
const QChar *unicode = m_name.unicode();
|
||||||
for (int i = 0; i < m_name.length(); ++i) {
|
for (int i = 0; i < m_name.length(); ++i) {
|
||||||
lib.writeNumber2(unicode[i].unicode());
|
lib.writeNumber2(unicode[i].unicode());
|
||||||
if (text && i % 16 == 0)
|
if ((text || pass1) && i % 16 == 0)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
}
|
}
|
||||||
offset += m_name.length()*2;
|
offset += m_name.length()*2;
|
||||||
|
|
||||||
// done
|
// done
|
||||||
if (text)
|
if (text || pass1)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
@ -349,7 +358,8 @@ RCCResourceLibrary::RCCResourceLibrary()
|
|||||||
m_namesOffset(0),
|
m_namesOffset(0),
|
||||||
m_dataOffset(0),
|
m_dataOffset(0),
|
||||||
m_useNameSpace(CONSTANT_USENAMESPACE),
|
m_useNameSpace(CONSTANT_USENAMESPACE),
|
||||||
m_errorDevice(0)
|
m_errorDevice(0),
|
||||||
|
m_outDevice(0)
|
||||||
{
|
{
|
||||||
m_out.reserve(30 * 1000 * 1000);
|
m_out.reserve(30 * 1000 * 1000);
|
||||||
}
|
}
|
||||||
@ -717,9 +727,39 @@ RCCResourceLibrary::ResourceDataFileMap RCCResourceLibrary::resourceDataFileMap(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &errorDevice)
|
bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &tempDevice, QIODevice &errorDevice)
|
||||||
{
|
{
|
||||||
m_errorDevice = &errorDevice;
|
m_errorDevice = &errorDevice;
|
||||||
|
|
||||||
|
const char pattern[] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };
|
||||||
|
if (m_format == Pass2) {
|
||||||
|
char c;
|
||||||
|
for (int i = 0; i < 8; ) {
|
||||||
|
if (!tempDevice.getChar(&c)) {
|
||||||
|
m_errorDevice->write("No data signature found\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c == pattern[i]) {
|
||||||
|
++i;
|
||||||
|
} else {
|
||||||
|
for (int k = 0; k < i; ++k)
|
||||||
|
outDevice.putChar(pattern[k]);
|
||||||
|
outDevice.putChar(c);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_outDevice = &outDevice;
|
||||||
|
quint64 start = outDevice.pos();
|
||||||
|
writeDataBlobs();
|
||||||
|
quint64 len = outDevice.pos() - start;
|
||||||
|
|
||||||
|
tempDevice.seek(tempDevice.pos() + len - 8);
|
||||||
|
outDevice.write(tempDevice.readAll());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//write out
|
//write out
|
||||||
if (m_verbose)
|
if (m_verbose)
|
||||||
m_errorDevice->write("Outputting code\n");
|
m_errorDevice->write("Outputting code\n");
|
||||||
@ -776,7 +816,12 @@ void RCCResourceLibrary::writeNumber2(quint16 number)
|
|||||||
|
|
||||||
void RCCResourceLibrary::writeNumber4(quint32 number)
|
void RCCResourceLibrary::writeNumber4(quint32 number)
|
||||||
{
|
{
|
||||||
if (m_format == RCCResourceLibrary::Binary) {
|
if (m_format == RCCResourceLibrary::Pass2) {
|
||||||
|
m_outDevice->putChar(char(number >> 24));
|
||||||
|
m_outDevice->putChar(char(number >> 16));
|
||||||
|
m_outDevice->putChar(char(number >> 8));
|
||||||
|
m_outDevice->putChar(char(number));
|
||||||
|
} else if (m_format == RCCResourceLibrary::Binary) {
|
||||||
writeChar(number >> 24);
|
writeChar(number >> 24);
|
||||||
writeChar(number >> 16);
|
writeChar(number >> 16);
|
||||||
writeChar(number >> 8);
|
writeChar(number >> 8);
|
||||||
@ -791,7 +836,7 @@ void RCCResourceLibrary::writeNumber4(quint32 number)
|
|||||||
|
|
||||||
bool RCCResourceLibrary::writeHeader()
|
bool RCCResourceLibrary::writeHeader()
|
||||||
{
|
{
|
||||||
if (m_format == C_Code) {
|
if (m_format == C_Code || m_format == Pass1) {
|
||||||
writeString("/****************************************************************************\n");
|
writeString("/****************************************************************************\n");
|
||||||
writeString("** Resource object code\n");
|
writeString("** Resource object code\n");
|
||||||
writeString("**\n");
|
writeString("**\n");
|
||||||
@ -800,7 +845,6 @@ bool RCCResourceLibrary::writeHeader()
|
|||||||
writeString("\n**\n");
|
writeString("\n**\n");
|
||||||
writeString("** WARNING! All changes made in this file will be lost!\n");
|
writeString("** WARNING! All changes made in this file will be lost!\n");
|
||||||
writeString( "*****************************************************************************/\n\n");
|
writeString( "*****************************************************************************/\n\n");
|
||||||
writeString("#include <QtCore/qglobal.h>\n\n");
|
|
||||||
} else if (m_format == Binary) {
|
} else if (m_format == Binary) {
|
||||||
writeString("qres");
|
writeString("qres");
|
||||||
writeNumber4(0);
|
writeNumber4(0);
|
||||||
@ -814,15 +858,16 @@ bool RCCResourceLibrary::writeHeader()
|
|||||||
bool RCCResourceLibrary::writeDataBlobs()
|
bool RCCResourceLibrary::writeDataBlobs()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_errorDevice);
|
Q_ASSERT(m_errorDevice);
|
||||||
if (m_format == C_Code)
|
if (m_format == C_Code) {
|
||||||
writeString("static const unsigned char qt_resource_data[] = {\n");
|
writeString("static const unsigned char qt_resource_data[] = {\n");
|
||||||
else if (m_format == Binary)
|
} else if (m_format == Binary) {
|
||||||
m_dataOffset = m_out.size();
|
m_dataOffset = m_out.size();
|
||||||
QStack<RCCFileInfo*> pending;
|
}
|
||||||
|
|
||||||
if (!m_root)
|
if (!m_root)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
QStack<RCCFileInfo*> pending;
|
||||||
pending.push(m_root);
|
pending.push(m_root);
|
||||||
qint64 offset = 0;
|
qint64 offset = 0;
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
@ -844,12 +889,17 @@ bool RCCResourceLibrary::writeDataBlobs()
|
|||||||
}
|
}
|
||||||
if (m_format == C_Code)
|
if (m_format == C_Code)
|
||||||
writeString("\n};\n\n");
|
writeString("\n};\n\n");
|
||||||
|
else if (m_format == Pass1) {
|
||||||
|
writeString("\nstatic const unsigned char qt_resource_data[");
|
||||||
|
writeByteArray(QByteArray::number(offset));
|
||||||
|
writeString("] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };\n\n");
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RCCResourceLibrary::writeDataNames()
|
bool RCCResourceLibrary::writeDataNames()
|
||||||
{
|
{
|
||||||
if (m_format == C_Code)
|
if (m_format == C_Code || m_format == Pass1)
|
||||||
writeString("static const unsigned char qt_resource_name[] = {\n");
|
writeString("static const unsigned char qt_resource_name[] = {\n");
|
||||||
else if (m_format == Binary)
|
else if (m_format == Binary)
|
||||||
m_namesOffset = m_out.size();
|
m_namesOffset = m_out.size();
|
||||||
@ -877,7 +927,7 @@ bool RCCResourceLibrary::writeDataNames()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_format == C_Code)
|
if (m_format == C_Code || m_format == Pass1)
|
||||||
writeString("\n};\n\n");
|
writeString("\n};\n\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -889,7 +939,7 @@ static bool qt_rcc_compare_hash(const RCCFileInfo *left, const RCCFileInfo *righ
|
|||||||
|
|
||||||
bool RCCResourceLibrary::writeDataStructure()
|
bool RCCResourceLibrary::writeDataStructure()
|
||||||
{
|
{
|
||||||
if (m_format == C_Code)
|
if (m_format == C_Code || m_format == Pass1)
|
||||||
writeString("static const unsigned char qt_resource_struct[] = {\n");
|
writeString("static const unsigned char qt_resource_struct[] = {\n");
|
||||||
else if (m_format == Binary)
|
else if (m_format == Binary)
|
||||||
m_treeOffset = m_out.size();
|
m_treeOffset = m_out.size();
|
||||||
@ -936,7 +986,7 @@ bool RCCResourceLibrary::writeDataStructure()
|
|||||||
pending.push(child);
|
pending.push(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_format == C_Code)
|
if (m_format == C_Code || m_format == Pass1)
|
||||||
writeString("\n};\n\n");
|
writeString("\n};\n\n");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -966,7 +1016,7 @@ void RCCResourceLibrary::writeAddNamespaceFunction(const QByteArray &name)
|
|||||||
|
|
||||||
bool RCCResourceLibrary::writeInitializer()
|
bool RCCResourceLibrary::writeInitializer()
|
||||||
{
|
{
|
||||||
if (m_format == C_Code) {
|
if (m_format == C_Code || m_format == Pass1) {
|
||||||
//write("\nQT_BEGIN_NAMESPACE\n");
|
//write("\nQT_BEGIN_NAMESPACE\n");
|
||||||
QString initNameStr = m_initName;
|
QString initNameStr = m_initName;
|
||||||
if (!initNameStr.isEmpty()) {
|
if (!initNameStr.isEmpty()) {
|
||||||
@ -976,18 +1026,36 @@ bool RCCResourceLibrary::writeInitializer()
|
|||||||
QByteArray initName = initNameStr.toLatin1();
|
QByteArray initName = initNameStr.toLatin1();
|
||||||
|
|
||||||
//init
|
//init
|
||||||
if (m_useNameSpace)
|
if (m_useNameSpace) {
|
||||||
writeString("QT_BEGIN_NAMESPACE\n\n");
|
writeString("#ifdef QT_NAMESPACE\n"
|
||||||
|
"# define QT_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name\n"
|
||||||
|
"# define QT_MANGLE_NAMESPACE0(x) x\n"
|
||||||
|
"# define QT_MANGLE_NAMESPACE1(a, b) a##_##b\n"
|
||||||
|
"# define QT_MANGLE_NAMESPACE2(a, b) QT_MANGLE_NAMESPACE1(a,b)\n"
|
||||||
|
"# define QT_MANGLE_NAMESPACE(name) QT_MANGLE_NAMESPACE2( \\\n"
|
||||||
|
" QT_MANGLE_NAMESPACE0(name), QT_MANGLE_NAMESPACE0(QT_NAMESPACE))\n"
|
||||||
|
"#else\n"
|
||||||
|
"# define QT_PREPEND_NAMESPACE(name) name\n"
|
||||||
|
"# define QT_MANGLE_NAMESPACE(name) name\n"
|
||||||
|
"#endif\n\n");
|
||||||
|
|
||||||
|
writeString("#ifdef QT_NAMESPACE\n"
|
||||||
|
"namespace QT_NAMESPACE {\n"
|
||||||
|
"#endif\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (m_root) {
|
if (m_root) {
|
||||||
writeString("extern Q_CORE_EXPORT bool qRegisterResourceData\n "
|
writeString("bool qRegisterResourceData"
|
||||||
"(int, const unsigned char *, "
|
"(int, const unsigned char *, "
|
||||||
"const unsigned char *, const unsigned char *);\n\n");
|
"const unsigned char *, const unsigned char *);\n\n");
|
||||||
writeString("extern Q_CORE_EXPORT bool qUnregisterResourceData\n "
|
writeString("bool qUnregisterResourceData"
|
||||||
"(int, const unsigned char *, "
|
"(int, const unsigned char *, "
|
||||||
"const unsigned char *, const unsigned char *);\n\n");
|
"const unsigned char *, const unsigned char *);\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_useNameSpace)
|
if (m_useNameSpace)
|
||||||
writeString("QT_END_NAMESPACE\n\n\n");
|
writeString("#ifdef QT_NAMESPACE\n}\n#endif\n\n");
|
||||||
|
|
||||||
QByteArray initResources = "qInitResources";
|
QByteArray initResources = "qInitResources";
|
||||||
initResources += initName;
|
initResources += initName;
|
||||||
writeString("int ");
|
writeString("int ");
|
||||||
@ -1002,9 +1070,6 @@ bool RCCResourceLibrary::writeInitializer()
|
|||||||
}
|
}
|
||||||
writeString(" return 1;\n");
|
writeString(" return 1;\n");
|
||||||
writeString("}\n\n");
|
writeString("}\n\n");
|
||||||
writeString("Q_CONSTRUCTOR_FUNCTION(");
|
|
||||||
writeMangleNamespaceFunction(initResources);
|
|
||||||
writeString(")\n\n");
|
|
||||||
|
|
||||||
//cleanup
|
//cleanup
|
||||||
QByteArray cleanResources = "qCleanupResources";
|
QByteArray cleanResources = "qCleanupResources";
|
||||||
@ -1020,9 +1085,15 @@ bool RCCResourceLibrary::writeInitializer()
|
|||||||
}
|
}
|
||||||
writeString(" return 1;\n");
|
writeString(" return 1;\n");
|
||||||
writeString("}\n\n");
|
writeString("}\n\n");
|
||||||
writeString("Q_DESTRUCTOR_FUNCTION(");
|
|
||||||
writeMangleNamespaceFunction(cleanResources);
|
writeByteArray(
|
||||||
writeString(")\n\n");
|
"namespace {\n"
|
||||||
|
" struct initializer {\n"
|
||||||
|
" initializer() { QT_MANGLE_NAMESPACE(" + initResources + ")(); }\n"
|
||||||
|
" ~initializer() { QT_MANGLE_NAMESPACE(" + cleanResources + ")(); }\n"
|
||||||
|
" } dummy;\n"
|
||||||
|
"}\n");
|
||||||
|
|
||||||
} else if (m_format == Binary) {
|
} else if (m_format == Binary) {
|
||||||
int i = 4;
|
int i = 4;
|
||||||
char *p = m_out.data();
|
char *p = m_out.data();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
** Contact: http://www.qt-project.org/legal
|
** Contact: http://www.qt-project.org/legal
|
||||||
**
|
**
|
||||||
** This file is part of the tools applications of the Qt Toolkit.
|
** This file is part of the tools applications of the Qt Toolkit.
|
||||||
@ -64,11 +64,11 @@ public:
|
|||||||
RCCResourceLibrary();
|
RCCResourceLibrary();
|
||||||
~RCCResourceLibrary();
|
~RCCResourceLibrary();
|
||||||
|
|
||||||
bool output(QIODevice &out, QIODevice &errorDevice);
|
bool output(QIODevice &outDevice, QIODevice &tempDevice, QIODevice &errorDevice);
|
||||||
|
|
||||||
bool readFiles(bool ignoreErrors, QIODevice &errorDevice);
|
bool readFiles(bool ignoreErrors, QIODevice &errorDevice);
|
||||||
|
|
||||||
enum Format { Binary, C_Code };
|
enum Format { Binary, C_Code, Pass1, Pass2 };
|
||||||
void setFormat(Format f) { m_format = f; }
|
void setFormat(Format f) { m_format = f; }
|
||||||
Format format() const { return m_format; }
|
Format format() const { return m_format; }
|
||||||
|
|
||||||
@ -87,6 +87,9 @@ public:
|
|||||||
void setInitName(const QString &name) { m_initName = name; }
|
void setInitName(const QString &name) { m_initName = name; }
|
||||||
QString initName() const { return m_initName; }
|
QString initName() const { return m_initName; }
|
||||||
|
|
||||||
|
void setOutputName(const QString &name) { m_outputName = name; }
|
||||||
|
QString outputName() const { return m_outputName; }
|
||||||
|
|
||||||
void setCompressLevel(int c) { m_compressLevel = c; }
|
void setCompressLevel(int c) { m_compressLevel = c; }
|
||||||
int compressLevel() const { return m_compressLevel; }
|
int compressLevel() const { return m_compressLevel; }
|
||||||
|
|
||||||
@ -137,6 +140,7 @@ private:
|
|||||||
QStringList m_fileNames;
|
QStringList m_fileNames;
|
||||||
QString m_resourceRoot;
|
QString m_resourceRoot;
|
||||||
QString m_initName;
|
QString m_initName;
|
||||||
|
QString m_outputName;
|
||||||
Format m_format;
|
Format m_format;
|
||||||
bool m_verbose;
|
bool m_verbose;
|
||||||
int m_compressLevel;
|
int m_compressLevel;
|
||||||
@ -147,6 +151,7 @@ private:
|
|||||||
bool m_useNameSpace;
|
bool m_useNameSpace;
|
||||||
QStringList m_failedResources;
|
QStringList m_failedResources;
|
||||||
QIODevice *m_errorDevice;
|
QIODevice *m_errorDevice;
|
||||||
|
QIODevice *m_outDevice;
|
||||||
QByteArray m_out;
|
QByteArray m_out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** Resource object code
|
** Resource object code
|
||||||
**
|
**
|
||||||
IGNORE: ** Created by: The Resource Compiler for Qt version 5.0.0
|
IGNORE: ** Created by: The Resource Compiler for Qt version 5.3.1
|
||||||
**
|
**
|
||||||
** WARNING! All changes made in this file will be lost!
|
** WARNING! All changes made in this file will be lost!
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
|
||||||
|
|
||||||
static const unsigned char qt_resource_data[] = {
|
static const unsigned char qt_resource_data[] = {
|
||||||
IGNORE: // /dev/qt5/qtbase/tests/auto/tools/rcc/data/images/images/circle.png
|
IGNORE: // /dev/qt5/qtbase/tests/auto/tools/rcc/data/images/images/circle.png
|
||||||
0x0,0x0,0x0,0xa5,
|
0x0,0x0,0x0,0xa5,
|
||||||
@ -94,16 +92,29 @@ static const unsigned char qt_resource_struct[] = {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
#ifdef QT_NAMESPACE
|
||||||
|
# define QT_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
|
||||||
|
# define QT_MANGLE_NAMESPACE0(x) x
|
||||||
|
# define QT_MANGLE_NAMESPACE1(a, b) a##_##b
|
||||||
|
# define QT_MANGLE_NAMESPACE2(a, b) QT_MANGLE_NAMESPACE1(a,b)
|
||||||
|
# define QT_MANGLE_NAMESPACE(name) QT_MANGLE_NAMESPACE2( \
|
||||||
|
QT_MANGLE_NAMESPACE0(name), QT_MANGLE_NAMESPACE0(QT_NAMESPACE))
|
||||||
|
#else
|
||||||
|
# define QT_PREPEND_NAMESPACE(name) name
|
||||||
|
# define QT_MANGLE_NAMESPACE(name) name
|
||||||
|
#endif
|
||||||
|
|
||||||
extern Q_CORE_EXPORT bool qRegisterResourceData
|
#ifdef QT_NAMESPACE
|
||||||
(int, const unsigned char *, const unsigned char *, const unsigned char *);
|
namespace QT_NAMESPACE {
|
||||||
|
#endif
|
||||||
|
|
||||||
extern Q_CORE_EXPORT bool qUnregisterResourceData
|
bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
|
||||||
(int, const unsigned char *, const unsigned char *, const unsigned char *);
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
|
||||||
|
|
||||||
|
#ifdef QT_NAMESPACE
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int QT_MANGLE_NAMESPACE(qInitResources)()
|
int QT_MANGLE_NAMESPACE(qInitResources)()
|
||||||
{
|
{
|
||||||
@ -112,8 +123,6 @@ int QT_MANGLE_NAMESPACE(qInitResources)()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources))
|
|
||||||
|
|
||||||
int QT_MANGLE_NAMESPACE(qCleanupResources)()
|
int QT_MANGLE_NAMESPACE(qCleanupResources)()
|
||||||
{
|
{
|
||||||
QT_PREPEND_NAMESPACE(qUnregisterResourceData)
|
QT_PREPEND_NAMESPACE(qUnregisterResourceData)
|
||||||
@ -121,5 +130,9 @@ int QT_MANGLE_NAMESPACE(qCleanupResources)()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DESTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qCleanupResources))
|
namespace {
|
||||||
|
struct initializer {
|
||||||
|
initializer() { QT_MANGLE_NAMESPACE(qInitResources)(); }
|
||||||
|
~initializer() { QT_MANGLE_NAMESPACE(qCleanupResources)(); }
|
||||||
|
} dummy;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user