[Development] RFC: CMake's automoc option to warn about missing moc includes; or not have mocs_compilation.cpp

Friedrich W. H. Kossebau kossebau at kde.org
Thu Jul 13 23:16:07 CEST 2023


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))




More information about the Development mailing list