conda-forge / qt-feedstock

A conda-smithy repository for qt.
BSD 3-Clause "New" or "Revised" License
12 stars 57 forks source link

Include static libraries to enable static linking of applications #138

Open certik opened 4 years ago

certik commented 4 years ago

Currently only dynamic shared libraries are provided in the qt package at conda-forge. When creating a Qt application, it would be nice to (optionally) link it statically. One currently cannot do that because the qt package only ships dynamic libraries:

/usr/bin/ld: attempted static link of dynamic object `/home/ondrej/miniconda3/envs/qt/lib/libQt5Widgets.so.5.12.5'

It seems that it is possible to build Qt statically also, which would be very helpful.

mingwandroid commented 4 years ago

Static builds of Qt are massive. The static libs would need to be in a separate package as most people wouldn't need them. This would require splitting Qt up to avoid clobbering.

One way:

qt-build-tools
qt-static-libs
qt-runtime-libs
qt (would depend on `qt-runtime-libs` and `qt-build-tools` and be deprecated).

The various build system metadata files emitted for a static build of Qt and those emitted for a dynamic build are likely quite different and it might be a lot of work to be able to make ones that work for both (and work going forward maintaining patches for that). Otherwise qt-build-tools would need to be split into 2 packages, one for static and one for dynamic (this is probably easier).

Apart from these issues, building Qt5 statically is hard (building it dynamically is not easy either but statically is worse). I used to maintain MSYS2's mingw-w64-qt5-static package and have spent countless hours on it (and Qt's build system).

I expect many modules would just not build this way and expect there would be a lot of work involved in making qtwebengine (which is just chromium) build statically. As soon as you drop any important module as I fear would happen the whole exercise becomes much less valuable to our users.

So I definitely support the idea of trying to provide static libs for Qt but it must be done carefully.

Do you see yourself having time to contribute to this?

certik commented 4 years ago

@mingwandroid thanks for the feedback. Right now I am writing a prototype Qt C++ application. If it works out and I end up using Qt, then I would be happy to help.

With the current shared libraries, what is the recommended way to distribute an application to end users? I was hoping to simply distribute a static binary. With shared libraries, one option would be to copy the appropriate Qt shared libs into the tarball with the application, and adjust rpath appropriately.

mingwandroid commented 4 years ago

You shouldn't need to do rpath fixing. Conda build fixes them to be relative always so provided you keep the standard fhs layout things will get found.

For packaging applications there two options, constructor and conda-pack. Neither of these will mess with rpaths.

mingwandroid commented 4 years ago

Bit you asked for the preferred way. My preferred way is to add a conda package to conda-forge and tell your users to get it from there.

certik commented 4 years ago

One major issue with static linking: the main application would have to be LGPL (https://stackoverflow.com/a/10179181). I cannot do that. Which means that I cannot use static linking and will have to use dynamic linking. That's unfortunate.

Regarding distribution, requiring every end user of my app to install Conda is too much. For people who already use Conda the Conda pakcage solution is great -- although because this app is not open source, I would have to host an internal Conda channel. But even if it was open source, it's much easier if people just download a tarball, unpack and run. No need to run conda-pack (which I have used before).

So I will investigate how to build using Conda, but then extract the relevant shared libraries and put them all into a tarball with the application and figure out how to make it just work on each platform.

certik commented 4 years ago

I just checked and ParaView is distributed precisely as I was hoping to achieve: just a tarball that you unpack and you can directly run bin/paraview and it uses relative rpath. Qt5 is just a shared library, so that ParaView can stay BSD licensed.

mingwandroid commented 4 years ago

Yes, I forgot to mention the licensing implications of static qt.

mingwandroid commented 4 years ago

The problem with 'naive' approaches to repackaging is that the linking scripts (prelink and postlink, where by linking we don't mean C/C++ linking, we mean installation of packages) will not get run.

This means qt.conf will not get written. This needs to happen somehow and it needs to contain the right user-specific install paths.