PDA

View Full Version : [MSVC 2010] Static linking and unresolved external symbols



Blood9999
1st September 2012, 15:31
Just few minutes ago i have build static libraries for Qt using:


configure -no-webkit -no-scripttools -qt-sql-mysql -fast -opensource -static -platform win32-msvc2010

Everything worked perfectly fine. Later i tried to compile the most simple program as i can:



#include "test.h"
#include <qapplication.h>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
test w;
w.show();
return a.exec();
}

test.h:


#ifndef TEST_H
#define TEST_H

#include <QtGui/QMainWindow>
#include "ui_test.h"

class test : public QMainWindow
{
Q_OBJECT

public:
test(QWidget *parent = 0, Qt::WFlags flags = 0);
~test();

private:
Ui::testClass ui;
};

#endif // TEST_H

And errors i got:


1>------ Build started: Project: test, Configuration: Release Win32 ------
1>Build started 2012-09-01 15:19:31.
1>InitializeBuildStatus:
1> Touching "Release\test.unsuccessfulbuild".
1>CustomBuild:
1> All outputs are up-to-date.
1>ClCompile:
1> All outputs are up-to-date.
1> main.cpp
1>QtCore.lib(qeventdispatcher_win.obj) : error LNK2019: unresolved external symbol _WSAAsyncSelect@16 referenced in function "public: void __thiscall QEventDispatcherWin32Private::doWsaAsyncSelect(int )" (?doWsaAsyncSelect@QEventDispatcherWin32Private@@Q AEXH@Z)
1>QtGui.lib(qaccessible_win.obj) : error LNK2019: unresolved external symbol __imp__PlaySoundW@12 referenced in function "public: static void __cdecl QAccessible::updateAccessibility(class QObject *,int,enum QAccessible::Event)" (?updateAccessibility@QAccessible@@SAXPAVQObject@@ HW4Event@1@@Z)
1>QtGui.lib(qwininputcontext_win.obj) : error LNK2019: unresolved external symbol _ImmGetDefaultIMEWnd@4 referenced in function "struct HWND__ * __cdecl getDefaultIMEWnd(struct HWND__ *)" (?getDefaultIMEWnd@@YAPAUHWND__@@PAU1@@Z)
1>QtGui.lib(qwininputcontext_win.obj) : error LNK2019: unresolved external symbol _ImmGetContext@4 referenced in function "struct HIMC__ * __cdecl getContext(struct HWND__ *)" (?getContext@@YAPAUHIMC__@@PAUHWND__@@@Z)
1>QtGui.lib(qwininputcontext_win.obj) : error LNK2019: unresolved external symbol _ImmReleaseContext@8 referenced in function "void __cdecl releaseContext(struct HWND__ *,struct HIMC__ *)" (?releaseContext@@YAXPAUHWND__@@PAUHIMC__@@@Z)
1>QtGui.lib(qwininputcontext_win.obj) : error LNK2019: unresolved external symbol _ImmNotifyIME@16 referenced in function "void __cdecl notifyIME(struct HIMC__ *,unsigned long,unsigned long,unsigned long)" (?notifyIME@@YAXPAUHIMC__@@KKK@Z)
1>QtGui.lib(qwininputcontext_win.obj) : error LNK2019: unresolved external symbol _ImmGetCompositionStringW@16 referenced in function "long __cdecl getCompositionString(struct HIMC__ *,unsigned long,void *,unsigned long)" (?getCompositionString@@YAJPAUHIMC__@@KPAXK@Z)
1>QtGui.lib(qwininputcontext_win.obj) : error LNK2019: unresolved external symbol _ImmAssociateContext@8 referenced in function "void __cdecl enableIme(class QWidget *,bool)" (?enableIme@@YAXPAVQWidget@@_N@Z)
1>QtGui.lib(qwininputcontext_win.obj) : error LNK2019: unresolved external symbol _ImmSetCandidateWindow@8 referenced in function "public: virtual void __thiscall QWinInputContext::update(void)" (?update@QWinInputContext@@UAEXXZ)
1>QtGui.lib(qwininputcontext_win.obj) : error LNK2019: unresolved external symbol _ImmSetCompositionWindow@8 referenced in function "public: virtual void __thiscall QWinInputContext::update(void)" (?update@QWinInputContext@@UAEXXZ)
1>QtGui.lib(qwininputcontext_win.obj) : error LNK2019: unresolved external symbol _ImmSetCompositionFontW@8 referenced in function "public: virtual void __thiscall QWinInputContext::update(void)" (?update@QWinInputContext@@UAEXXZ)
1>C:\Users\Daniel\Desktop\test\Win32\Release\\test.e xe : fatal error LNK1120: 11 unresolved externals
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:02.30
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

