2

I am developing a cross platform shared library right now, and I'm a bit confused about the correct way this works on *nix. My plan for versions is pretty standard, majors break interfaces, minors add to interfaces but remain compatible with older versions, and patch numbers are bug fixes / improvements that don't touch the interfaces. This translates to minors must increment the SO Version.

So, the filename for the library is libNAME.so.X.Y.Z for library version X.Y.Z, and the install name is libNAME.so.X.Y. My issue here is that when I update my minor, I would like existing linked executables to use the new library (since they are backwards compatible down to X.0.0), but the executables are linked against the old minor libNAME.so.X.Y. So, does that mean I need to maintain a list of symlinks for all minor versions below the current and update them all to point to the new library everytime I upgrade my shared lib?

  • Seems like ldconfig is the answer here, though I'm not sure how exactly – pat Sep 27 '14 at 4:51
  • Actually, it looks like my intended plan for the version isn't the linux way of doing things. The linux way is to increment the major after any change to the interface, so adding to it, even if it doesn't change the old, should increase the major. That's a bit of a drag. I think I'm just going to maintain the symlinks. – pat Sep 27 '14 at 5:13
1

Programs using your library should link with libNAME.so if they want the latest version, with libNAME.so.X if they want the latest of the major version X, and with libNAME.so.X.Y if they want a particular minor version.

If you just provide the extra links for libNAME.so, libNAME.so.X and libNAME.so.X.Y to libNAME.so.X.Y.Z they will all use the latest version and you can always update these links.

Assume the version you are installing bumps the minor version, before that time the links would be (assume Y-1 to be the number before Y and z the latest patchlevel for the X.Y-1 series):

libNAME.so -> libNAME.so.X.Y-1.z
libNAME.so.X -> libNAME.so.X.Y-1.z
libNAME.so.X.Y-1 -> libNAME.so.X.Y-1.z

after the update is installed (Z is probably 0 maybe 1):

libNAME.so -> libNAME.so.X.Y.Z
libNAME.so.X -> libNAME.so.X.Y.Z
libNAME.so.X.Y-1 -> libNAME.so.X.Y-1.z
libNAME.so.X.Y -> libNAME.so.X.Y.Z

any program that explicitly linked to use X.Y-1 will still find the X.Y-1.z file.

Following this scheme there is no need to update any of the previous links apart from the ones indicated and you can determine which ones those are from whether your major, minor or patch number changes (1, 2, resp 3 links).

It used to be much more common to have old versions of libraries on your system with these "intermediate" links. But package management often takes away the old versions.¹

¹ I always liked this way of doing things, relying on the links to get you the latest version, if not explicitly asking for an older one. On the Microsoft MFC conference (1994), where DLLs were presented as a solution for shared libraries, I pointed out to the speaker, the problem of accessing older versions without such an already proven scheme. The phrase "DLL hell" still had to be invented at that point.

  • I like this solution, and I think it will work fine, but what if someone tries to run a program linked with a newer (minor) version of the library than they have? They will likely get unresolved external symbols errors. I suppose the alternative would be file not found errors, which might be even more confusing. Okay! This is what I will do. – pat Sep 27 '14 at 5:32
  • @pat An old program can always run with a newer minor version number, as only extra stuff is introduced in the library. A new program requires the installation of at least the library version it was linked against. – Anthon Sep 27 '14 at 5:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.