[cmake-developers] cmake automoc breaks kde
Alexander Neundorf
neundorf at kde.org
Mon Oct 31 16:47:31 EDT 2011
On Monday 31 October 2011, David Faure wrote:
> Hi Alex,
>
> The latest changes in cmake-git (probably the merge of
> AutomocFindQ_OBJECTAlwaysInHeader) break the compilation of kde-frameworks.
This is for fixing http://public.kitware.com/Bug/view.php?id=12533
> Before:
>
> Generating kauthactionwatcher.moc
> AUTOMOC: Checking kauthactionwatcher.cpp
> moc [...] -o kauthactionwatcher.moc kauthactionwatcher.h
>
> After:
>
> AUTOMOC: Checking kauthactionwatcher.h
> AUTOMOC: Checking kauthactionwatcher.cpp
> Generating moc_kauthactionwatcher.cpp
> moc [...] moc_kauthactionwatcher.cpp kauthactionwatcher.h
> leading to
> Error: moc_kauthactionwatcher.cpp:75:22: error: invalid use of incomplete
> type 'struct KAuth::ActionWatcher::Private'
>
> Generating kauthactionwatcher.moc
> moc [...] -o kauthactionwatcher.moc kauthactionwatcher.cpp
> kauthactionwatcher.cpp:0: Note: No relevant classes found. No output
> generated.
>
>
> This is a typical (kde) case where the .cpp incudes the .moc, for the
> object defined in the .h.
Shouldn't it include moc_kauthactionwatcher.cpp ?
Is this really a typical case, i.e. is that done in many places ?
I thought the rule is that if there is a include foo.moc, the Q_OBJECT is in
the same cpp file.
That's also what is documented for cmake 2.8.6.
If it did additionally other things, this was more or less accidentially.
> Apparently it now creates two moc files, one for the .cpp file (empty) and
Yes, because kauthactionwatcher.moc is included.
> one for the .h file (but with the wrong name, so not included during
> compilation).
Yes, because it contains a Q_OBJECT macro.
The logic which is currently implemented is:
1. if foo.cpp includes foo.moc, run moc on foo.cpp and generate foo.moc
2. run moc on all header files bar.h which contain "Q_OBJECT" and generate
moc_bar.cpp from them
(which in detail means:
2.1 for every included moc_xyz.cpp (no matter in which file), search for a
corresponsing xyz.h/hxx/hpp file and run moc on it
2.2 for every bar.cpp file, check whether there is a corresponding
bar.h/hpp/hxx file and collect it
2.3 check for a Q_OBJECT macro in all collected header files and all header
files listed explicitely as a source for the target, and run moc on them. If
the resulting moc_xyz.cpp file has not been included in any source file,
include it in <targetname>_automoc.cpp, which is built as part of the target )
Step 2.2 already involves guessing, which I don't like.
Beside that, IMO these are clear rules, which are easy to understand.
With the old behaviour it was actually ambigous:
foo.h:
class Foo
{
Q_OBJECT
};
foo.cpp:
Foo::Foo() {}
#include "foo.moc"
#include "moc_foo.cpp"
This would have generated twice the same moc file, I think. IMO this is really
confusing.
Now it is simple: foo.moc from foo.cpp, moc_foo.cpp from foo.h.
If this is really done in many places in KDE, I'll add some workaround, but I
think the default behaviour should stay as it is now in cmake git.
How does qmake handle such cases ?
Alex
More information about the cmake-developers
mailing list