No idea what's going on. I use Qt Visual Studio Addin. QtGui.lib and QtCore.lib are included in linker.

tbscope
1st September 2012, 15:40
How does your .pro file look? Did you forget to configure for a static build?

Blood9999
1st September 2012, 15:49
I don't have any *.pro file. Visual Studio 2010 doesn't create any one. I thought about create one, but i have no idea how to attach it to project.

But my main problem and reason why i need static linking. I have to use QAxWidget in my project, but as far as i know i have to do static build to be able to include ActiveQt to my project. Am i right?

EDIT

Hmm ... i think that i found something. Is it true that i can't build project just using Visual Studio, but i have to use qmake and then nmake?

d_stranz
2nd September 2012, 00:10
I build all of my projects using the Qt Add-in for Visual Studio. You don't need to use qmake or nmake - it is all done within VS using the toolbar / menu commands to build projects.

Use the Qt Add-in to add a new Qt GUI project and select QWidget as the class to use as the base of the GUI. If you've tried to build a new project manually, you have most likely have a project where some required libraries are not being included in the link. Using the Add-in avoids this problem.

You do not need a static Qt build in order to use ActiveQt. It works just fine in the default DLL version. I don't know where you got that crazy idea. Nothing in Qt requires a static build, and in fact static libraries are incompatible with the LGPL license under which Qt is released.

amleto
2nd September 2012, 01:26
...
and in fact static libraries are incompatible with the LGPL license under which Qt is released.

No they're not.

Blood9999
2nd September 2012, 10:42
You do not need a static Qt build in order to use ActiveQt. It works just fine in the default DLL version. I don't know where you got that crazy idea. Nothing in Qt requires a static build, and in fact static libraries are incompatible with the LGPL license under which Qt is released.

Then show me where have you got any kind of ActiveX DLL file :)

amleto
2nd September 2012, 13:40
those PARTICULAR libraries may be static libs, but that does not mean the whole of your Qt build has to be static...

Blood9999
2nd September 2012, 15:29
As far as i know, you can't build your application half static and half shared ;D

amleto
2nd September 2012, 18:05
wow, you still don't get it?

You can link against static and shared libs. You do not need a static Qt build to use the qt activex sttic libs.

capisce?

d_stranz
2nd September 2012, 18:59
No they're not.

LGPL (http://www.gnu.org/licenses/lgpl.html) requires that you be able to substitute the functionality contained in a library at run time by substituting another library with the same functionality (and function signatures), unless you provide the source code for the library in question (see clause 4.d). So either you have to make available the source code to the Qt libraries you have statically linked against, or you have to link dynamically.



You can link against static and shared libs. You do not need a static Qt build to use the qt activex sttic libs.


I think you would likely run into problems trying to compile the application. You have to declare the compile-time constants (QT_DLL, etc.) that tell the compiler how to bring in the class and methods declarations from the Qt header files. If you are using part of Qt that has been compiled statically and part that has been compiled into DLLs, the function signatures for any dependencies between the libraries are probably going to be inconsistent with one definition or the other. This isn't to say it can't be done, but you probably couldn't do it as a project-level declaration - it would have to be done on a header-by-header basis where you have to modify the QT_DLL define as appropriate for each source and header file (and all their dependencies). I think it would be a real mess.


Then show me where have you got any kind of ActiveX DLL file

You know, I think you are right - the vcproj files for QAxContainer.lib and QAxServer.lib build them both as static libraries, not DLLs. (As does the .pro file: CONFIG += qt warn_off staticlib)

The header files for the ActiveQt classes declare them without qualifiers (e.g. class QAxBase), whereas the headers for the core Qt classes it uses are declared with the export macro (e.g. class Q_CORE_EXPORT QObject), which I guess does the right magic to ensure that the declarations are consistent when link time comes.

amleto
2nd September 2012, 19:26
LGPL requires that you be able to substitute the functionality contained in a library at run time by substituting another library with the same functionality (and function signatures), unless you provide the source code for the library in question (see clause 4.d). So either you have to make available the source code to the Qt libraries you have statically linked against, or you have to link dynamically.

Exactly. Static libraries can be used and can comply with LGPL.

As for the issue of qt/ActiveQt, it is all explained in the docs activeqt so there is no static/shared problem here either. Not to mention your edit that says that dll import macros wont get in the way of statically linking against those libs when you need to also link against the rest of your non-static Qt build

mingxin505
31st December 2014, 09:19
imm32.lib
winmm.lib
Ws2_32.lib
add these librarys to Project

d_stranz
31st December 2014, 22:12
I am sure that after almost 2 1/2 years, everyone is excited and happy to finally get this answer.