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
signature.asc
Description: This is a digitally signed message part.