Hi, reaching out here for those into moc and, even more, CMake's automoc. Please be caught and read on :)
I would like to propose some new features to CMake's automoc, around enforcing explicit moc includes, and to do this with support of the respective Qt developers, so first hear their comments or, best, get them also involved :) A) Have automoc emit warnings if no explicit moc include has been found and instead one is to be added to mocs_compilation.cpp (silently currently). Perhaps controlled by some target property AUTOMOC_MISSING_INCLUDE_WARNINGS, default OFF --- 8< --- AutoMoc warning: SRC:/foo.h contains a Q_OBJECT macro, but no file includes the moc file "moc_foo.cpp". Added to the target's mocs_compilation.cpp instead. --- 8< --- B) Have an option for no mocs_compilation.cpp at all being used in the build, saving the related build resources and failing hard in case of missing includes. Perhaps by a target property named AUTOMOC_USE_MOCS_COMPILATION, default ON. QUESTIONS Have you Qt developers, even more those pushing for using explicit moc includes where possible, already pondered about this or are planning/working on something related, either on your side or together with CMake developers? What do you think about the proposed approaches? Ideas for other solutions? MOTIVATION Recently in KDE spheres it was (re)discovered that having explicit includes for header moc files yields usually some speed gains in both full & incremental builds, but also a bit more optimized binary code as well more compiler sanity checks. By the cost of one more line per moc'ed header. (See for the complete story this blog post: https://frinring.wordpress.com/2023/06/28/include-also-moc-files-of-headers ) So scripts to add any missing explicit moc includes have been run over lots of the KDE projects and respective commits being done and pushed in the last weeks. But doing so raised some issues, see next. PROBLEMS How to gently enforce the explicit include policy long-term? Those commits with the additions have been a one-time activity. Now how to ensure this new policy of using explicit moc includes is (gently) enforced instead of having things naturally regress again? Because things silently work if one forgets to add such an include, due to automoc doing its fallback inclusion, and one usually has their focus on other things than manually tracking needed moc includes. So it would be nice to get some nudging warning (during active hacking) as well as optionally full errors where useful (like CI builds). Having to remember to do once-in-a-while include mass additions (like it seems to have been done for Qt modules so far, cmp. "QtFoo: includemocs" commits) means for one it takes someone to do that, and often enough, for the other has all the developers miss out all the advantages in the mean-time where things are regressing. Any chance to drop the unused mocs_compilation.cpp completely? When having all explicit moc includes, and thus the mocs_compilation.cpp being empty, the generated build system still spends efforts on it, i.e. compiling & linking it into the targets. While the building costs are minimal for the empty source file, it still shows up in the visual log, but also as builds targets etc., scaled by the number of library/plugin/executable targets. So in builds where one does not use that convenience feature, it would be nice to just completely drop it and nowhere be bothered with it anymore. SOLUTIONS To be warned, or not to be warned The one tool which currently has a complete picture already of which files need moc'ing and which moc files need to be included, that is automoc. And it already gently nudges people with warnings for unneeded includes. --- 8< --- AutoMoc warning --------------- "SRC:/foo.cpp" includes the moc file "foo.moc", but does not contain a Q_OBJECT, Q_GADGET, Q_NAMESPACE or Q_NAMESPACE_EXPORT macro. AutoMoc: /home/koder/Kode/experiments/headermocinclude/foo.cpp:0: Note: No relevant classes found. No output generated. --- 8< --- So it seems balanced if automoc would also warn, if asked to, in a similar fashion for missing explicit moc includes while it collects them into the helper mocs_compilation.cpp source file. That allows during development cycles to note as early as possible the issue and finally act on the warning when there is time. Whether to emit such a warning might be something to control per target, one might have different standards for unit tests than end-user executables. No example made up yet where this might be something to control also per source file property even? To have a mocs_compilation.cpp or not to have one mocs_compilation.cpp instances exists at the granularity level of targets. So there would be a flag property per target, defaulting to some global property, which controls whether cmake should generate build rules for a mocs_compilation.cpp file and respectively automoc add includes to it, or not. Something like CMAKE_AUTOMOC_USE_MOCS_COMPILATION being the global control, with AUTOMOC_USE_MOCS_COMPILATION being the target property name, by the usual patterns. TBD: FILING REQUESTS AT CMAKE ISSUE TRACKER The above is more or less what I was about to file as feature requests at https://gitlab.kitware.com/cmake/cmake/-/issues , based on the mentioned recent experience. So, who is interested to join the boat here, perhaps even take the steering (anyone feels like moc captain)? :) Hoping for your reactions & replies in the next 14 days, otherwise would just proceed with filing the requests as described (modulo new thoughts meanwhile). Cheers Friedrich (here contributor to KDE projects, including Extra CMake Modules (ECM)) -- Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development