On Friday 06 September 2013 12:27:08 Jan Kundrát wrote: > 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. >
You forgot to include [1] link. > -> Is there really a problem with adding a *static plugin* > into a *shared library*? > I think yes, because that qt plugin instance function comes from static library linked into dynamic. And for this is whole-archive flag needed. Rather include static plugins directly into execuable and call import_plugin macro from main.cpp file. > > 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. > This is easy and simple, just one cmake option switch and if statement. And it can be usefull if trojita is compiled with 2 defined static plugins and other dynamic plugins are not needed. > > 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. > Searching for plugins is not done by dynamic linker, but by trojita code itself (in our case by QPluginLoader). > > 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. > No, this is for users who do not want precompiled OBS version with more plugins... > 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. > Yes, moving build directory is something which we do not care about. But moving binary without build directory should work and not break full application. This is also common on windows platform, where user choose where he will put executable binary *not* at compile time. > > 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? > Personal preference. I do not see reason why application must be splitted into 10 libraries. For me this sounds like problem in application itself. > > 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: > Yes, whole-archive linker flag. > 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) > This means to drop all non gcc compilers/linkers. And you already wrote that these hacks are not acceptable. > 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) > See my objections about tons of private libraries. > 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?) > This is what cmake doing in my gsoc-branch now > - 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) > 4) Create only libtrojitaprivate.so (which will have all code from Common, Composer, Plugins, ...), trojita executable (link to libtrojitaprivate.so), kontact-plugin.so (link to private too), and link all test and plugins to private library too. This will of course slow down compilation (because everything needs to be relinked) > 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. > Yes, option 3) is for me the best. It only waste disk space (kontact and trojita have duplicated code), but only one version is used at one time. And it does not need to relink every binary after single change (e.g version string) -- Pali Rohár pali.ro...@gmail.com
signature.asc
Description: This is a digitally signed message part.