On Tue, Oct 21, 2014 at 03:59:46PM +0100, David Howells wrote: > Is there a good description of ELF shared library symbol versioning best > practices somewhere? > > In particular, under what conditions do you need to create a new section in > the versioning file given to the linker's --version-script option when new > symbols are added? For libvirt, we create a new version section for each new upstream release. ie so all new APIs in a release get tagged with the version number of the release they first appeared in. > And what do you do if you've done it wrong? Cry, and then live with it forever, unless you want to break ABI and force all downstream apps to re-link :-( > For example, in libkeyutils, I added a couple of symbols to KEYUTILS_1.4 when > I should perhaps have created KEYUTILS_1.5 and added them there: > > http://git.kernel.org/cgit/linux/kernel/git/dhowells/keyutils.git/commit/?id=49249ce7d84a967fcdc06fbe6bf1d0cf89ac5215 > > I have been given a patch to move these symbols to KEYUTILS_1.5, but checking > the keyctl program with "readelf -s", I see: > > 47: 0000000000000000 0 FUNC GLOBAL DEFAULT UND recursive_session_key_sca@KEYUTILS_1.4 (7) > > so I would guess applying this patch would break anything that uses this. Yes, unfortunately anything which has already linked against your library *and* used these original symbols will have the 1.4 version encoded in their ELF section. So if you change the version to 1.5 you will cause linker loading failures which can only be fixed by rebuilding the downstream apps. > I assumed that adding them to KEYUTILS_1.4 would be okay because nothing > would've tried to use them previously because they didn't exist in any > version. One thing to bear in mind with symbol versioning is that it also interacts with RPM versioning. ie, if an application links to a symbol foo@MYLIB_X.Y then the RPM will automatically get a "Requires: mylib.so(MYLIB_X.Y)" added to it. This ensures that when you install the application, it pulls in a version of the library that is new enough to have all the symbols the application needs. Note that RPM only depends on the version, not the full symbol name. So by adding new symbols to the existing KEYUTILS_1.4 version section, no new RPM dependancies will be introduced. So an RPM install of an application that uses the new symbols, will still be (mistakenly) satisfied by the an old version of the library that lacks the symbols. This is the primary reason why for libvirt, we take the approach of always introducing a new version block for each new release that includes new APIs. BTW, there is one tricky thing to be aware of if you ever backport new APIs to old "stable branches". You likely want to avoid adding a linker version section for the stable branch, since if an app links against the stable branch version of the library, you want a clean upgrade path to the next major version of the library (assuming preserved ABI). I've never found any particularly good docs on symbol versioning when I've looked previously. In case it helps though, here's how we deal with it in libvirt: https://www.berrange.com/posts/2011/01/13/versioning-in-the-libvirt-library/ In summary, I'd probably suggest you just live with the symbols as part of the KEYUTILS_1_4 version block. It isn't a particularly serious hardship that those were added to an old version block, so not worth the pain of changing them (unless you plan to break ABI and change soname version anyway). Then for future API additions just define a new version section for each new release that adds APIs. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxxx https://admin.fedoraproject.org/mailman/listinfo/devel Fedora Code of Conduct: http://fedoraproject.org/code-of-conduct