Build non-QT C++ static library using QT
-
Hi and welcome to devnet,
Are you sure you linked your library to your custom static build of Qt ?
In any case, if you don't want any dependencies, then you have to get the static version of all of them.
-
Thanks @SGaist for your response.
I'll add a minimal example to make this more concrete. I basically created a C++ static library in QtCreator:QT -= gui QT += network TARGET = TestLib TEMPLATE = lib CONFIG += staticlib SOURCES += testlib.cpp HEADERS += testlib.h unix { target.path = /usr/lib INSTALLS += target }
testlib.h:
#ifndef TESTLIB_H #define TESTLIB_H class TestLib { public: TestLib(); }; #endif // TESTLIB_H
testlib.cpp:
#include "testlib.h" #include <QUdpSocket> TestLib::TestLib() { QUdpSocket *socket = new QUdpSocket(); (void)socket; }
Compile output (using the Kit which is qt5.7 statically compiled):
15:29:30: Starting: "/usr/bin/make" g++ -c -pipe -O2 -fPIC -std=gnu++11 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_NETWORK_LIB -DQT_CORE_LIB -I../TestLib -I. -I../qt5/qtbase/include -I../qt5/qtbase/include/QtNetwork -I../qt5/qtbase/include/QtCore -I. -I../qt5/qtbase/mkspecs/linux-g++ -o testlib.o ../TestLib/testlib.cpp rm -f libTestLib.a ar cqs libTestLib.a testlib.o 15:29:31: The process "/usr/bin/make" exited normally.
And the result library:
nm libTestLib.a | c++filt testlib.o: 0000000000000000 V DW.ref.__gxx_personality_v0 U _GLOBAL_OFFSET_TABLE_ U __gxx_personality_v0 U qt_version_tag U _Unwind_Resume U operator delete(void*) U QUdpSocket::QUdpSocket(QObject*) 0000000000000000 T TestLib::TestLib() 0000000000000000 T TestLib::TestLib() U operator new(unsigned long)
You can see that the QT symbols are undefined, and not pulled in. Is this how it's supposed to be? How should this static library be deployed without the developer having to worry about QT dependencies?
-
@julianoes said in Build non-QT C++ static library using QT:
- Try to make a separate non-QT application which links to mylib.a, this fails because there are numerous undefined references to QT symbols.
because the static lib only contains your symbols. The target binary has to be linked against It's dependencies.
This creates a huge (over 200MB) library and includes a lot more than needed. Once you link an application to it, the filesize reduces to around 50MB,
but this what you actually want. It contains all the infos needed. And as you already noticed the size reduces dramatically when linked into the final binary.
however, the linking to it still requires a lot of dependencies on Linux such as:
pthread z icuio icuuc icutu icule iculx icudata icutest icui18n dl glib-2.0 pcre16 proxy
again just because Qt itself is compiled statically it doesn't mean it has no dependencies. You would need to link against those also statically and "combine" them again.
Actually this is all normal "behavior" of static libs. If you want an all-in-solution you would have to go with one big static lib. But i doubt that it will be possible and able to use it successfully with all Qt dependencies included statically.
There are some Qt macros available to disable unneeded features though to reduce the file size though.Also note that some Qt stuff requires an event loop running!
-
Thanks @raven-worx.
@raven-worx said in Build non-QT C++ static library using QT:
again just because Qt itself is compiled statically it doesn't mean it has no dependencies.
Right I understand that but I really don't want that users of my library need to worry about all dependencies like pcre16 or proxy that I doubt are needed for the functions that I use.
@raven-worx said in Build non-QT C++ static library using QT:
There are some Qt macros available to disable unneeded features though to reduce the file size though.
Can you give me a pointer to these? What am I looking for?
@raven-worx said in Build non-QT C++ static library using QT:
Also note that some Qt stuff requires an event loop running!
My library starts a QThread and uses
exec
in there which seems to work for the things I'm trying to do. -
Then I suggested before, you'll have to get all dependencies of Qt also statically linked.
But before looking to do that, what exactly do you need for your application ?
You're looking for the Qt Lite project. More information here. Note that you can already build a feature reduced version of Qt but the Qt Lite project offers an easier alternative to do it.
-
@SGaist said in Build non-QT C++ static library using QT:
Then I suggested before, you'll have to get all dependencies of Qt also statically linked.
I don't understand how I would do that. There is no linking happing if you look at my minimal example.
@SGaist said in Build non-QT C++ static library using QT:
But before looking to do that, what exactly do you need for your application ?
I only really need: QUdpSocket, QThread, QMutex, QEventLoop (and in the future serial support and QTcpSocket).
Thanks for the link to Qt Lite. I have heard of this before and it's definitely exciting. Does it make these static linking issues easier? Or does it just make things leaner with less baggage?
-
It will limit the number of Qt dependencies.
AFAIK, when you link to a static library, you should only get the symbols you are currently using pulled in your application/library. You shouldn't have to pack everything as you do now.
-
@SGaist said in Build non-QT C++ static library using QT:
AFAIK, when you link to a static library, you should only get the symbols you are currently using pulled in your application/library. You shouldn't have to pack everything as you do now.
I think they get pulled in an application but it seems not into a library. There is no linking taking place as far as I can tell. It's just an
ar
call that merges the objects but without core and network.
Presumably, the linking itself happens later when you use the library for an application.If anyone knows an easy way like a script or tool to determine which .o files that I need from Qt5Core.a to resolve all dependencies, that would be great.
-
Then there might be something I'm missing about your current setup.
In any case, take a look at this excellent blog article about that subject. That should give you the clues needed to solve your situation.