PDA

View Full Version : Link errors when linking chained libraries on windows



darkadept
22nd May 2008, 22:00
This isn't a question but a declaration of my own stupidity. If I can save you some hours of banging your head against the wall then I hope this helps.

I'm using Qt 4.4.0 on Windows with MSVC 2008 Express, although I'm sure this could happen to anyone when compiling on windows.

The problem happens when you have one library linking against another library. I use the following code to export classes on windows:



#if defined(Q_OS_WIN32)
# ifdef MYLIB
# define MYEXPORT Q_DECL_EXPORT
# else
# define MYEXPORT Q_DECL_IMPORT
# endif
#else
# define MYEXPORT
#endif

class MYEXPORT myclass : public QObject {
//...
}


If I try to be sneaky and use the same MYEXPORT macro in both libraries and then try to link them together i get a mess of errors like this:



cl -c -nologo -Zm200 -Zc:wchar_t- -O2 -MD -GR -EHsc -W3 -w34100 -w34189 -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DAXISLIB -DQT_DLL -DQT_NO_DEBUG -DQT_SQL_LIB -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"c:\qt\msvc\4.4.0\include\QtUiTools" -I"c:\qt\msvc\4.4.0\include\QtCore" -I"c:\qt\msvc\4.4.0\include\QtCore" -I"c:\qt\msvc\4.4.0\include\QtGui" -I"c:\qt\msvc\4.4.0\include\QtGui" -I"c:\qt\msvc\4.4.0\include\QtXml" -I"c:\qt\msvc\4.4.0\include\QtXml" -I"c:\qt\msvc\4.4.0\include\QtSql" -I"c:\qt\msvc\4.4.0\include\QtSql" -I"c:\qt\msvc\4.4.0\include" -I"..\libaxis" -I"c:\qt\msvc\4.4.0\include\ActiveQt" -I".tmp" -I"." -I"c:\qt\msvc\4.4.0\mkspecs\default" -Fo.tmp\ @C:\DOCUME~1\root\LOCALS~1\Temp\nm1648.tmpclientmo dule.cpp
link /LIBPATH:"c:\qt\msvc\4.4.0\lib" /NOLOGO /INCREMENTAL:NO /DLL /MANIFEST /MANIFESTFILE:".tmp\mylib.intermediate.manifest" /OUT:..\bin\mylib.dll @C:\DOCUME~1\root\LOCALS~1\Temp\nm1649.tmp
Creating library ..\bin\mylib.lib and object ..\bin\mylib.exp
clientmodule.obj : error LNK2019: unresolved external symbol "public: static struct QMetaObject const MyObject::staticMetaObject" (?staticMetaObject@MyObject@@2UQMetaObject@@B) referenced in function "public: static class QString __cdecl MyObject::tr(char const *,char const *)" (?tr@MyObject@@SA?AVQString@@PBD0@Z)
clientmodule.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall MyObject::metaObject(void)const " (?metaObject@MyObject@@UBEPBUQMetaObject@@XZ)
clientmodule.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall MyObject::qt_metacast(char const *)" (?qt_metacast@MyObject@@UAEPAXPBD@Z)
clientmodule.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall MyObject::qt_metacall(enumQMetaObject::Call,int,vo id * *)" (?qt_metacall@MyObject@@UAEHW4Call@QMetaObject@@HP APAX@Z)
..\bin\mylib.dll : fatal error LNK1120: 4 unresolved externals
NMAKE : fatal error U1077: 'C:\vs9\VC\BIN\link.EXE' : return code '0x460'
Stop.
NMAKE : fatal error U1077: 'C:\vs9\VC\BIN\nmake.exe' : return code '0x2'
Stop.
NMAKE : fatal error U1077: 'cd' : return code '0x2'
Stop.


The reason is that when i compile my second library it includes the headers from the first library but the macro wants to export instead of import the classes. This seems to only happen with QObject classes but i could be wrong.

So in the second library write a new macro with a DIFFERENT name. I sure hope this helps you.

ChristianEhrlicher
23rd May 2008, 06:47
You're probably using MYLIB define for both libs. That's wrong. Use a more specific define to distinguish between the two libs.

btw: no need to put a #ifdef Q_OS_WIN32 around - this works fine for Linux and others too

darkadept
23rd May 2008, 15:13
Yeah that's exactly what I was doing. Since I didn't find the info anywhere else on the web I figured I'd share it here. :D

It seems like 90% of the bugs I run into are obvious forehead slappers.

arunredi
25th May 2008, 11:12
Hello,

I didn't understand the solution very well here but I'm having the same issue that was discussed in this thread.

My app is developed using QT 4.3.1 commerical/ VS 2005. Everything works great when build from VS 2005. Now I want to deploy/ distribute the app to other systems. So I did read the deploy document on trolltech and followed these steps:

opened the QT command prompt...
cmd> nmake clean (no errors)
cmd> qmake -config release (no errors)
cmd> nmake ---- lots of LNK2019 errors

I'm copying partial error output here:

snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: bool __thiscall QDomDocument::setContent(class QIODevice *,class QString *
,int *,int *)" (__imp_?setContent@QDomDocument@@QAE_NPAVQIODevice @@PAVQString@@P
AH2@Z) referenced in function "private: void __thiscall snipit::checkOptions(voi
d)" (?checkOptions@snipit@@AAEXXZ)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: __thiscall QDomNode::~QDomNode(void)" (__imp_??1QDomNode@@QAE@XZ) referenc
ed in function "private: void __thiscall snipit::checkOptions(void)" (?checkOpti
ons@snipit@@AAEXXZ)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: __thiscall QDomDocument::QDomDocument(class QString const &)" (__imp_??0QD
omDocument@@QAE@ABVQString@@@Z) referenced in function "private: void __thiscall
snipit::checkOptions(void)" (?checkOptions@snipit@@AAEXXZ)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: class QDomNode __thiscall QDomNode::appendChild(class QDomNode const &)" (
__imp_?appendChild@QDomNode@@QAE?AV1@ABV1@@Z) referenced in function "private: v
oid __thiscall snipit::checkOptions(void)" (?checkOptions@snipit@@AAEXXZ)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: class QDomElement __thiscall QDomDocument::createElement(class QString con
st &)" (__imp_?createElement@QDomDocument@@QAE?AVQDomElem ent@@ABVQString@@@Z) re
ferenced in function "private: void __thiscall snipit::checkOptions(void)" (?che
ckOptions@snipit@@AAEXXZ)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: class QString __thiscall QHttpResponseHeader::reasonPhrase(void)const " (_
_imp_?reasonPhrase@QHttpResponseHeader@@QBE?AVQStr ing@@XZ) referenced in functio
n "private: void __thiscall snipit::readResponseHeaderFilePosted(class QHttpResp
onseHeader const &)" (?readResponseHeaderFilePosted@snipit@@AAEXABVQHtt pResponse
Header@@@Z)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: int __thiscall QHttpResponseHeader::statusCode(void)const " (__imp_?status
Code@QHttpResponseHeader@@QBEHXZ) referenced in function "private: void __thisca
ll snipit::readResponseHeaderFilePosted(class QHttpResponseHeader const &)" (?re
adResponseHeaderFilePosted@snipit@@AAEXABVQHttpRes ponseHeader@@@Z)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: class QDomElement __thiscall QDomNode::toElement(void)const " (__imp_?toEl
ement@QDomNode@@QBE?AVQDomElement@@XZ) referenced in function "private: void __t
hiscall snipit::readyReadFile(class QHttpResponseHeader const &)" (?readyReadFil
e@snipit@@AAEXABVQHttpResponseHeader@@@Z)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: class QDomNode __thiscall QDomNodeList::item(int)const " (__imp_?item@QDom
NodeList@@QBE?AVQDomNode@@H@Z) referenced in function "private: void __thiscall
snipit::readyReadFile(class QHttpResponseHeader const &)" (?readyReadFile@snipit
@@AAEXABVQHttpResponseHeader@@@Z)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: class QDomNodeList & __thiscall QDomNodeList::operator=(class QDomNodeList
const &)" (__imp_??4QDomNodeList@@QAEAAV0@ABV0@@Z) referenced in function "priv
ate: void __thiscall snipit::readyReadFile(class QHttpResponseHeader const &)" (
?readyReadFile@snipit@@AAEXABVQHttpResponseHeader@ @@Z)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: __thiscall QDomNodeList::~QDomNodeList(void)" (__imp_??1QDomNodeList@@QAE@
XZ) referenced in function "private: void __thiscall snipit::readyReadFile(class
QHttpResponseHeader const &)" (?readyReadFile@snipit@@AAEXABVQHttpResponseHeade
r@@@Z)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: unsigned int __thiscall QDomNodeList::length(void)const " (__imp_?length@Q
DomNodeList@@QBEIXZ) referenced in function "private: void __thiscall snipit::re
adyReadFile(class QHttpResponseHeader const &)" (?readyReadFile@snipit@@AAEXABVQ
HttpResponseHeader@@@Z)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: class QDomNodeList __thiscall QDomElement::elementsByTagName(class QString
const &)const " (__imp_?elementsByTagName@QDomElement@@QBE?AVQDomN odeList@@ABVQ
String@@@Z) referenced in function "private: void __thiscall snipit::readyReadFi
le(class QHttpResponseHeader const &)" (?readyReadFile@snipit@@AAEXABVQHttpRespo
nseHeader@@@Z)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: __thiscall QDomNode::QDomNode(void)" (__imp_??0QDomNode@@QAE@XZ) reference
d in function "private: void __thiscall snipit::readyReadFile(class QHttpRespons
eHeader const &)" (?readyReadFile@snipit@@AAEXABVQHttpResponseHeader @@@Z)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: __thiscall QDomNodeList::QDomNodeList(void)" (__imp_??0QDomNodeList@@QAE@X
Z) referenced in function "private: void __thiscall snipit::readyReadFile(class
QHttpResponseHeader const &)" (?readyReadFile@snipit@@AAEXABVQHttpResponseHeader
@@@Z)
snipit.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) pu
blic: class QByteArray __thiscall QHttp::readAll(void)" (__imp_?readAll@QHttp@@Q
AE?AVQByteArray@@XZ) referenced in function "private: void __thiscall snipit::re
adyReadFile(class QHttpResponseHeader const &)" (?readyReadFile@snipit@@AAEXABVQ
HttpResponseHeader@@@Z)
release\snipit.exe : fatal error LNK1120: 40 unresolved externals
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 8\VC\BIN\l
ink.EXE"' : return code '0x460'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 8\VC\BIN\n
make.exe"' : return code '0x2'
Stop.

what am I doing wrong here or how can I resolve the issue I'm having?

thanks in advance.

darkadept
25th May 2008, 14:38
It looks like a different problem then the one I posted about. It looks like you forgot to include the XML and Network modules in your .pro file.

QT += xml \
network

You can tell this because your linker is missing the QDomDocument::setContent() and QHttpResponseHeader::reasonPhrase() methods amoong others.

arunredi
26th May 2008, 14:52
you were right. All those errors got resolved after adding the line into my .pro file. thank you.