Qt signal wrapped in an ifdef
Asked Answered
M

2

6

My Qt project links to a library that is linux-only. When the project is run under linux, I wish to have a signal fired on an event using a type defined in that library. A complication that I have, though, is that the project must also build in Windows. Obviously, this signal and the slot catching it wouldn't exist in Windows, and that's fine. I am, however, finding issues with Qt's moc tool failing to recognize the existence of an #ifdef __linux__ around the code that emits the signal. My code looks like this:

[SomeFile.h]

#ifdef __linux__
signals:
  void SomeSignal(SomeTypeDefinedInTheLinuxLibrary);
#endif

[SomeFile.cpp]

#ifdef __linux__
  emit SomeSignal(someObject);
#endif

When I attempt to compile this with g++, I get the error: SomeFile.cpp:(.text+0x858c): undefined reference to SomeFile::SomeSignal(SomeTypeDefinedInTheLinuxLibrary)

Any ideas how to get moc and #ifdefs to play well together?

Mobile answered 22/11, 2010 at 14:38 Comment(0)
L
6

A much better solution is to always provide the signal and just comment out the code that fires it on Windows. That way, the public API is the same on all platforms.

[EDIT] The moc tool is really dumb. It doesn't actually understand the code; instead it just reacts on certain patterns. That's why it ignores the #ifdef.

To solve the issue, wrap the type or use #ifndef __linux__ and define your own dummy type in there so it compiles on Windows. Since the signal won't be emitted on Windows, the slot will never be used so any type that makes the code compile should be fine.

Lamberto answered 22/11, 2010 at 14:43 Comment(4)
I wish I could do that, but the type of the parameter associated with the signal is defined by the linux-specific library. If I were to try to build under windows with the signal not commented out, it would error with an undefined type.Mobile
@Dave: Wrap the type or use #ifndef __linux__ and define your own dummy type in there so it compiles on Windows.Lamberto
Thanks for your input. I ended up wrapping the type and got it to work. It still seems like the code generated by the moc should respect the #ifdefs the signal/slot code is in.Mobile
That would mean the moc would have to copy the #ifdef to the generated classes.Lamberto
T
0

With Qt 5.3 at least using Visual Studio, I am able to pass pre-processor macros to the moc tool. In order to make this work, I had to text edit my Visual Studio project file and manually add command line arguments for each file in order to hand the pre-processor arguments to the moc tool. You can use -D[Pre-Processor], i.e. -DSPECIAL_BUILD or -DSPECIAL_BUILD=1, and the moc compiler is smart enough to see the #if SPECIAL_BUILD checks in your code and not try to moc those parts.

Just search for "moc.exe" and add the appropriate parameters for each configuration.

Thorpe answered 8/1, 2015 at 17:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.