Details
-
Bug
-
Resolution: Done
-
P2: Important
-
6.2.0 Beta4
-
None
-
-
fc08a07a0 (dev), 3946e7af6 (6.8)
Description
In the CI, we're building the examples with CMake in-source.
Then, we're building the examples with qmake out-of-source, meaning that the qmake build will operate on a source directory, tainted with generated files.
This is not only ugly, but leads to actual problems:
https://codereview.qt-project.org/c/qt/qtbase/+/370280
tries to remove .qmake.conf from qtbase, however it fails when building the dbus/chat example with qmake:
agent:2021/09/13 13:33:07 build.go:391: link /NOLOGO /DYNAMICBASE /NXCOMPAT /OPT:REF /OPT:ICF /INCREMENTAL:NO /SUBSYSTEM:WINDOWS "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST:embed /OUT:release\chat.exe @C:\Users\qt\AppData\Local\Temp\chat.exe.1620.412110.jom agent:2021/09/13 13:33:07 build.go:391: moc_chat_interface.obj : error LNK2005: "private: static void __cdecl OrgExampleChatInterface::qt_static_metacall(class QObject *,enum QMetaObject::Call,int,void * *)" (?qt_static_metacall@OrgExampleChatInterface@@CAXPEAVQObject@@W4Call@QMetaObject@@HPEAPEAX@Z) already defined in chat_interface.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_interface.obj : error LNK2005: "public: void __cdecl OrgExampleChatInterface::action(class QString const &,class QString const &)" (?action@OrgExampleChatInterface@@QEAAXAEBVQString@@0@Z) already defined in chat_interface.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_interface.obj : error LNK2005: "public: void __cdecl OrgExampleChatInterface::message(class QString const &,class QString const &)" (?message@OrgExampleChatInterface@@QEAAXAEBVQString@@0@Z) already defined in chat_interface.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_interface.obj : error LNK2005: "public: virtual struct QMetaObject const * __cdecl OrgExampleChatInterface::metaObject(void)const " (?metaObject@OrgExampleChatInterface@@UEBAPEBUQMetaObject@@XZ) already defined in chat_interface.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_interface.obj : error LNK2005: "public: virtual int __cdecl OrgExampleChatInterface::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@OrgExampleChatInterface@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z) already defined in chat_interface.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_interface.obj : error LNK2005: "public: virtual void * __cdecl OrgExampleChatInterface::qt_metacast(char const *)" (?qt_metacast@OrgExampleChatInterface@@UEAAPEAXPEBD@Z) already defined in chat_interface.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_interface.obj : error LNK2005: "public: static struct QMetaObject const OrgExampleChatInterface::staticMetaObject" (?staticMetaObject@OrgExampleChatInterface@@2UQMetaObject@@B) already defined in chat_interface.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_adaptor.obj : error LNK2005: "private: static void __cdecl ChatAdaptor::qt_static_metacall(class QObject *,enum QMetaObject::Call,int,void * *)" (?qt_static_metacall@ChatAdaptor@@CAXPEAVQObject@@W4Call@QMetaObject@@HPEAPEAX@Z) already defined in chat_adaptor.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_adaptor.obj : error LNK2005: "public: void __cdecl ChatAdaptor::action(class QString const &,class QString const &)" (?action@ChatAdaptor@@QEAAXAEBVQString@@0@Z) already defined in chat_adaptor.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_adaptor.obj : error LNK2005: "public: void __cdecl ChatAdaptor::message(class QString const &,class QString const &)" (?message@ChatAdaptor@@QEAAXAEBVQString@@0@Z) already defined in chat_adaptor.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_adaptor.obj : error LNK2005: "public: virtual struct QMetaObject const * __cdecl ChatAdaptor::metaObject(void)const " (?metaObject@ChatAdaptor@@UEBAPEBUQMetaObject@@XZ) already defined in chat_adaptor.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_adaptor.obj : error LNK2005: "public: virtual int __cdecl ChatAdaptor::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@ChatAdaptor@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z) already defined in chat_adaptor.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_adaptor.obj : error LNK2005: "public: virtual void * __cdecl ChatAdaptor::qt_metacast(char const *)" (?qt_metacast@ChatAdaptor@@UEAAPEAXPEBD@Z) already defined in chat_adaptor.obj agent:2021/09/13 13:33:07 build.go:391: moc_chat_adaptor.obj : error LNK2005: "public: static struct QMetaObject const ChatAdaptor::staticMetaObject" (?staticMetaObject@ChatAdaptor@@2UQMetaObject@@B) already defined in chat_adaptor.obj agent:2021/09/13 13:33:07 build.go:391: release\chat.exe : fatal error LNK1169: one or more multiply defined symbols found agent:2021/09/13 13:33:07 build.go:391: jom: C:\Users\qt\work\qt\qtbase_qmake\examples\dbus\chat\Makefile.Release [release\chat.exe] Error 1169
Several things contribute to this.
In the CMake build, we're calling dbusxml2cpp with the -m option that generates #include "filename.moc" statements in the .cpp files. We don't do that in the qmake build.
In the qmake build of the examples/dbus/chat, when .qmake.conf is not present, we're compiling chat_adapter.cpp from the source directory (which includes chat_adapter.moc) but qmake sees the generated chat_adapter.cpp from the build directory and calls moc on chat_adapter.h, generates moc_chat_adapter.cpp and adds this as source file.
And now we have the metaobject symbols duplicated.
The presence of .qmake.conf affects how source paths are handled inside qmake and how nmake inference rules are generated.
With .qmake.conf present, Makefile.Release has the rules
{C:\Users\qt\work\qt\qtbase\examples\dbus\chat}.cpp{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {C:\Users\qt\work\qt\qtbase\examples\dbus\chat}.cc{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {C:\Users\qt\work\qt\qtbase\examples\dbus\chat}.cxx{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {C:\Users\qt\work\qt\qtbase\examples\dbus\chat}.c{release\}.obj:: $(CC) -c $(CFLAGS) $(INCPATH) -Forelease\ @<< $< << {release}.cpp{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {release}.cc{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {release}.cxx{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {release}.c{release\}.obj:: $(CC) -c $(CFLAGS) $(INCPATH) -Forelease\ @<< $< << {.}.cpp{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {.}.cc{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {.}.cxx{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {.}.c{release\}.obj:: $(CC) -c $(CFLAGS) $(INCPATH) -Forelease\ @<< $< <<
With .qmake.conf removed, the rules look like this:
{release}.cpp{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {release}.cc{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {release}.cxx{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {release}.c{release\}.obj:: $(CC) -c $(CFLAGS) $(INCPATH) -Forelease\ @<< $< << {.}.cpp{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {.}.cc{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {.}.cxx{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {.}.c{release\}.obj:: $(CC) -c $(CFLAGS) $(INCPATH) -Forelease\ @<< $< << {..\..\..\..\qtbase\examples\dbus\chat}.cpp{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {..\..\..\..\qtbase\examples\dbus\chat}.cc{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {..\..\..\..\qtbase\examples\dbus\chat}.cxx{release\}.obj:: $(CXX) -c $(CXXFLAGS) $(INCPATH) -Forelease\ @<< $< << {..\..\..\..\qtbase\examples\dbus\chat}.c{release\}.obj:: $(CC) -c $(CFLAGS) $(INCPATH) -Forelease\ @<< $< <<
This smells a lot like infamous QTBUG-13496, and indeed, specifying CONFIG += no_batch makes the examples build. Magic.
Attachments
Issue Links
- relates to
-
QTBUG-82820 Insource builds and relative paths with Ninja generator
- Open
- mentioned in
-
Page Loading...
For Gerrit Dashboard: QTBUG-96513 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
293823,9 | CMake: Move all CMake Coin builds to be out-of-source | dev | qt/qtbase | Status: MERGED | +2 | 0 |
370280,5 | Remove .qmake.conf from this repository | dev | qt/qtbase | Status: MERGED | +2 | 0 |
407287,4 | Fix building the dbus examples in CI with qmake and MSVC | tqtc/lts-6.2 | qt/tqtc-qtbase | Status: MERGED | +2 | 0 |
595288,6 | coin: Move cross-compilation build directories outside of sources | dev | qt/qtbase | Status: MERGED | +2 | 0 |
596405,2 | coin: Move cross-compilation build directories outside of sources | 6.8 | qt/qtbase | Status: MERGED | +2 | 0 |