summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/androiddeployqt/main.cpp19
-rw-r--r--src/tools/bootstrap/bootstrap.pro6
-rw-r--r--src/tools/moc/generator.cpp6
-rw-r--r--src/tools/moc/main.cpp131
-rw-r--r--src/tools/moc/moc.cpp5
-rw-r--r--src/tools/moc/moc.h1
-rw-r--r--src/tools/rcc/rcc.cpp26
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.cpp4
8 files changed, 173 insertions, 25 deletions
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index aa8c91865e..00da778fe6 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -1738,17 +1738,18 @@ bool scanImports(Options *options, QSet<QString> *usedDependencies)
qmlImportScanner += QLatin1String(" -qrcFiles");
for (const QString &qrcFile : options->qrcFiles)
qmlImportScanner += QLatin1Char(' ') + shellQuote(qrcFile);
- } else {
- if (rootPath.isEmpty())
- rootPath = QFileInfo(options->inputFileName).absolutePath();
- else
- rootPath = QFileInfo(rootPath).absoluteFilePath();
-
- if (!rootPath.endsWith(QLatin1Char('/')))
- rootPath += QLatin1Char('/');
- qmlImportScanner += QLatin1String(" -rootPath %1").arg(shellQuote(rootPath));
}
+ if (rootPath.isEmpty())
+ rootPath = QFileInfo(options->inputFileName).absolutePath();
+ else
+ rootPath = QFileInfo(rootPath).absoluteFilePath();
+
+ if (!rootPath.endsWith(QLatin1Char('/')))
+ rootPath += QLatin1Char('/');
+
+ qmlImportScanner += QLatin1String(" -rootPath %1").arg(shellQuote(rootPath));
+
QStringList importPaths;
importPaths += shellQuote(options->qtInstallDirectory + QLatin1String("/qml"));
if (!rootPath.isEmpty())
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index c784e35607..b68bed436e 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -19,6 +19,10 @@ DEFINES += \
QT_NO_FOREACH \
QT_NO_CAST_FROM_ASCII
+INCLUDEPATH += \
+ $$PWD/.. \
+ $$PWD/../../3rdparty/tinycbor/src
+
SOURCES += \
../../corelib/codecs/qlatincodec.cpp \
../../corelib/codecs/qtextcodec.cpp \
@@ -63,6 +67,8 @@ SOURCES += \
../../corelib/kernel/qsharedmemory.cpp \
../../corelib/kernel/qsystemsemaphore.cpp \
../../corelib/plugin/quuid.cpp \
+ ../../corelib/serialization/qcborcommon.cpp \
+ ../../corelib/serialization/qcborstreamwriter.cpp \
../../corelib/serialization/qcborvalue.cpp \
../../corelib/serialization/qdatastream.cpp \
../../corelib/serialization/qjsoncbor.cpp \
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 04686db788..43bbe5ad02 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -458,7 +458,7 @@ void Generator::generateCode()
// Build extra array
//
QVector<QByteArray> extraList;
- QHash<QByteArray, QByteArray> knownExtraMetaObject = knownGadgets;
+ QMultiHash<QByteArray, QByteArray> knownExtraMetaObject = knownGadgets;
knownExtraMetaObject.unite(knownQObjectClasses);
for (int i = 0; i < cdef->propertyList.count(); ++i) {
@@ -534,8 +534,10 @@ void Generator::generateCode()
if (isQObject)
fprintf(out, " nullptr,\n");
- else if (cdef->superclassList.size() && (!cdef->hasQGadget || knownGadgets.contains(purestSuperClass)))
+ else if (cdef->superclassList.size() && !cdef->hasQGadget) // for qobject, we know the super class must have a static metaobject
fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.constData());
+ else if (cdef->superclassList.size()) // for gadgets we need to query at compile time for it
+ fprintf(out, " QtPrivate::MetaObjectForType<%s>::value(),\n", purestSuperClass.constData());
else
fprintf(out, " nullptr,\n");
fprintf(out, " qt_meta_stringdata_%s.offsetsAndSize,\n"
diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp
index 4aa040a9bb..b8c2d7f594 100644
--- a/src/tools/moc/main.cpp
+++ b/src/tools/moc/main.cpp
@@ -175,6 +175,49 @@ static QStringList argumentsFromCommandLineAndFile(const QStringList &arguments)
return allArguments;
}
+// Escape characters in given path. Dependency paths are Make-style, not NMake/Jom style.
+// The paths can also be consumed by Ninja.
+// "$" replaced by "$$"
+// "#" replaced by "\#"
+// " " replaced by "\ "
+// "\#" replaced by "\\#"
+// "\ " replaced by "\\\ "
+//
+// The escape rules are according to what clang / llvm escapes when generating a Make-style
+// dependency file.
+// Is a template function, because input param can be either a QString or a QByteArray.
+template <typename T> struct CharType;
+template <> struct CharType<QString> { using type = QLatin1Char; };
+template <> struct CharType<QByteArray> { using type = char; };
+template <typename StringType>
+StringType escapeDependencyPath(const StringType &path)
+{
+ using CT = typename CharType<StringType>::type;
+ StringType escapedPath;
+ int size = path.size();
+ escapedPath.reserve(size);
+ for (int i = 0; i < size; ++i) {
+ if (path[i] == CT('$')) {
+ escapedPath.append(CT('$'));
+ } else if (path[i] == CT('#')) {
+ escapedPath.append(CT('\\'));
+ } else if (path[i] == CT(' ')) {
+ escapedPath.append(CT('\\'));
+ int backwards_it = i - 1;
+ while (backwards_it > 0 && path[backwards_it] == CT('\\')) {
+ escapedPath.append(CT('\\'));
+ --backwards_it;
+ }
+ }
+ escapedPath.append(path[i]);
+ }
+ return escapedPath;
+}
+
+QByteArray escapeAndEncodeDependencyPath(const QString &path)
+{
+ return QFile::encodeName(escapeDependencyPath(path));
+}
int runMoc(int argc, char **argv)
{
@@ -308,6 +351,22 @@ int runMoc(int argc, char **argv)
collectOption.setDescription(QStringLiteral("Instead of processing C++ code, collect previously generated JSON output into a single file."));
parser.addOption(collectOption);
+ QCommandLineOption depFileOption(QStringLiteral("output-dep-file"));
+ depFileOption.setDescription(
+ QStringLiteral("Output a Make-style dep file for build system consumption."));
+ parser.addOption(depFileOption);
+
+ QCommandLineOption depFilePathOption(QStringLiteral("dep-file-path"));
+ depFilePathOption.setDescription(QStringLiteral("Path where to write the dep file."));
+ depFilePathOption.setValueName(QStringLiteral("file"));
+ parser.addOption(depFilePathOption);
+
+ QCommandLineOption depFileRuleNameOption(QStringLiteral("dep-file-rule-name"));
+ depFileRuleNameOption.setDescription(
+ QStringLiteral("The rule name (first line) of the dep file."));
+ depFileRuleNameOption.setValueName(QStringLiteral("rule name"));
+ parser.addOption(depFileRuleNameOption);
+
parser.addPositionalArgument(QStringLiteral("[header-file]"),
QStringLiteral("Header file to read from, otherwise stdin."));
parser.addPositionalArgument(QStringLiteral("[@option-file]"),
@@ -476,6 +535,7 @@ int runMoc(int argc, char **argv)
// 1. preprocess
const auto includeFiles = parser.values(includeOption);
+ QStringList validIncludesFiles;
for (const QString &includeName : includeFiles) {
QByteArray rawName = pp.resolveInclude(QFile::encodeName(includeName), moc.filename);
if (rawName.isEmpty()) {
@@ -488,6 +548,7 @@ int runMoc(int argc, char **argv)
moc.symbols += Symbol(0, MOC_INCLUDE_BEGIN, rawName);
moc.symbols += pp.preprocessed(rawName, &f);
moc.symbols += Symbol(0, MOC_INCLUDE_END, rawName);
+ validIncludesFiles.append(includeName);
} else {
fprintf(stderr, "Warning: Cannot open %s included by moc file %s: %s\n",
rawName.constData(),
@@ -507,6 +568,7 @@ int runMoc(int argc, char **argv)
QScopedPointer<FILE, ScopedPointerFileCloser> jsonOutput;
+ bool outputToFile = true;
if (output.size()) { // output file specified
#if defined(_MSC_VER)
if (_wfopen_s(&out, reinterpret_cast<const wchar_t *>(output.utf16()), L"w") != 0)
@@ -535,6 +597,7 @@ int runMoc(int argc, char **argv)
}
} else { // use stdout
out = stdout;
+ outputToFile = false;
}
if (pp.preprocessOnly) {
@@ -549,6 +612,74 @@ int runMoc(int argc, char **argv)
if (output.size())
fclose(out);
+ if (parser.isSet(depFileOption)) {
+ // 4. write a Make-style dependency file (can also be consumed by Ninja).
+ QString depOutputFileName;
+ QString depRuleName = output;
+
+ if (parser.isSet(depFileRuleNameOption))
+ depRuleName = parser.value(depFileRuleNameOption);
+
+ if (parser.isSet(depFilePathOption)) {
+ depOutputFileName = parser.value(depFilePathOption);
+ } else if (outputToFile) {
+ depOutputFileName = output + QLatin1String(".d");
+ } else {
+ fprintf(stderr, "moc: Writing to stdout, but no depfile path specified.\n");
+ }
+
+ QScopedPointer<FILE, ScopedPointerFileCloser> depFileHandle;
+ FILE *depFileHandleRaw;
+#if defined(_MSC_VER)
+ if (_wfopen_s(&depFileHandleRaw,
+ reinterpret_cast<const wchar_t *>(depOutputFileName.utf16()), L"w") != 0)
+#else
+ depFileHandleRaw = fopen(QFile::encodeName(depOutputFileName).constData(), "w");
+ if (!depFileHandleRaw)
+#endif
+ fprintf(stderr, "moc: Cannot create dep output file '%s'. %s\n",
+ QFile::encodeName(depOutputFileName).constData(),
+ strerror(errno));
+ depFileHandle.reset(depFileHandleRaw);
+
+ if (!depFileHandle.isNull()) {
+ // First line is the path to the generated file.
+ fprintf(depFileHandle.data(), "%s: ",
+ escapeAndEncodeDependencyPath(depRuleName).constData());
+
+ QByteArrayList dependencies;
+
+ // If there's an input file, it's the first dependency.
+ if (!filename.isEmpty()) {
+ dependencies.append(escapeAndEncodeDependencyPath(filename).constData());
+ }
+
+ // Additional passed-in includes are dependencies (like moc_predefs.h).
+ for (const QString &includeName : validIncludesFiles) {
+ dependencies.append(escapeAndEncodeDependencyPath(includeName).constData());
+ }
+
+ // Plugin metadata json files discovered via Q_PLUGIN_METADATA macros are also
+ // dependencies.
+ for (const QString &pluginMetadataFile : moc.parsedPluginMetadataFiles) {
+ dependencies.append(escapeAndEncodeDependencyPath(pluginMetadataFile).constData());
+ }
+
+ // All pre-processed includes are dependnecies.
+ // Sort the entries for easier human consumption.
+ auto includeList = pp.preprocessedIncludes.values();
+ std::sort(includeList.begin(), includeList.end());
+
+ for (QByteArray &includeName : includeList) {
+ dependencies.append(escapeDependencyPath(includeName));
+ }
+
+ // Join dependencies, output them, and output a final new line.
+ const auto dependenciesJoined = dependencies.join(QByteArrayLiteral(" \\\n "));
+ fprintf(depFileHandle.data(), "%s\n", dependenciesJoined.constData());
+ }
+ }
+
return 0;
}
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index b98198d1d5..7b132493f8 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -935,9 +935,9 @@ void Moc::parse()
if (it != classList.end()) {
it->classInfoList += def.classInfoList;
- it->enumDeclarations.unite(def.enumDeclarations);
+ it->enumDeclarations.insert(def.enumDeclarations);
it->enumList += def.enumList;
- it->flagAliases.unite(def.flagAliases);
+ it->flagAliases.insert(def.flagAliases);
} else {
knownGadgets.insert(def.classname, def.qualified);
knownGadgets.insert(def.qualified, def.qualified);
@@ -1387,6 +1387,7 @@ void Moc::parsePluginData(ClassDef *def)
error(msg.constData());
return;
}
+ parsedPluginMetadataFiles.append(fi.canonicalFilePath());
metaData = file.readAll();
}
}
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 6785b7f9e8..1d70fa154b 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -224,6 +224,7 @@ public:
QHash<QByteArray, QByteArray> knownQObjectClasses;
QHash<QByteArray, QByteArray> knownGadgets;
QMap<QString, QJsonArray> metaArgs;
+ QVector<QString> parsedPluginMetadataFiles;
void parse();
void generate(FILE *out, FILE *jsonOutput);
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
index 9acbce25ff..7188c81300 100644
--- a/src/tools/rcc/rcc.cpp
+++ b/src/tools/rcc/rcc.cpp
@@ -129,7 +129,7 @@ public:
QLocale::Country m_country;
QFileInfo m_fileInfo;
RCCFileInfo *m_parent;
- QHash<QString, RCCFileInfo*> m_children;
+ QMultiHash<QString, RCCFileInfo *> m_children;
RCCResourceLibrary::CompressionAlgorithm m_compressAlgo;
int m_compressLevel;
int m_compressThreshold;
@@ -737,7 +737,7 @@ bool RCCResourceLibrary::addFile(const QString &alias, const RCCFileInfo &file)
parent->m_children.insert(node, s);
parent = s;
} else {
- parent = parent->m_children[node];
+ parent = *parent->m_children.constFind(node);
}
}
@@ -757,7 +757,7 @@ bool RCCResourceLibrary::addFile(const QString &alias, const RCCFileInfo &file)
break;
}
}
- parent->m_children.insertMulti(filename, s);
+ parent->m_children.insert(filename, s);
return true;
}
@@ -1478,13 +1478,19 @@ bool RCCResourceLibrary::writeInitializer()
writeString(" return 1;\n");
writeString("}\n\n");
- writeByteArray(
- "namespace {\n"
- " struct initializer {\n"
- " initializer() { QT_RCC_MANGLE_NAMESPACE(" + initResources + ")(); }\n"
- " ~initializer() { QT_RCC_MANGLE_NAMESPACE(" + cleanResources + ")(); }\n"
- " } dummy;\n"
- "}\n");
+
+ writeString("namespace {\n"
+ " struct initializer {\n");
+
+ if (m_useNameSpace) {
+ writeByteArray(" initializer() { QT_RCC_MANGLE_NAMESPACE(" + initResources + ")(); }\n"
+ " ~initializer() { QT_RCC_MANGLE_NAMESPACE(" + cleanResources + ")(); }\n");
+ } else {
+ writeByteArray(" initializer() { " + initResources + "(); }\n"
+ " ~initializer() { " + cleanResources + "(); }\n");
+ }
+ writeString(" } dummy;\n"
+ "}\n");
} else if (m_format == Binary) {
int i = 4;
diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp
index 9bb2cfcfea..8a8c5610af 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.cpp
+++ b/src/tools/uic/cpp/cppwriteinitialization.cpp
@@ -824,8 +824,8 @@ void WriteInitialization::acceptWidget(DomWidget *node)
qPrintable(m_option.messagePrefix()),
name.toLatin1().data());
} else {
- m_output << m_indent << varName << language::derefPointer << "raise()"
- << language::eol;
+ m_output << m_indent << varName << language::derefPointer
+ << (language::language() != Language::Python ? "raise()" : "raise_()") << language::eol;
}
}
}