[cmake-developers] cmake automoc breaks kde

Alexander Neundorf neundorf at kde.org
Wed Nov 30 16:07:43 EST 2011


On Wednesday 30 November 2011, Stephen Kelly wrote:
> Alexander Neundorf wrote:
> > On Tuesday 22 November 2011, Stephen Kelly wrote:
> >> On 11/22/2011 10:03 PM, Alexander Neundorf wrote:
> >> >> Now when I try to build the frameworks branch using the cmake next
> >> >> branch, I get:
> >> >> 
> >> >> AUTOMOC: error:
> >> >> /home/stephen/dev/src/kf5/tier1/libkcoreaddons/src/io/kdirwatch.cpp:
> >> >> The file includes the moc file "kdirwatch_p.moc", which seems to be
> >> >> the moc file from a different source file. This is not supported.
> >> >> Include "kdirwatch.moc" to run moc on this source file.
> >> > 
> >> > I added special handling now for the case that basename_p.moc is
> >> > included with Qt4.
> >> 
> >> Your new commits work with the parts of the frameworks branch affected
> >> by this, yes.
> >> 
> >> However, there are still many places where the foo.moc file is expected
> >> to be the result of moc'ing the header, which causes errors like this:
> >> 
> >> 
> >> In file included from
> 
> >> /home/stephen/dev/build/qt48/kf5/tier1/libkdbus/kdbus_automoc.cpp:2:0:
> /home/stephen/dev/build/qt48/kf5/tier1/libkdbus/moc_kdbusinterprocesslock.c
> 
> >> pp: In static member function 'static void
> >> KDBusInterProcessLock::qt_static_metacall(QObject*, QMetaObject::Call,
> 
> >> int, void**)':
> /home/stephen/dev/build/qt48/kf5/tier1/libkdbus/moc_kdbusinterprocesslock.c
> 
> >> pp:55:22: error: invalid use of incomplete type 'struct
> >> KDBusInterProcessLockPrivate'
> 
> /home/stephen/dev/build/qt48/kf5/tier1/libkdbus/../../../../../src/kf5/tie
> 
> >> r1/libkdbus/kdbusinterprocesslock.h:30:7: error: forward declaration of
> >> 'struct KDBusInterProcessLockPrivate'
> >> 
> >> Fixed by changing the include from foo.moc to moc_foo.cpp of course.
> >> 
> >> This is due to the use of Q_PRIVATE_SLOT. I've just added a testcase to
> >> the branch.
> > 
> > Please give the current AutomocIncludedDotMocFileHandling branch a try,
> > it checks now also for this.
> 
> Building solid still fails with the AutomocIncludedDotMocFileHandling
> branch. One of the reasons for failure is including a file with a different
> basename .moc. Fixed in solid with
> 
> -#include "devicenotifier.moc"
> +#include "moc_devicenotifier.cpp"
> 
> in devicemanager.cpp.
> 
> The other failure is building files in subdirectories from a CMakeLists two
> levels up (all the files in the subdirectories are compiled into a single
> library) and including their moc files, which fails.
> 
> /home/stephen/dev/src/kf5/tier1/solid/solid/backends/fakehw/fakedevice.cpp:
> 338:42: fatal error: backends/fakehw/fakedevice.moc: No such file or
> directory
> 
> 
> Solid builds standalone with Qt 4 in the frameworks branch. You already
> have it in your kdelibs git repo. The easiest thing would be:
> 
> git new-workdir kdelibs kdelibs-frameworks frameworks
> cd kdelibs-frameworks/tier1/solid
> mkdir build && cd build
> cmake .. && make
> 
> For convenience I put the current solid source here:
> 
> http://www.steveire.com/share/solid.tar.gz

Thanks.

diff --git a/tier1/solid/solid/audiointerface.cpp 
b/tier1/solid/solid/audiointerface.cpp
index ddf6cbc..98e42b2 100644
--- a/tier1/solid/solid/audiointerface.cpp
+++ b/tier1/solid/solid/audiointerface.cpp
@@ -67,4 +67,4 @@ Solid::AudioInterface::SoundcardType 
Solid::AudioInterface::soundcardType() cons
     return_SOLID_CALL(Ifaces::AudioInterface *, d->backendObject(), 
InternalSoundcard, soundcardType());
 }
 
