Qt static and dynamic linking same time to third dll
I have created static and dynamic Qt library. Now while building my application dll i want to use QtCore dynamically linked and QtGui statically to my dll (shared library) as i am using only 1 non-gui QDesktopService instance. And i dn't want complete QtGui to be packaged.
Now is it possible to link QtCore dynamically and QtGui statically? if yes then How ?
I have modified .pro file accordingly
@QT -= gui
LIBS += -lQtGui4-static@
To copy to clipboard, switch view to plain text mode
but when i do that i get linking error on windows
bq. error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class QString __cdecl QDesktopServices::storageLocation(enum QDesktopServices::StandardLocation)" (_imp?storageLocation@QDesktopServices@@SA?AVQSt ring@@W4StandardLocation@1@@Z) referenced in function
I don't think this is possible. You either link against static libs or dynamic.
Is there any reason for this ?
Qt can be built with -static switch OR -shared. There is no such switch like -shared-and-static. You are saying:
bq. I have created static and dynamic Qt library.
I understand this, as you compiled Qt with -static swtich, and then compiled Qt again, but this time with -shared. Nothing wrong here, you now have two copies of Qt, one of them is with static libs and the other one - with shared. So you trying to build your projects. It is time to call qmake. Let say you run qmake from the shared copy of Qt. We should expect that it knows nothing about statically built Qt, because its configured for shared libs. Even if you copied shared libs of Qt to where static libs are located you must have overriden conf files.
bq. Let say you run qmake from the shared copy of Qt. We should expect that it knows nothing about statically built Qt, because its configured for shared libs. Even if you copied shared libs of Qt to where static libs are located you must have overriden conf files.
When i run qmake from shared Qt with @QT -= gui@ in pro file. gui related stuff (lib path/name, include path, some micros related to module ) will be dropped by qmake and other (in this case only QtCore) libs and header will be added in generated Makefile.
Just like we link any static library i explicitly mentioned @LIBS += -lQtGui4-static@ in my pro file so qmake generated Makefile will contain additional link information for QtGui4-static library. This is same like we link any third party static library to our code. isn't it ?
This way it should work rite? but is get linking error, - correct me if my understanding is wrong here
I see what you mean. Are static Qt and shared Qt installed to the same dir? And try adding -L/path/to/static/Gui/lib to LIBS variable.
Only possible way to do this would be to link the libraries by hand to the binary. This means, you can by no means use qmake’s Qt library system nor cmake’s FindQt.cmake. Atleast I can’t think of a way to do it.
It is perfectly possible to link static library to binary that uses shared libraries too. The problem here is that no-one has done such support for Qt, since it is most of time useless. For Linux, everyone will want shared libraries. For Windows people will either supply Qt libraries with the application or just compile statically to allow exe to be portable.
First thing you want to consider is that will you benefit from this at all?
If you do, you need to work the compiler scripts by yourself. Whatever you use, cmake/qmake/autotools, they can’t help you until you tell them what you need to do.
ok did lot of dig in and its not possible to link Qt modules statically and dynamically in same executable in Windows.
As it tunrns out qglobal.h file which contains many golbal variables for Qt. In this file they have defined common setting micro for static and shared library of Qt in order to export classes.
define Q_CORE_EXPORT Q_DECL_EXPORT
define Q_GUI_EXPORT Q_DECL_EXPORT
define Q_SQL_EXPORT Q_DECL_EXPORT
define Q_NETWORK_EXPORT Q_DECL_EXPORT
define Q_SVG_EXPORT Q_DECL_EXPORT
define Q_DECLARATIVE_EXPORT Q_DECL_EXPORT
define Q_OPENGL_EXPORT Q_DECL_EXPORT
define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT
define Q_OPENVG_EXPORT Q_DECL_EXPORT
define Q_XML_EXPORT Q_DECL_EXPORT
define Q_XMLPATTERNS_EXPORT Q_DECL_EXPORT
define Q_SCRIPT_EXPORT Q_DECL_EXPORT
define Q_SCRIPTTOOLS_EXPORT Q_DECL_EXPORT
define Q_COMPAT_EXPORT Q_DECL_EXPORT
And this is the reason when static lib is mentioned explicitly (Not from qmake generated makefile) to link, at the time of linking dllImport error pops up.
Even if you try to bypass header file somehow by removing Q_GUI_EXPORT micro and try to make it work. dllImport will move to core feature u are using. That is QString which are linked dynamically (In particularly mentioned above problem, Not in general).
Hence static and dynamic linking can not be done on windows at the same time for Qt library. For other libraries you can do that. Just the case Qt uses qglobal.h across all the modules. which are tightly couples (In the sense of linking static or dynamic) with Qt Core module.
However if there is still any workaround anybody finds out, please let me know :)
I think I'm starting to get why in first place it has not been made to work...
Since QtGui(and all other modules) depends on QtCore, you'd need to compile QtGui shared library with static QtCore library, as you compile your own application too. This means that you'd be duplicating QtCore in two places and already making static libraries quite pointless in terms of effiniency.
Other way around, QtGui as static and QtCore as shared, it could work, but it'd need some manual work still.
Customizing the way Qt uses different modules would be possible too, so shared+static linking seems to be possible, but I fail to see benefit from this in first place.
The point is i have one application which hardly uses some of the functionality from UI, As its more of an library. Now at the time of deplyoment i have to carry huge QtGui library as well. Was planning to optimise that without any code change. Hence wanted to link Qtgui statically for those few function from gui.
I suggest just compiling whole program statically, in that case. For Windows you'll need anyway provide QtCore.
hmm tried that but my binary size is exponentially increased.
It shouldn't increase more than QtCore and QtGui has size, or you are including other modules than those two in too?