0

The question says all the thing. I am using Qt Creator, which uses QMake and I want to build a .so shared library file that has all its dependencies statically linked. Like libstdc++, and etc.

But when I use CONFIG += static it also changes the library to a static library and produces a .a static file, which I don't want it. So my question is not a duplicate of this.

I searched here but I was not able to find any suitable thing.

Community
  • 1
  • 1
Matin Lotfaliee
  • 1,745
  • 2
  • 21
  • 43

2 Answers2

0

CONFIG += static is the wrong flag, as stated by the documentation:

The target is a static library (lib only). The proper compiler flags will automatically be added to the project.

If you want to link dependencies statically, and produce a shared library, you need to pass a flag to the linker, so add QMAKE_LFLAGS += -static to your .pro file.

A simple tests results in a 16kb dll without that flag, and a 995kb dll with it. Also, if dependency walker is to be trusted, the larger dll has no external dependencies, while the smaller depend on libgcc and libstdc++ (it is just a trivial std::cout test).

So evidently, you don't really need a static qt or qmake build. Tested with the "stock" 32bit mingw version of Qt.

dtech
  • 47,916
  • 17
  • 112
  • 190
  • When I use CONFIG += static it compiles ok with no errors. But when I use QMAKE_LFLAGS += -static it shows me these errors: error: cannot find -lgnustl_shared error: cannot find -llog error: cannot find -lz error: cannot find -ldl – Matin Lotfaliee Nov 29 '16 at 05:51
  • If you want to link statically to a library, you must have a static version of that library. `-lgnustl_shared` sounds a lot like it is a shared library, usually without the `_shared` suffix the linker will look for an `.a` version of the library, but in your case there is no such thing. The actual library is `-lgnustl_static`. You don't get errors without that flag because without it you are not linking statically at all. – dtech Nov 29 '16 at 13:21
  • I repeat, when I use CONFIG += static it compiles ok with no errors. – Matin Lotfaliee Nov 29 '16 at 14:04
  • Well, use `CONFIG += static` then. On that's right, it has already been established in practice and verified by the documentation that it doesn't do what you want to achieve. – dtech Nov 29 '16 at 14:08
  • @MatinLotfaliee I can't give you any more specific help without more specific information. What build tools are you using, what are your dependencies...? The answer already contains what you normally need to do to get it working, so if it doesn't work for you, then there is some other variable that needs to be taken into account. – dtech Nov 29 '16 at 14:13
  • I can not use it. because it builds a static library. And I think it can find the libraries it needs to do the static building. But why when I use LFLAG += -static it needs them to be found? – Matin Lotfaliee Nov 29 '16 at 14:15
  • I have created a shared library in Qt Creator (without using the Qt libraries), and I have added the Android kit and I am compiling for the Android using NDK. – Matin Lotfaliee Nov 29 '16 at 14:17
  • Try explicitly adding `LIBS += -Lpath/to/libdir -lgnustl_static` to the project. – dtech Nov 29 '16 at 14:21
  • For cmake there is the option to set `APP_STL := gnustl_static` in the makefile but I don't find the exact syntax for qmake PRO config. – dtech Nov 29 '16 at 14:26
  • Lastly, for llog, lz and ldl you will have to set the `LOCAL_LDLIBS` flag, but like for `gnustl_static` I am not sure and can't find a reference on what's the proper (if any) syntax. – dtech Nov 29 '16 at 15:27
  • @MatinLotfaliee - you might consider opening a new question on NDK + qmake + static linking, seems that there are specifics there, maybe even missing options in qmake. – dtech Dec 01 '16 at 16:51
  • Yes I have asked it in here: http://stackoverflow.com/questions/40917341/how-to-create-a-single-native-shared-library-with-no-dependency-for-android-usin – Matin Lotfaliee Dec 01 '16 at 17:58
  • @MatinLotfaliee you did write the actual path to the library instead of `path/to/libdir` in `LIBS += -Lpath/to/libdir -lgnustl_static` right? :) – dtech Dec 01 '16 at 18:29
  • Yes I did. Are you facing a different result? – Matin Lotfaliee Dec 01 '16 at 18:32
  • Not personally, but I read that this worked. Very awkward and frustrating having to deal with such things in the 21 century. Will they ever make it simple and elegant... – dtech Dec 01 '16 at 18:35
-1

You need three things:

  1. You need Qt itself built as a static library:
  2. You need said Qt statically linked to the runtime.
  3. You need to link your library statically to the runtime. This is handled automatically.

For all of it, you need to configure a custom Qt build with -static -static-runtime arguments. Any executable/library you build using this Qt build will be statically linked to the runtime and statically linked to Qt (iff it uses Qt).

It is worth noting that none of the above requires any changes to your project's .pro file. Conversely, there's nothing you can do to your project file to get the same effect, generally speaking. You have to get a properly configured Qt built, and everything will be handled from there.

There's no requirement on your library itself to use Qt, other than there being a project file that manages the build. For example, this would be a rudimentary library that doesn't use Qt nor C++:

TARGET = mylib
TEMPLATE = lib
CONFIG -= qt
SOURCES = mylib.c
HEADERS = mylib.h

As long as you invoke qmake from a Qt configured as above, the shared library won't dynamically link to the language runtime (nor to Qt, but in this case it won't link to Qt at all!).

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • 1 - why? What he wants to do is to make a shared lib that links its own dependencies statically. – dtech Nov 28 '16 at 22:09
  • What about using QMAKE_LFLAG_RELEASE? – Matin Lotfaliee Nov 28 '16 at 22:09
  • @ddriver Because if you don't have a static build of Qt, then the Qt dependency can't be satisfied statically: the object archives to statically link with don't exist. – Kuba hasn't forgotten Monica Nov 28 '16 at 22:11
  • @MatinLotfaliee Nothing about it. It doesn't matter, as I've said in the answer, because if you **don't have a statically built Qt to link with**, no linker options will fix that. You need to have a Qt that provides static object archives (`.a` or static `.lib`). And you get it by configuring it and building it yourself. That's all. Furthermore, Qt already knows what platform-specific options to give the linker to link with the runtime statically. To force it to use these options, you need to configure it with `-static-runtime`. – Kuba hasn't forgotten Monica Nov 28 '16 at 22:13
  • Yeah, but he said "like `libstdc++`" not "like some qt module". To me dependency on Qt is not a given in the question as it is. – dtech Nov 28 '16 at 22:14
  • 1
    Well, I am not using Qt libraries – Matin Lotfaliee Nov 28 '16 at 22:14
  • So as I suspected, he is not using Qt libraries, just the IDE. – dtech Nov 28 '16 at 22:15
  • You don't have to use Qt libraries. You use qmake, and for qmake to do what you need it should come from a Qt build that is properly configured for what you intend to do with it. That's all. It's really simple. It'll be guaranteed to work. Any other solution will be less portable in all likelihood. – Kuba hasn't forgotten Monica Nov 28 '16 at 22:16
  • Then he only needs to build qmake ;) Also, why use qmake if you are not using qt libs... – dtech Nov 28 '16 at 22:16
  • Also, without passing linker flags, even if you have a static qt build, it will only link the qt libs statically, with a tonn of other stuff linked dynamically, including the runtime libs. – dtech Nov 28 '16 at 22:22
  • @KubaOber - I can link libgcc and libstdc++ statically with a Qt version build as dynamic library, with its qmake. So apparently, you are wrong on this one. – dtech Nov 28 '16 at 22:32
  • I'm not wrong, I'm just saying that if you configure qt as `-static-runtime`, it will link the runtime statically everywhere. – Kuba hasn't forgotten Monica Nov 29 '16 at 13:56