From cf3d4cf3c3755faa5474267bf5097e87b9f8152b Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Tue, 10 Dec 2019 15:01:11 +0100 Subject: Teach moc to output a Make-style depfile If moc is invoked with the --output-dep-file option, it will generate a "moc_.d" dep file which contains dependency entries that can be consumed by a Makefile / Ninja build system. This is useful for build tools (like CMake) to know when moc should be re-ran. In the future, it might also be useful for ccache (teach ccache not to re-run moc when not necessary). The dependency list contains: the original source file, the passed --include files (like moc_predefs.h), the include files that were discovered while preprocessing the source file, and the plugin metadata json files listed in Q_PLUGIN_METADATA macros. The file paths are encoded using QFile::encodeName, so using the local 8-bit encoding. The paths are also escaped (so ' ' replaced by '\ ', '$' by '$$', etc) according to the Make-style rules as described in clang's dep file generator https://github.com/llvm/llvm-project/blob/release/9.x/clang/lib/Frontend/DependencyFile.cpp#L233 For reference, the equivalent Ninja depfile parser source code can be found at https://github.com/ninja-build/ninja/blob/v1.9.0/src/depfile_parser.in.cc#L37 Additional options that can be passed: --dep-file-path - to change the location where the dep file should be generated. --dep-file-rule-name - to change the rule name (first line) of the dep file (useful when no -o option is specified, so output goes to stdout). Encoding story. Note that moc doesn't handle non-local-8-bit characters properly when processing include directives at the preprocessor step. Specifically the content of the main input file is read as a raw byte array (which can be UTF-8 encoded) and then each include directive is resolved via Preprocessor::resolveInclude(), which calls QString::fromLocal8Bit(). Because moc uses the QtBootstrap library, only a limited set of codecs are available: various UTF 8 / 16 / 32 codecs and QLatin1Codec (ISO-8859-15). This means that on Windows, if the source input file is UTF-8 encoded, and contains include names with UTF-8 characters (like an emoji or any character >= 127 that is not in the QLatin1 codec), moc will fail to resolve and process that include, and thus no dep file entry will be created either. On macOS / QNX / WASM the main locale is UTF-8, so file content and paths will be processed correctly (hardcoded via QT_LOCALE_IS_UTF8 in src/corelib/codecs/qtextcodec_p.h). On Linux it will depend on the current locale / encoding set, and if that encoding is one of the ones supported above. UTF-8 should work fine. [ChangeLog][QtCore][moc] moc can now output a ".d" dep file that can be consumed by other build systems. Task-number: QTBUG-74521 Task-number: QTBUG-76598 Change-Id: I5585631ff1bbbae4e2875cade9cb6c20ed018c0a Reviewed-by: Leander Beernaert Reviewed-by: Joerg Bornemann Reviewed-by: Qt CI Bot --- src/tools/moc/moc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/tools/moc/moc.h') diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 687ea2552f..5d1ae0ad6d 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -223,6 +223,7 @@ public: QHash knownQObjectClasses; QHash knownGadgets; QMap metaArgs; + QVector parsedPluginMetadataFiles; void parse(); void generate(FILE *out, FILE *jsonOutput); -- cgit v1.2.3