diff options
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/androiddeployqt/main.cpp | 19 | ||||
-rw-r--r-- | src/tools/bootstrap/bootstrap.pro | 6 | ||||
-rw-r--r-- | src/tools/moc/generator.cpp | 6 | ||||
-rw-r--r-- | src/tools/moc/main.cpp | 131 | ||||
-rw-r--r-- | src/tools/moc/moc.cpp | 5 | ||||
-rw-r--r-- | src/tools/moc/moc.h | 1 | ||||
-rw-r--r-- | src/tools/rcc/rcc.cpp | 26 | ||||
-rw-r--r-- | src/tools/uic/cpp/cppwriteinitialization.cpp | 4 |
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; } } } |