On Tuesday 13 August 2013 13:43:14 Thomas Lübking wrote:
> On Dienstag, 13. August 2013 08:26:51 CEST, Pali Rohár wrote:
> > On Monday 12 August 2013 22:36:26 Jan Kundrát wrote:
> >> They way I understand it, Pali wants to support a
> >> configuration where there are no shared libraries, just the
> >> /usr/bin/trojita with some plugins statically linked in.
> > 
> > Yes, I want to support also this configuration. But not only
> > this.
> > 
> > No. Runtime loading should work too (at least with GCC). For
> > GNU compiler/linker is needed special flag, but this is
> > added by cmake when using GNU. Also if some password and
> > some addressbook plugins will be statically linked into
> > trojita executable, it will not be needed anymore.
> 
> Runtime symbol resolution is performed by RTDL_* - it should
> not be affected here.
> 
> The reason why Pali (likely) needs -whole-archive is because
> otherwise the unreferenced objects in the plugins will not be
> resolved / included. I doubt that it's implicit impact on
> symbol resolution (precendence of static linked libs) is any
> important here. (Please fix me, if i missed sth. obvious, but
> sane symbol resolution is done differently anyway)
> 

Yes, by default linker doing optimalization which drop all 
code/symbols from executable which are not used. And because 
protected constructor of main plugin class is not used in trojita 
(if there are no static linked plugins into executable) it is 
dropped.

There is no real difference between using common shared library 
and static linked common library into executable. In first case 
(with shared library) dynamic linker resolve all symbols needed 
by plugins and trojita at runtime. In second case (with static 
linked library) all shared symbols are present in trojita 
executable and these symbols are exported to dynamic linker. So 
when plugin is loading dynamic linker will use exported symbol 
from trojita executable.

And static common library is linker only to trojita executable 
and not to plugins. So there is no duplicate code.

> ---
> 
> Pretending this is a reasonable target:
> ============================
> a) -whole-archive is not specific to GCC, but GNU ld - no
> matter which compiler invokes it, so that should be tested
> instead.
> 
> b) the equivalent on CLANG is -force_load <library>, MSVC has
> /INCLUDE [1] and /OPT:NOREF [2] - no guarantee that it works
> at all (One could look up the dsp's for Qt)
> 
> c) simply DO NOT DO THAT.
>    ---------------------
> If you want to compile in plugins, just instantiate the
> objects based on the plugin name, like
> 
> if (pluginName == "ClearTextPassword")
>    plugin = new ClearTextPassword;
> else if (pluginName == "AkonadiAddressbook")
>    plugin = new AkonadiAddressbook;
> else if () ...
> else {
>    // attempt to dlopen plugin library here
> }
> 
> This will get you the relevant objects referenced and added to
> the binary by all compilers that are the least ISO compliant.
> And it requires one preprocessor block and CFLAG only.
> 
> It will also prevent unneeded bloat (in case there's
> irrelevant stuff in the lib you link in this way) and not be
> acidentally broken by downstream, tweaking compiler options
> for optimization.
> 
> Cheers,
> Thomas
> 
> [1]
> http://msdn.microsoft.com/en-us/library/2s3hwbhs(v=VS.100).as
> px [2]
> http://msdn.microsoft.com/en-US/library/bxwfs976(v=VS.80).asp
> x

Qt has native support for static linked plugins. See macro 
Q_IMPORT_PLUGIN which *must* be defined in main code, so linker 
will use include needed plugin to binary. Also in this case 
whole-archive flag is not needed, because symbol is referenced in 
main.cpp and linker must include it into library (otherwise 
symbol in main.cpp will be unresolved and binary not compiled).

Flag -whole-archive is needed only if trojita code not calling 
protected plugin constructor which is only if trojita code not 
creating instance of some plugin.

-- 
Pali Rohár
pali.ro...@gmail.com

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to