[Geany-Devel] New plugin loader mechanisms

Thomas Martitz kugel at xxxxx
Wed Mar 18 23:16:01 UTC 2015

Am 18.03.2015 um 22:23 schrieb Lex Trotman:
> Hi Thomas,
> In general this looks like an improvement to the current method of
> setting up plugins, except it continues to require the plugin .so file
> to be dlloaded just to populate the plugin manager.  That will run the
> dll initialization code, and may therefore break Geany.  Have you
> thought about having a separate plain data file with the data for the
> plugin manager so the dll doesn't need loading until its activated by
> the PM?
> A few specific things in-line below.

Yes I have thought a lot about this, and I concluded that libpeas is the 
right way to accomplish this. Therefore my longterm goal is to use 
libpeas for geany plugins. According to my current roadmap I'll 
implement this as a plugin (i.e. a plugin that uses libpeas to proxy 
other plugins), which I already have prototyped. In this scenario the 
other plugins use the peas-style .ini metafile.

To be able to do this I need a few, relatively minor changes, to Geany 
to support this infastructure. This will also benefit geanypy, which can 
then too act as a proxy and finally show scipts in the main PM dialog 
and support keybindings properly. All of these infrastructure changes 
remain API and ABI compatibility to all existing plugins.

For Geany core I don't plan to bring a metafile soon. I tried to get 
libpeas into the core, but such major changes are not feasible at the 

> Ok, the number of symbols went from 5-6 to 1 but we still have the
> same name exported from each dll, so the original problem of symbols
> still exists.  I don't think there is a solution really.

This is a solution, and I think it's the only one. The difference is 
that with this symbol it is only referenced once through 
g_module_symbol() by geany, by using the GModule handle. This way 
namespace collisions *cannot* occur. Afterwards the function is never 
referenced anymore, neither by the core nor plugin, so in the case that 
a second plugin's geany_load_module() collides with the one of the first 
plugin the first one is never referenced again anyway. There is no 
problem here.

Whereas now plugins reference their geany_plugin globals (without 
g_module_symbol()) which, unless measures are taken, collide accross 
plugins (so plugin 1 could accidentally access plugin 2's geany_plugin).

There is no other way of loading C shared libraries and registering them 
as plugins.

>> And the only thing this function ought to do is to call
>> geany_plugin_register(). This does 4 things
>> 1) Provide the plugin handle to the plugin very early
>> 2) Perform abi and abi checks, so this is finally done inside geany. Added
>> bonus is that geany knows the requested api and can possibly apply
>> backcompat workarounds on a per plugin basis (instead of globally), warn
>> about very old plugins or even deny loading them.
> This precludes the plugin from adapting itself to Geany since the
> plugin is not supplied with the API and ABI numbers.  It would be good
> if a plugin could do simple things like:
>      if (ABI > 124) f1() else f2();

Surely you mean if (API > 124) f1() else f2() right?

But indeed, the API version could be passed to geany_load_module() to 
allow for the above. Passing the abi version is pretty useless as the 
plugin will only load with one specific abi anyway so it can't adapt.

> Also it would be good to consider the semantics of API and ABI since
> there are some conditions where we cannot express a change in the
> interface except for the hammer of an ABI break.

We should be able with the new loader mechanism, since we learn about 
the plugin's minimum API version. Now we can not only deny based on the 
ABI version but also based on the minimum API (we could possibly deny 
loading plugins which are written against too old API version).

Best regards

More information about the Devel mailing list