[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