[Geany-devel] geany-plugins depends on GIO

Lex Trotman elextr at xxxxx
Thu Nov 18 22:56:21 UTC 2010


On 19 November 2010 03:16, Colomban Wendling <lists.ban at herbesfolles.org> wrote:
> Le 18/11/2010 01:18, Lex Trotman a écrit :
>> On 18 November 2010 10:16, Colomban Wendling <lists.ban at herbesfolles.org> wrote:
>>> Le 17/11/2010 23:09, Lex Trotman a écrit :
>>>> On 18 November 2010 03:36, Colomban Wendling <lists.ban at herbesfolles.org> wrote:
>>>>> But does new API really matters? If a plugin writer wants to keep being
>>>>> compatible with old Geany versions, she just have not to use new API --
>>>>> as far as the ABI hasn't changed.
>>>>>
>>>>
>>>> But ATM how does a plugin check that without being re-compiled?
>>> What what what? :D
>>> If a plugin compiles with version 0.18 and Geany doesn't detect a
>>> problem when comparing the ABI version it was built against, it IS
>>> compatible, no? And if the same plugin is compiled against Geany 0.19
>>> (assuming the ABI hasn't changed), it will still work with Geany 0.18...
>>
>> Yes, but ANY change to the API/ABI even in areas that the plugin
>> doesn't use changes the version and makes the plugin incompatible with
>> older Geany.
> Okay, I think I got your point, reading this and some other mails in
> this thread: you want to prevent ABI bumps to break plugins that are not
> directly affected.
>
> Yes, an ABI bump break every plugin that was compiled before it. If it
> isn't affected, it has to be rebuild.
>
> But I'm with Enrico here: I don't think ABI bumps will/should happen often.

That means as soon as you expose something its frozen, you have to get
it complete and exactly right the first time, no incremental
development.  I think thats setting a pretty large barrier for a small
project like Geany.

And as more goes into plugins the difficulty increases, it doesn't decrease.

>
> And finally, if you want to protect from ABI breakage, you have to
> protect every symbol, not only functions, but also structures and
> structure members (even enums values may need this then).

Each function in *Funcs in plugindata.h

Just structures (ie each pointer in GeanyData), no need to protect
individual members because over time structures should be removed from
the API because they expose implementation details that are then
frozen.  They should use accessors to read/write only the information
the plugin needs and new fields should be exposed that way rather than
in the structures.

Similarly types internal to Geany should not be exposed, except
perhaps as an opaque typename needed for some functions (ie returned
by one call and passed to another).

Enums don't need it since changing one changes the struct/function
that uses it so they are protetcted that way. (if they are not used in
a visible struct/function why are they exposed??)

>
> So... while I'm not (and never was) against having a very flexible
> dependency mechanism, I still think it's overkill, and won't it to make
> everything complicated. If backbard compatibility is this important, I'd
> prefer to simply keep the whole ABI stable, even if it may cost some
> deprecated things and some "old and now useless stuff": it isn't really
> nice either, but still seems less bloated to me.
>
> But I'd be curious to see how you would implement this :)

Well this is a first thought only :-)

Have a set of structs parallel to GeanyData and *Funcs structures,
with same member names and all unsigned ints.  Lets call them say
GeanyDataVersion and *FuncsVersion. Collectively called the *Version
structs.

Also have API and ABI numbers for GeanyData and *Funcs struct, that
handles additions (changes API) and removals (changes ABI) to the
struct itself.  This needs only one struct with members named after
the structures, lets call it the StructVersions struct.

plugindata.h has #defines for each value to go in the *Version structs
eg #define GEANYAPPVERSION 12345 to use the first struct in GeanyData
as the example and similar symbols for the StructVersions values.
This allows plugins to still do static checks if they want to.

plugins.c has the *Version and StructVersions structs initialised with
these symbols.

Each plugin has an array of:

struct detailed_versions_needed {
    size_t item_to_check;              // offset of a member of
GeanyDataVersion or *FuncsVersion, NULL to end
    unsigned int required_version;  // version must equal this
};

initialised with the required offsets and versions, and the plugin
also has a StructVersion struct initialised as required.

A macro PLUGIN_DETAILED_VERSION_CHECK defines a function that runs
through the array and the struct doing the checks.

Geany checks if the plugin has the plugin_detailed_version_check
symbol and only calls it if it does, otherwise it calls the normal
plugin_version_check.

Something like this approach does not force plugins to change
immediately, it can happen over time.  Also it allows a simple tool to
check that a plugin dev has listed all the functions and structs she
used.

We should not force immediate change on the plugins, but the plugins
won't start changing until the facility is made available :-) and the
sooner it is the easier for new plugin developers.

Cheers
Lex

>
>
> Regards,
> Colomban
> _______________________________________________
> Geany-devel mailing list
> Geany-devel at uvena.de
> http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel
>



More information about the Devel mailing list