GNOME Bugzilla – Bug 676565
library symbols are not versioned
Last modified: 2018-05-24 14:14:01 UTC
When a new symbol is added without changing the soname of a library, applications which use that symbol should (obviously) not be run against older versions of the library, despite the fact that the soname is the same. It's often desirable to update one or two packages from the 'next' version of a distribution, for example I recently updated the libvirt packages on my Fedora 16 to the version which is in Fedora 17 in order to fix some important bugs. Distribution packages should correctly convey their dependencies — a package which uses a symbol that was added in glib-2.31 should have a requirement on glib 2.31 or later. The Fedora packages do not have correct dependencies; packages built against glib 2.31 and using symbols which were not present in 2.30 are perfectly happy to install on a system where only glib 2.30 is present. And of course they then fail to run. This is because the glib libraries do not include versioning information in their symbols. If the new symbols were correctly versioned (e.g. g_async_queue_timeout_pop@@GLIB_2.32) then these dependencies would all work out automatically in RPM packaging, and with minimal packager intervention in Debian packaging. Please add symbol versioning (using the --version-script option to the GNU linker, or -M option to Solaris linker) on platforms where it's supported. Ideally this should be a standard feature of *all* GNOME platform libraries.
this has been discussed already on gtk-devel-list: https://mail.gnome.org/archives/desktop-devel-list/2010-May/msg00075.html with a fairly negative response. if anything, it should be brought up again on the mailing list for discussion.
by the way, libxml2 switching to versioned symbols ought to be a good case study on why people should *not* be using versioned symbols at all - unless you have a build farm that can rebuild the world and WebKit every time libxml2 does a point release.
There's a thread here: https://mail.gnome.org/archives/release-team/2012-May/msg00026.html but it should really be on gtk-devel-list not release-team i guess.
(In reply to comment #2) > unless you > have a build farm that can rebuild the world and WebKit every time libxml2 does > a point release. Uh? Versioned symbols in an ABI stable library will keep the same version forever, the version won't get increased on every symbol for each point release. Only new symbol additions will get a newer version, and you need to rebuild packages using libxml2 anyway if you want to make use of it.
(In reply to comment #4) > Uh? Versioned symbols in an ABI stable library will keep the same version > forever, the version won't get increased on every symbol for each point > release. Only new symbol additions will get a newer version, and you need to > rebuild packages using libxml2 anyway if you want to make use of it. this is all well and good, except when you're building inside jhbuild and you have half the stack built with the system libxml2 and half with the one in the jhbuild root - which will end up causing a rebuild of the entire jhbuild even if the consumers of the libxml2 API do not require different versions. the error messages coming from the linker are also entirely not useful. versioned symbols are nice if you're rebuilding the world anyway, which is the main use case coming from a distribution; developers are not keen on rebuilding the whole stack every time¸though, and will try and rebuild the minimum amount of dependencies possible because their time is more valuable fixing bugs and implementing features, instead of going around on chairs, fighting with swords, while the compiler finishes building.
libxml2 is a bit special here in that symbol versioning was always disabled in the 'last' release because of a bug, while distros added a patch to fix this bug and have libxml2 with versioning enabled. I guess most of the pain you describe came for that, but it's not a very good example for this discussion imo.
It sounds like libxml2 is an example of how *not* to do symbol versioning. No wonder people are having such a strange reaction to what should be a simple and obvious fix. Symbol versioning done sanely is simple. Whenever you add a new symbol, label it with the version that it was introduced in. Like my example above, g_async_queue_timeout_pop@@GLIB_2.32 Anything using that symbol will automatically depend on glib 2.32, and anything which *doesn't* a use a new symbol won't depend on the new library — it'll only require the latest version of the library from which it actually uses a symbol. It solves a real problem, and unless done stupidly I can't think of any reason why you *wouldn't* want to do it. It works with the Solaris and GNU linkers (which includes most *BSD systems), and doesn't *hurt* the few platforms on which it *doesn't* run.
I went through the discussions and tried to make sense of them, but for some reason I put that in Red Hat bugzilla (https://bugzilla.redhat.com/823992#c2) instead of here where it would be more appropriate. I'll copy it here... Hm, I hadn't thought to look for previous discussion; it seems like such an obviously correct thing to do to fix a real problem, that I'm surprised anyone would not want to do it; I assumed it had just never been considered or a patch had never been provided. Looking now at some of the discussion, the 'no' camp doesn't seem to be particularly well-informed... - libxml2 seems to be used as an example of why symbol versioning is bad, because AFAICT it did something insanely broken (using symbol versions and then taking them *out* in release versions, or something like that?). That is not what I mean when I refer to symbol versioning. That is just complete crack; do not use that as an example of anything. (Update: This was apparently a bug of some kind rather than being caused by *actual* use of crack cocaine on DV's part. Either way, the result appears to be the same.) - I see complaints that it doesn't allow you to version structures and other things, which is both incorrect and not necesarily relevant. Firstly, it *does* let you version structures. The canonical example of symbol versioning is its use in glibc to handle changes to 'struct stat'. And secondly, it doesn't have to solve every problem in the world — complaining that it won't cure AIDS is pointless. It solves the problem it's intended to solve, quite well. - I see complaints that it doesn't work on every platform. Which is also fine. It doesn't *hurt* any of the few platforms that don't support it. It *does* work on any platform which uses the GNU linker (or gold), and Solaris. - I see complaints that it can't cope with incompatibilities for which we really *do* need to be changing the soname of the library rather than attempting to claim backward compatibility anyway (like changing non-opaque structures that are embedded in users' own variables such as GtkWidget). Unless I'm misreading that, and in fact it was a complaint that it would be impractical to provide full backward compatibility in that case, by using symbol versions to provide "old" versions of every function that touches something like GtkWidget — which of course isn't something I'd suggest attempting anyway. Did I miss anything?
> Did I miss anything? - The people who maintain the libraries in the GTK+ stack are not interested in taking on the extra work in dealing with this.
Thanks for the constructive feedback. So the important thing is to make sure it isn't extra work. The issue of having to keep a symbol map in sync with reality had already been raised, and I'm looking at how we could automatically generate it either from the GLIB_AVAILABLE_IN_xxx macros in the header files, or the 'Since:' tags in DocBook markup.
FWIW - the rpmsodiff script will output a template, e.g.: # template for libgobject-2.0.so.0 version script GLIB2_2.40.0 { global: g_binding_unbind; g_mapped_file_get_type; g_param_spec_get_default_value; g_type_add_instance_private; g_type_class_adjust_private_offset; g_type_class_get_instance_private_offset; g_variant_dict_get_type; }; Perhaps it could be adapted for use in the glib workflow. I suppose you would need a previous version of the glib library built to compare it to.
(In reply to Orion Poplawski from comment #11) > Perhaps it could be adapted for use in the glib workflow. I suppose you > would need a previous version of the glib library built to compare it to. It would be better if, instead, there were a script that took the "Since" annotation in gtk-doc stanzas and used that to generate the ancillary file for the symbol versioning during install/distcheck. It's been made abundantly clear by the GLib and GTK+ (and G* platform libraries in general) maintainers that taking on yet another ancillary file that has to be modified each time a new symbol is added is *not* going to be taken into consideration.
Created attachment 300318 [details] gtk-symbol-versions Here's an initial hack at trying to used the Since: tags to generate a symbol version map. Comments welcome.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/548.