On Thursday, 5 September 2013 17:02:47 CEST, Pali Rohár wrote:
- libtrojitaprivate.so shall include code for the basic
plugins which implement e.g. password storage via QSettings

Not possible without linker or other hacks.
[...]
2. "static" plugin which has own qt_instance_<NAME> function (mangled by C macro at compile time) and which doing some magic. For initializing static plugin is needed to call some Qt macro Q_IMPORT_PLUGIN in main c++ file which will do all magic. And then plugin is available in QPluginLoader in static plugin list.

Thanks for writing this up. The documentation I read only says that one should put the Q_IMPORT_PLUGIN "somewhere in the application (in a .cpp file)". Some 3rd-party docs [1] explicitly acknowledge that one can include a "static plugin" in a shared library.

-> Is there really a problem with adding a *static plugin* into a *shared library*?

And working platform/compilter/linker independent solution for this problem (sharing full c++ classes in executable & dynamic library) is moving common functions into separate dynamic shared library.

I'm happy that we've reached a consensus here.

And both hacks are needed *only* for loading *dynamic* plugins if common shared library is not using.

I don't think we have to support this use case.

With static plugins I wanted:

1. include some common plugins into executable, so badly installed trojita application will be able to use at least qsettings passwords...

I'd prefer to rely on the dynamic linker to check for "obviously bad" installation -- hence my suggestion to move the basic static plugins into a required shared library.

2. ability to compile trojita binary for specific usage:

* trojita with two selected plugins (one password, one addressbook) and everything in one executable

or

* only kontact kpart dynamic library with static linked kaddressbook and kwallet plugins

Some high level users do not need all plugins and one specific which using is enough. Also ability to have one binary with everything copied into eg. ~/bin/trojita without worring where to store plugin library XYZ...

First of all, users who couldn't be bothered to compile themselves can just fetch the nightly builsd from the OBS. It won't get much easier.

Those who for some reason cannot use that are encouraged to follow the instructions. When plugins are added to the mix, the instructions will include something like this:

1) cmake -DCMAKE_INSTALL_PREFIX=/opt/trojita ..
2) make && make test && make install
3) run /opt/trojita/bin/trojita

I also want this whole thing to work right from the build directory without invoking `make install`. I believe that this can be done (cmake IIRC does all required rpath mangling for us).

What I explicitly do *not* care about are people doing "creative" things like moving their build directory somewhere else and expecting that Trojita will still work. I just don't see why we should be adding extra code to make this work.

I'm tryinto to solve problem: Application installing tons of libraries which are needed for normal operations. Not that application depends on tons of system (or other common gui) libraries used by other applications.

I'm lost here -- do you object to a single binary linking to 10 application-specific shared libraries? If so, is there some technical argument, or is it a matter of personal preference?

One problem is there. CMake should not create any static libraries like:

add_library(Streams ${libStreams_SOURCES})
add_library(qwwsmtpclient ${libqwwsmtpclient_SOURCES})
...

But every source C++ file must be added directly to libtrojitaprivate (otherwise link hack is needed)

add_library(trojitaprivate ${libStreams_SOURCES} ${libqwwsmtpclient_SOURCES ...)

This means radical CMakeLists.txt changes...

Assuming you mean --whole-archive here. Well, it's a pity cmake doesn't support it in a portable way. So we basically have three possibilities:

1) Hardcode --whole-archive and produce the following targets:

 - libtrojitaprivate.so
 - libtrojitapluginsprivate.so
- trojita-kontact.so (linking to libtrojitaprivate.so & libtrojitapluginsprivate.so) - trojita (small binary linking to libtrojitaprivate.so & libtrojitapluginsprivate.so)
 - test_* (small binaries linking to libtrojitaprivate.so), not installed
 - trojita_plugin_*.so (linking to libtrojitapluginsprivate.so)

2) Produce a ton of shared libraries

- libtrojitaCommon, libtrojitaComposer, libtrojitaIMAP, libtrojitaMSA, libtrojitaStreams.so,...
 - libtrojitapluginsprivate.so
 - trojita (linking to all libs)
 - trojita-kontact.so (linking to all libs)
 - test_* (linking to all libs, not installed)
 - trojita_plugin_*.so (linking to libtrojitapluginsprivate.so)

3) Don't change anything, "waste" some space with duplicated code in both standaalone executable and the shared library for Kontact (can we do this?)

 - libtrojitapluginsprivate.so
 - trojita (linking to libtrojitapluginsprivate.so), a big size
 - trojita-kontact.so (linking to libtrojitapluginsprivate.so), a big size
- test_* (not linking to anything unless it works with plugins, not installed)
 - trojita_plugin_*.so (linking to libtrojitapluginsprivate.so)

Pali, Thomas, Caspar, Kevin -- which of these do you prefer? I believe that 3) actually provides fastest compile times during regular development (i.e. the lest to rebuild upon an isolated change), which is somewhat of a one of the metrics to me.

Cheers,
Jan
--
Trojitá, a fast Qt IMAP e-mail client -- http://trojita.flaska.net/

Reply via email to