woboq / verdigris

Qt without moc: set of macros to use Qt without needing moc
https://woboq.com/blog/verdigris-qt-without-moc.html
GNU Lesser General Public License v3.0
643 stars 60 forks source link

W_GADGET_IMPL on macOS causes problems #38

Closed jcelerier closed 6 years ago

jcelerier commented 6 years ago

Hello,

on macOS (and macOS only - works fine on windows and linux) I'm getting the following problem :

foo.hpp:

struct foo { 
  W_GADGET(foo)
};

foo.cpp:

W_GADGET_IMPL(foo)

bar.hpp

struct bar {
  W_OBJECT(bar)
  public: void doStuff(foo f) W_SIGNAL(doStuff, f);
};

bar.cpp:

W_OBJECT_IMPL(bar)

-> Undefined symbols for architecture x86_64: "foo::staticMetaObject", referenced from: (whatever) bar.cpp

What I suppose is that since the staticMetaObject is constexpr, if it is not being ODR-used in foo.cpp it may not be instantiated at all.

I am supposing this because adding for instance :

auto disregard_me = &foo::staticMetaObject; 

in foo.cpp makes linking work.

I guess another solution would be to put the W_GADGET_IMPL in the header, but I am not sure it is guaranteed to work - is it ?

ogoffart commented 6 years ago

Maybe we should remove the constexpr (can you try removing the W_STATICMETAOBJECT_CONSTEXPR?) We already don't have it constexpr on windows. (for another reason) I hope that it will still be initialized at compile time, even without that constexpr.

Otherwise we could try to add the disregard_me somehow in the macro. (W_OBJECT_IMPL uses it in the metaObject() implementation, i guess that's why it works for W_OBJECT)

jcelerier commented 6 years ago

I tested a bit more and have two observations :

Maybe an interesting solution would be to add metaObject() support to Q/W_GADGET ?

jcelerier commented 6 years ago

verdigris-bug.zip in any case here's a simple repro

ogoffart commented 6 years ago

Should be fixed now with the last commit.