[Geany-devel] geany-plugins depends on GIO

Colomban Wendling lists.ban at xxxxx
Mon Nov 22 15:36:04 UTC 2010

Le 18/11/2010 23:56, Lex Trotman a écrit :
> 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.
Not exactly. You can still happen members to structs (but see below for
thoughts about structs) without breaking the A[PB]I, and I think that
this doesn't really apply for functions.
In a library POV, I think that functions' signature should be got right
the first time (it isn't easy, but…); and I still think that it'd be
overkill to handle such changes from a plugin.

> 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.
I agree, exposing members is generally a pain.

> 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??)
Well, right.

>> 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.
Wouldn't manually checking for /everything/ be a PITA? Or at least,
provide a trivial way to say "if this functions isn't present, I can't
run". Or I miss something?

> 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.


More information about the Devel mailing list