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 moment.
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
- Provide the plugin handle to the plugin very early
- 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