Library versioning

Do you maintain or contribute to a library, especially a KDE library (other than the Frameworks)? If so, I have a question for you.

First, some background. These days, the norm for libraries is to follow some variation of semantic versioning, where the version number follows the scheme x.y.z (eg: 1.4.3) and it should always be safe to upgrade the library to version with a higher y (minor) component as long as the x (major) component is the same. Qt follows this scheme, for example.

This scheme doesn’t really allow for alpha versions of software, though – the alpha releases for the (x+1) major version can be incompatible with both version x and with the final releases of version (x+1). The Semantic Versioning scheme prescribes using versions like x.y.z-alpha1, but this breaks the nicely numeric scheme we had, and not all tools can cope with that.

KDE Frameworks (and, in the past, kdelibs) approached this by defining some arbitrarily high minor version (typically 90+) to indicate pre-releases for the next major release. So the pre-release Frameworks were numbered like 4.90.1.

So where is all of this going? Well, CMake provides a helpful function to write package version information files that allow find_package() calls to only find compatible versions. So if you use the SameMajorVersion scheme, find_package(Foo 4.3) will find Foo 4.3.0 and Foo 4.5.2, but not Foo 4.2.5 or Foo 5.1.1. However, if project Foo uses the “high minor = next version prerelease” scheme, it will also find Foo 4.90.1, which is not compatible with Foo 4.3.

I wrote a SameMajorVersionWithPreleases scheme that would deal with this for Extra CMake Modules, but never committed it because I wasn’t sure if it would get used (KDE Frameworks doesn’t need it because we put KF5 in the package names). My question is: would your project find this useful? In other words, do you contribute to (or know of) a CMake-based project that uses the “high minor = next version prerelease” scheme I described above? If so, please comment!


Tags: , ,

5 Responses to “Library versioning”

  1. Links 19/11/2015: Linux Kernel 3.2.73 LTS, DockerCon EU | Techrights Says:

    […] Library versioning […]

  2. olin Says:

    This scheme is also not perfect – normally you expect that the alpha release breaks compatibility and that might be true for any released alpha version (if you release more of them). So one could expect that any of >=X.90 is incompatible and you cannot depend on the version at all (4.91.1 might be incompatible with 4.90.1). The library version should not follow the version of the software, they are independent – the software version (the whole software bundle version) does not tell you whether the API is compatible or not, the specific library version is telling you that. If you are releasing a library and break the API, you should increase the major version of the library (but not necessarily the major version of the software). This version numbering is not perfect (the granularity does not cover compatibility of separate functions/methods), but once you start using it, you should follow its philosophy.

    If you wish to have a single major version increase for the whole alpha phase, you either stop releasing alpha versions (which is not what you want), or accept the fact that the alpha is incompatible and might break at any time – in this case the used version scheme is used in a wrong way and your cmake script will not help.

    Your cmake script helps when the API is freezed – in the beta phase. But it will not help in the alpha phase, where the API breaks rather frequently.

    The correct way is the following – once you release a version (make it public), look at the library API as being frozen. If you break compatibility in the next version (and it does not matter if it is another alpha), you should increase the major version as well.

    • randomguy3 Says:

      Sure, it’s not perfect. It exists to satisfy two constraints: purely numeric versioning for everything, including alpha and beta releases, and preventing software that wants final versions from accidentally finding alpha or beta versions.

      There is a bonus of being able to explicitly look for alpha and beta releases – useful when projects are moving forward in tandem (eg: consider alpha release of Frameworks, where *all* the Frameworks will be in alpha at the same time, and depend on each other). You make a valid point about alpha releases being incompatible with each other and with everything else, but it’s easy enough to specify EXACT in the find_project() calls of the downstreams to deal with that.

  3. Johan Ouwerkerk Says:

    Expressing backwards compatibility (of libraries), that is what soversion is for isn’t it?

    • randomguy3 Says:

      Only for built objects – it only covers binary compatibility, not source compatibility. Semantic versioning aims to cover source compatibility, rather than binary compatibility.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: