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/