[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