Discussion:
[Development] moc 4.8.6 & macros
Samuel Gaist
2014-09-11 16:28:58 UTC
Permalink
Hi,

I've stumbled on https://bugreports.qt-project.org/browse/QTBUG-41190 which states that QtSerialPort cannot be built with Qt 4.8.6.

From a quick look and build, it's the use of the QT_DEPRECATED_SINCE macro around the signals that makes moc miss them and thus the compilation fails.

Is there something that can be done outside of moc to workaround the problem ? Or does moc need to be improved ?

Thanks

Samuel
Thiago Macieira
2014-09-11 18:50:35 UTC
Permalink
Post by Samuel Gaist
Hi,
I've stumbled on https://bugreports.qt-project.org/browse/QTBUG-41190 which
states that QtSerialPort cannot be built with Qt 4.8.6.
Samuel Gaist
2014-09-11 19:44:15 UTC
Permalink
Post by Samuel Gaist
Hi,
I've stumbled on https://bugreports.qt-project.org/browse/QTBUG-41190 which
states that QtSerialPort cannot be built with Qt 4.8.6.
Post by Samuel Gaist
From a quick look and build, it's the use of the QT_DEPRECATED_SINCE macro
around the signals that makes moc miss them and thus the compilation
fails.
Is there something that can be done outside of moc to workaround the problem
? Or does moc need to be improved ?
NEVER #ifndef signals and slots, unless it's a simple #ifdef/#ifndef and the
#define is present in the source file being processed.
The thing is, it's not even a #ifdef, it's only a #if

What would be the correct procedure to handle QT_DEPRECATED_SINCE ? Removing it from around the signal declaration would make the code a bit inconsistent.

By the way, how is it handled in Qt 5 since building goes without any problem even with the macros around the signal ?
Thiago Macieira
2014-09-11 19:49:48 UTC
Permalink
Post by Samuel Gaist
What would be the correct procedure to handle QT_DEPRECATED_SINCE ? Removing
it from around the signal declaration would make the code a bit
inconsistent.
By the way, how is it handled in Qt 5 since building goes without any
problem even with the macros around the signal ?
moc is smarter in Qt 5: it expands macros.

But the recommendation stands: do not #if (of any kind) anything that isn't
#defined in the same source, in a header next to the one being compiled, or
passed as -D in the command-line.

That means: don't hide signals and slots with #if, even for deprecation.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Samuel Gaist
2014-09-11 20:03:03 UTC
Permalink
Post by Thiago Macieira
Post by Samuel Gaist
What would be the correct procedure to handle QT_DEPRECATED_SINCE ? Removing
it from around the signal declaration would make the code a bit
inconsistent.
By the way, how is it handled in Qt 5 since building goes without any
problem even with the macros around the signal ?
moc is smarter in Qt 5: it expands macros.
But the recommendation stands: do not #if (of any kind) anything that isn't
#defined in the same source, in a header next to the one being compiled, or
passed as -D in the command-line.
That means: don't hide signals and slots with #if, even for deprecation.
I thought I've read somewhere that moc got better at this job :-)

It seems that the new moc doesn't use much of the Qt 5 only classes, would it be useful to backport it to Qt 4 to avoid having to "break" the code style for modules supporting both series ?
Thiago Macieira
2014-09-11 22:49:50 UTC
Permalink
Post by Samuel Gaist
I thought I've read somewhere that moc got better at this job :-)
It seems that the new moc doesn't use much of the Qt 5 only classes, would
it be useful to backport it to Qt 4 to avoid having to "break" the code
style for modules supporting both series ?
Definitely not. Too intrusive a change. We did find breakage long after the
change went in so we know for a fact that there's Qt 4 code that will start to
silently fail.

No, fix qtserialport and anywhere else that a signal or a slot got #ifndef'ed
out.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Olivier Goffart
2014-09-12 09:14:59 UTC
Permalink
Post by Samuel Gaist
Post by Thiago Macieira
Post by Samuel Gaist
What would be the correct procedure to handle QT_DEPRECATED_SINCE ?
Removing it from around the signal declaration would make the code a bit
inconsistent.
By the way, how is it handled in Qt 5 since building goes without any
problem even with the macros around the signal ?
moc is smarter in Qt 5: it expands macros.
But the recommendation stands: do not #if (of any kind) anything that isn't
#defined in the same source, in a header next to the one being compiled, or
passed as -D in the command-line.
That means: don't hide signals and slots with #if, even for deprecation.
I thought I've read somewhere that moc got better at this job :-)
I would not be as strict as Thiago.
In Qt5 it's fine to use the preprocessor as long as moc can see the defines
(that is, if they don't rely on compiler built-in or need special include
paths.)
QT_DEPRECATED_SINCE should be fine.

It is strange it does not work with Qt4. Are you sure that all the include
paths are passed to moc?
Otherwise, you will have to work around it somehow.
try #if not QT_DEPRECATED_SINCE() #else
Or some other trick with Q_MOC_RUN


You can also use the QT_MOC_COMPAT macro in front of a declaration so QObject
will throw a runtime warning when connecting to this signal. (in debug mode)
Post by Samuel Gaist
It seems that the new moc doesn't use much of the Qt 5 only classes, would
it be useful to backport it to Qt 4 to avoid having to "break" the code
style for modules supporting both series ?
This is out of question.
This is a behaviour change as Qt4 code relied on moc not expending the macro
in some cases.

