Force Moc to moc a file
-
Hi All,
I've got an issue, that moc doesn't moc a file it should moc, under the following circumstances ( This is not exactly my situation, but explains resp. reproduces the problem):
Suppose you have a macro defined in a header file - say foo.h:
// in foo.h #define MAKE_TYPE(name) class name: public QObject { Q_OBJECT public: name() : QObject(0) {} };
and a definition in the same file, like
// in foo.h MAKE_TYPE(MyType)
Then I can create an instance of MyType in any other file without any problems.
// any file MyType t
Do I move the definition in another file - say bar.h
// in bar.h MAKE_TYPE(MyType)
I get a couple of undefined references, when I create the Instance. This is because bar.h is not mocced ( is this the right word ?).
To get it work, I have to put a dummy QObject in bar.h, like:// in bar.h class DummyQObj : public QObject { Q_OBJECT public: DummyQObj() : QObject(0) {} }; MAKE_TYPE(MyType)
The it's mocced and it works.
So my question is, is there any way to tell the moc ( p.e. by means of a define ) to moc the file, although it thinks it shouldn't ?Or is this even a bug ?
Thanks,
Martin -
HI and welcome to devnet
@matze42 said:
I get a couple of undefined references, when I create the Instance. This is because bar.h is not
can you post the errors? Probably could be better to include <QObject> in the macro.
BTW,
Q_OBJECT
is itself a macro; I suggest to define your macro in multi-line mode#define MAKE_TYPE(name) \ #include <QObject> class name: public QObject \ { \ Q_OBJECT \ public: \ name(): QObject(0) {} \ };
-
Hi ,
thanks for your answer.
the error is
error: undefined reference to `vtable for MyType'
This is clear, as the moc file is not generated.
... and the original macro is of course defined in multiline mode, the posted example is only a condensed version.
Additionally including <QObject> doesn't help ( btw: the way you posted it leads to preprocessor errors ).
-
@matze42 said:
Additionally including <QObject> doesn't help ( btw: the way you posted it leads to preprocessor errors ).
Yep, I forgot
\
at the end of the line.
Can you post you .pro file? Are your headers in theHEADERS
variablewhat happens if you run manually moc on this header file?
-
Hi,
I simplified it and it looks like this:
QT += core QT -= gui TARGET = moctest CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += main.cpp \ bar.cpp \ foo.cpp HEADERS += \ foo.h \ bar.h
// main.cpp #include "foo.h" #include "bar.h" #include <QCoreApplication> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); MyType t; MyOtherType ot; return a.exec(); }
// foo.h #ifndef FOO_H #define FOO_H #include <QObject> #define MAKE_TYPE(name) \ class name: public QObject \ { \ Q_OBJECT \ public: name() : QObject(0) {}\ }; MAKE_TYPE(MyType) #endif // FOO_H
// bar.h #ifndef BAR_H #define BAR_H #include "foo.h" #include <QObject> // With this uncommented it works //class DummyQObj : public QObject { Q_OBJECT public: DummyQObj() : QObject(0) {} }; MAKE_TYPE(MyOtherType) #endif // BAR_H
// foo.cpp #include "foo.h"
// bar.cpp #include "bar.h"
Just try it.
( Don't forget do completey cleanup your build directory after changing something, sometimes the object files are kept )Btw: Is it possible in this forum to attach files to posts ? Then I could attach my project directly.
-
This post is deleted! -
HI,
my guess is that qmake force
moc
to be called only for header files whereQ_OBJECT
is used. qmake runs before the preprocessor so in your project it doesn't see theQ_OBJECT
macro inside bar.h -
Hi,
... yes, that was my original question.
Quote from Post:
So my question is, is there any way to tell the moc ( p.e. by means of a define ) to moc the file, although it thinks it shouldn't ?Of course I can put some Q_OBJECT somewhere on the top of the file, p.e.:
#ifdef SOMETHING_WHICH_DEFINITELY_IS_NOT_DEFINED_ELSEWHERE Q_OBJECT #endif
where it's just there, but not evaluated.
But this looks pretty hacky and not nice.I rather would like something like;
#define Q_FORCE_MOC
-
Hi,
Out of curiosity, which version of Qt are we talking about ?
-
Hi,
thanks for asking - i missed that:
Qt 5.4 on Xubuntu 14. -
Ok,
I understand, that
qmake
does not recognize ( and probably even cannot - as it supposed doesn't expand macros) that the concerning file needs to get mocced.
Is there any ways then to add something in the pro file to tellqmake
, that the file needs to get mocced ? p.e.:moc += bar.h
-
qmake is a project manager so indeed it doesn't include macro expansion. moc on the other end (since Qt 5) should expand macro properly.
I just tested your code on OS X and it worked
-
Hi SGaist,
thanx for caring about this issue,
Did yout test it without the Q_OBJECT pseudo code commented or uncommented ?In the meanwhile I started to redesign this part of our software (we are talking about 70-80 type definitions in about 7-8 namespaces resp. files ) - but anyway it would be quite interesting ( at least for me ) to know, if such kind of constructs make sense in the Qt world or not.
-
I've removed/re-added it and it still builds. Q_OBJECT is useful when you implement e.g. signals and slots
-
Strange !
Seems, that my qmake implementation is different from yours.
Reproducable it builds if I have the Q_OBJECT uncommented, and it gives me the linker errors if i have it commented.
So this led me to the assumption, that a (uncommented) Q_OBJECT occurance in a header file is the hint for qmake to mark it to be mocced.
-
Which version of qmake are you using ?
-
Qt 5.4.0 GCC 64bit on Xubuntu 14 64bit.
-
Are you calling qmake through Qt Creator or on the command line ?
-
By QtCreator
-
Did you re-try with Qt 5.5 ?