3

I'm working in a big project with Qt/MinGW/Windows. Recently I changed the places of some of my source files and recompile them, and after some corrections, I began to receive messages such as

(.idata$5+0x0):-1: error: multiple definition of `_imp___ZN9QwtThermo16staticMetaObjectE'

This happens regarding two classes: QwtThermo and QwtPlotPicker in a code where previously there was no such error (remember: I just changed the places of the files in the base folder to some subfolders; no code changed (as far as I remember) and notice that many other Qwt classes are also included and normally used without any compile error; this are the only two ones that are giving me problems).

Now "multiple definition of" is a common error in C++ and I already know how one would normally solve it (many threads, including in StackOverflow, talk about it): one should only declare things in header files while defining them in the .cpp files.

Unfortunately this doesn't seem to be a viable solution this time. Here is what is going on:

  • I did a research regarding where this header was being included, and I found no problems. As I sad, it used to compile nicely before.
  • The problem would only occur with QwtPlotPicker if I create a subclass of it (doesn't matter if I use it). If I only declare the name of the subclass in the header and define it in the .cpp, then I'm able to compile, but as soon as I start using it (with a member pointer declared in the header), then the compile error "undefined reference for 'vtable for Picker'" appears. So declaring the class in the header and define it in the .cpp doesn't actually help;
  • With QwtThermo, if I include the file in the header and ONLY declare a pointer to it (no subclass), then the error start appearing already. This is solved if I only declare the QwtThermo class in my project's header and include QwtThermo's own header in the .cpp file; this way I'm able to declare a member pointer to it and also instantiate the pointer with "new" in the .cpp file inside it's parent class, but as soon as I start using it by calling its methods, the "multiple definition of" starts appearing again.

So as you may see, it would seem that this time it's not just a matter of "declare in the header and define it in the .cpp"; something more is going on. :T

So what could be wrong? Sorry not posting any code, but believe me that everything of interesting of it that could be seen was written already; the only change of posting the code would be by copying more then 5000 lines ^^

I'm glad for any help you can give me :)

Thanks,


EDIT: Here is the code from Qt Creator's "Compile Output":

g++ -c -pipe -fno-keep-inline-dllexport -g -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DMGENERALDEFINES_GUI -DMGENERALDEFINES_DEBUG -DMGENERALDEFINES_GENERAL -DQWT_INCLUDED -DDEBUG -DRELEASE -DQT_NO_DEBUG -DQT_NO_DEBUG_OUTPUT -DQT_PRINTSUPPORT_LIB -DQT_MULTIMEDIA_LIB -DQT_WIDGETS_LIB -DQT_SQL_LIB -DQT_NETWORK_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I. -I"MSHARE_REPO" -I"MSHARE_COMMON" -I"C:\Qt\Qwt-6.1.0\include" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtPrintSupport" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtMultimedia" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtWidgets" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtSql" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtNetwork" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtGui" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtCore" -I"build\moc" -I"build\ui" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\mkspecs\win32-g++" -o build\obj\moc_mainwindow.o build\moc\moc_mainwindow.cpp
g++ -Wl,-subsystem,windows -mthreads -o debug\mShare.exe object_script.mShare.Debug  -lglu32 -lopengl32 -lgdi32 -luser32 -lmingw32 -lqtmaind "D:/Minhas obras/Softwares/mShare Project/mShare/SMTPEmail.dll" -lpsapi C:/Qt/Qwt-6.1.0/lib/qwtd.dll "D:/Minhas obras/Softwares/mShare Project/mShare/../../Classes/mLogger/build/debug/mLogger.dll" "D:/Minhas obras/Softwares/mShare Project/mShare/../mShareLib/build/debug/mShareLib.dll" C:/Qt/Qwt-6.1.0/lib/qwt.dll "D:/Minhas obras/Softwares/mShare Project/mShare/../../Classes/mLogger/build/release/mLogger.dll" "D:/Minhas obras/Softwares/mShare Project/mShare/../mShareLib/build/release/mShareLib.dll" -LC:\Qt\Qt5.2.1\5.2.1\mingw48_32\lib -lQt5PrintSupportd -lQt5Multimediad -lQt5Widgetsd -lQt5Sqld -lQt5Networkd -lQt5Guid -lQt5Cored .\build\obj\icone_res.o 
d000171.o:(.idata$5+0x0): multiple definition of `_imp___ZN13QwtPlotPicker16staticMetaObjectE'
d000022.o:(.idata$5+0x0): first defined here
d000171.o:(.idata$6+0x0): multiple definition of `_nm___ZN13QwtPlotPicker16staticMetaObjectE'
d000022.o:(.idata$6+0x0): first defined here
d000172.o:(.idata$5+0x0): multiple definition of `_imp___ZN9QwtThermo16staticMetaObjectE'
d000102.o:(.idata$5+0x0): first defined here
d000172.o:(.idata$6+0x0): multiple definition of `_nm___ZN9QwtThermo16staticMetaObjectE'
Makefile.Debug:246: recipe for target 'debug\mShare.exe' failed
d000102.o:(.idata$6+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
mingw32-make[1]: [debug\mShare.exe] Error 1 (ignored)
jww
  • 97,681
  • 90
  • 411
  • 885
Momergil
  • 2,213
  • 5
  • 29
  • 59
  • Have you tried deleting all object files and recompiling from scratch? – user657267 May 27 '14 at 02:48
  • @user657267 many times :T – Momergil May 27 '14 at 02:56
  • You could have copied files rather than moved, this woul explain the multiple definitions error. As for undefined vtable, you are missing a definition of a member function, or probably not passing the relevant object to the linker. – n. m. could be an AI May 27 '14 at 04:54
  • @n.m. thanks for the comment. Well, that is certainly a possibility which I never checked, although I wouldn't bet on it (even if I had copied and not moved, I wouldn't have included twice in my source code, which I don't have here with me right know so I'll check that later). Btw if that were the problem, wouldn't more classes show the same problem? Remember that I'm using normally many Qwt classes not to mention those of my own and only those 2 are having problems. Regarding the vtable, I'ld bet it's a consequence of the general problem arising; no virtual functions used. – Momergil May 27 '14 at 11:11

3 Answers3

1

I could be wrong as I don't know what your code looks like, but it sounds like it is compiling these classes multiple times? If you don't already add #pragma once to the top of your header files to ensure only one compiled copy of that class. Hope you find a solution soon!

rtbaldwin
  • 88
  • 1
  • 10
  • add #pragma? That's strange, since I never ever had to add any #pragma in one of my codes :P Are you sure you're not talking about the #ifndef/#define thing talked about by user2674995 above? If not, that how exactly would that #pragma with work? (I mean where to put it exactly and what to write after it) – Momergil May 27 '14 at 11:05
  • the #pragma once goes at the top of your header file to ensure it is only compiled once. the #ifndef MY_HEADER_H is another way to ensure this, as it checks to see if the definition is made and will proceed to read the code or not based on whether it is defined. the #ifndef will surround the code of interest as user3674995 pointed out. Hope that helps! – rtbaldwin May 27 '14 at 14:10
  • thanks for the reply, but as mentioned above, it didn't help; my code already have #ifndef and the problem persists. – Momergil May 28 '14 at 03:06
  • strange... could you possibly add some of your code to the question, specifically the headers/cpps in question? that would help most in trying to determine the problem. – rtbaldwin May 28 '14 at 17:18
  • thanks for the reply. As mentioned above, everything that seems relevant for comprehending the problem was written; code is as normal as always :T And as you may notice below, I did managed to find where the problem was - and really it had nothing to do with the source code files arrangement anyway :T I'ld be glad if you could help me with that, btw: just search for "qmake is not reading my .pro correctly"; Thanks! – Momergil May 29 '14 at 11:16
1

A few things could be of interest here. I notice that your error talks about static keyword. Your code possibly declares static variable and initializes it at many places.

Another reason could be that you are not using ifndef or pragma once to ensure that only one instance is being initialized for all classes + headers. You need to put something like this in your headers:

#ifndef MY_HEADER_H
#define MY_HEADER_H

... // all of your code

#endif
  • @user2674995 thanks for the answer. I never used (never had to) #pragma once in my source codes and I don't think the right way of solving this problem is by taking such a "go around" solution (at least it seamed so to me). About the #ifndef, Qt Creator automatically adds them to any class files created, so they are in my code. About static, well I'm not with the code here right now, but as far as I remember I don't use any static things in the classes of interest. – Momergil May 27 '14 at 11:08
0

Well, after some try-and-retry I managed to find WHERE the problem lies - but not how exactly to SOLVE it. The problem exists because in my Qt .pro file I tried to configure some specific configurations for debug compilation and others for release compilation, but for some reason the system is not making distinction between those two configurations. To be more specific, the following code should work:

win32 {
    LIBS += -lpsapi

    debug {
        LIBS += C:/Qt/Qwt-6.1.0/lib/qwtd.dll \
            $${MLOGGER}/build/debug/mLogger.dll \      
            $${MSHARE_LIB}/build/debug/mShareLib.dll  
        DEFINES += DEBUG
    }

    release {
        LIBS += C:/Qt/Qwt-6.1.0/lib/qwt.dll \
            $${MLOGGER}/build/release/mLogger.dll \
            $${MSHARE_LIB}/build/release/mShareLib.dll
        DEFINES += RELEASE \
           QT_NO_DEBUG \
           QT_NO_DEBUG_OUTPUT
    }
} # win32

since in the Qt Assistant files regarding qmake, such is the way to write such configurations with a secondary scope:

win32 {
    debug {
        CONFIG += console
    }
}

I noticed that, after commenting the "release" part, the problem vanished and I was capable of compiling without errors; if the comment was erased, the problem returns. At the same time, while uncommented, I was able to notice that the release defines were defined despite the fact that I was in a debug compilation 'state'. And finally this was a code that didn't exist prior to my changes.

The only question that arrives is: why isn't qmake being capable of interpreting the .pro file correctly? But I'll put that in another question.

Thanks for the help,

jww
  • 97,681
  • 90
  • 411
  • 885
Momergil
  • 2,213
  • 5
  • 29
  • 59