-#include "audiointerface.moc"
+#include "moc_audiointerface.cpp"

An alternative way to fix this is to include <QVariant> in the header and not 
include the moc file here at all.

-----------------------------


diff --git a/tier1/solid/solid/backends/fakehw/fakedevice.cpp 
b/tier1/solid/solid/backends/fakehw/fakedevice.cpp
index dce82e4..1e5781a 100644
--- a/tier1/solid/solid/backends/fakehw/fakedevice.cpp
+++ b/tier1/solid/solid/backends/fakehw/fakedevice.cpp
@@ -335,5 +335,5 @@ QObject *FakeDevice::createDeviceInterface(const 
Solid::DeviceInterface::Type &t
     return iface;
 }
 
-#include "backends/fakehw/fakedevice.moc"
+#include "backends/fakehw/moc_fakedevice.cpp"
 #include "backends/fakehw/fakedevice_p.moc"


This one was actually a bug, this one works now with the updated branch.


-----------------------------

diff --git a/tier1/solid/solid/devicemanager.cpp 
b/tier1/solid/solid/devicemanager.cpp
index 06919c3..0fd8c89 100644
--- a/tier1/solid/solid/devicemanager.cpp
+++ b/tier1/solid/solid/devicemanager.cpp
@@ -288,6 +288,6 @@ void Solid::DeviceManagerStorage::ensureManagerCreated()
     }
 }
 
-#include "devicenotifier.moc"
+#include "moc_devicenotifier.cpp"
 #include "moc_devicemanager_p.cpp"

In this case at least the error message is early and to the point:
"AUTOMOC: error: /home/alex/src/CMake/tests/solid/solid/devicemanager.cpp: The 
file includes the moc file "devicenotifier.moc", which seems to be the moc 
file from a different source file. This is not supported. Include 
"devicemanager.moc" to run moc on this source file."

An alternative fix is the following:

diff -rbup solid.orig/solid//solid/CMakeLists.txt solid//solid/CMakeLists.txt
--- solid.orig/solid//solid/CMakeLists.txt      2011-11-23 11:32:15.000000000 
+0100
+++ solid//solid/CMakeLists.txt 2011-11-30 21:48:13.000000000 +0100
@@ -42,6 +42,7 @@ set(solid_LIB_SRCS
    managerbase.cpp
    device.cpp
    devicemanager.cpp
+   devicenotifier.h
    deviceinterface.cpp
    genericinterface.cpp
    processor.cpp


diff -rbup solid.orig/solid//solid/devicemanager.cpp 
solid//solid/devicemanager.cpp
--- solid.orig/solid//solid/devicemanager.cpp   2011-11-30 03:08:04.000000000 
+0100
+++ solid//solid/devicemanager.cpp      2011-11-30 21:49:17.000000000 +0100
@@ -288,6 +288,5 @@ void Solid::DeviceManagerStorage::ensure
     }
 }
 
-#include "devicenotifier.moc"
 #include "moc_devicemanager_p.cpp"
 

> You can decide how much of this should be covered in the backwards
> guarantee automoc feature and how much will require fixing solid instead.

Yes, I'm quite undecided.
The breakages above are caused by forward declarations in the header (which I 
can't detect), and by moc'ing files which are not known to cmake at all 
(devicenotifier.h, and there is no devicenotifier.cpp).

So I think with the current cmQtAutomoc::ParseCpp() I can't handle and can't 
detect and warn for those cases. Which would mean that automoc in 2.8.7 will 
not be able to substitute the standalone automoc4 (as 2.8.6 was).
This is not really good.
But at least now in 2.8.7 automoc behaves more like what the documentation 
said already in 2.8.6, so it could be argued that everything which was working 
before is still working now and everything which does not work anymore was 
working only by accident.
Which seems kind of ok, but this still means that even if we start to require 
cmake 2.8.7 for kdelibs4, we still need the standalone automoc (which I don't 
feel like maintaining).

OTOH, if we add two ParseCpp()s, one with the behaviour from 2.8.6, which can 
be optionally enabled, if Qt4 is used, it will be much harder to generate 
proper warnings in that compatibility mode.

Alex



More information about the cmake-developers mailing list