(At some point it will be time to switch fully to Qt5 and drop Qt4 support)
--
Olivier

Woboq - Qt services and support - http://woboq.com - http://code.woboq.org
Samuel Gaist
2014-09-16 21:00:06 UTC
Permalink
Post by Olivier Goffart
Post by Samuel Gaist
Post by Thiago Macieira
Post by Samuel Gaist
What would be the correct procedure to handle QT_DEPRECATED_SINCE ?
Removing it from around the signal declaration would make the code a bit
inconsistent.
By the way, how is it handled in Qt 5 since building goes without any
problem even with the macros around the signal ?
moc is smarter in Qt 5: it expands macros.
But the recommendation stands: do not #if (of any kind) anything that isn't
#defined in the same source, in a header next to the one being compiled, or
passed as -D in the command-line.
That means: don't hide signals and slots with #if, even for deprecation.
I thought I've read somewhere that moc got better at this job :-)
I would not be as strict as Thiago.
In Qt5 it's fine to use the preprocessor as long as moc can see the defines
(that is, if they don't rely on compiler built-in or need special include
paths.)
QT_DEPRECATED_SINCE should be fine.
It is strange it does not work with Qt4. Are you sure that all the include
paths are passed to moc?
Good question, I'll have to check.
If that where not the case, what should I write to give additional include paths to moc ?
Post by Olivier Goffart
Otherwise, you will have to work around it somehow.
try #if not QT_DEPRECATED_SINCE() #else
Or some other trick with Q_MOC_RUN
I forgot about that one, might be a starting point
Post by Olivier Goffart
You can also use the QT_MOC_COMPAT macro in front of a declaration so QObject
will throw a runtime warning when connecting to this signal. (in debug mode)
Good to know
Post by Olivier Goffart
Post by Samuel Gaist
It seems that the new moc doesn't use much of the Qt 5 only classes, would
it be useful to backport it to Qt 4 to avoid having to "break" the code
style for modules supporting both series ?
This is out of question.
This is a behaviour change as Qt4 code relied on moc not expending the macro
in some cases.
(At some point it will be time to switch fully to Qt5 and drop Qt4 support)
I agree, but there are still lots of people locked to Qt 4… There's even posts on the forum asking for Qt 3
Thiago Macieira
2014-09-17 06:52:36 UTC
Permalink
Post by Samuel Gaist
Good question, I'll have to check.
If that where not the case, what should I write to give additional include paths to moc ?
Replace QT_DEPRECATED_SINCE with the actual contents of the macro. Also expand
QT_VERSION_CHECK.

Qt 4 moc does not expand macros.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Olivier Goffart
2014-09-17 15:20:58 UTC
Permalink
Post by Thiago Macieira
Post by Samuel Gaist
Good question, I'll have to check.
If that where not the case, what should I write to give additional include
paths to moc ?
Replace QT_DEPRECATED_SINCE with the actual contents of the macro. Also
expand QT_VERSION_CHECK.
Qt 4 moc does not expand macros.
Qt 4 moc does expand macros in #if directive.

(and QT_DEPRECATED_SINCE is defined to 1 for Qt4 in qtserialportglobal.h)
--
Olivier

Woboq - Qt services and support - http://woboq.com - http://code.woboq.org
Samuel Gaist
2014-09-17 15:42:40 UTC
Permalink
Post by Olivier Goffart
Post by Thiago Macieira
Post by Samuel Gaist
Good question, I'll have to check.
If that where not the case, what should I write to give additional include
paths to moc ?
Replace QT_DEPRECATED_SINCE with the actual contents of the macro. Also
expand QT_VERSION_CHECK.
Qt 4 moc does not expand macros.
Qt 4 moc does expand macros in #if directive.
(and QT_DEPRECATED_SINCE is defined to 1 for Qt4 in qtserialportglobal.h)
Indeed it's defined, but it looks like moc doesn't handle the case when the macro has one or more parameter(s) even if defined in the same file

Samuel
Thiago Macieira
2014-09-17 16:01:21 UTC
Permalink
Post by Samuel Gaist
Post by Olivier Goffart
Post by Thiago Macieira
Post by Samuel Gaist
Good question, I'll have to check.
If that where not the case, what should I write to give additional include
paths to moc ?
Replace QT_DEPRECATED_SINCE with the actual contents of the macro. Also
expand QT_VERSION_CHECK.
Qt 4 moc does not expand macros.
Qt 4 moc does expand macros in #if directive.
(and QT_DEPRECATED_SINCE is defined to 1 for Qt4 in qtserialportglobal.h)
Indeed it's defined, but it looks like moc doesn't handle the case when the
macro has one or more parameter(s) even if defined in the same file
Right, so let me be clearer: moc in Qt 4 does not expand macro calls.

$ cat foo.cpp
#define FOO(x) x
#if FOO(1)
class Foo : public QObject { Q_OBJECT };
#endif

$ moc -qt4.8 foo.cpp > /dev/null
foo.cpp:0: Note: No relevant classes found. No output generated.

$ moc -qt5 foo.cpp > /dev/null
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Loading...