c++clinuxshared-libraries

Difference between version number, minor number and release number


I'm reading http://www.tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html and I had some questions.

What is difference between version, minor and release number? What is meant by the part "version number is incremented whenever the interface changes"?

The soname has the prefix lib, the name of the library, the phrase .so, followed by a period and a version number that is incremented whenever the interface changes.

The real name adds to the soname a period, a minor number, another period, and the release number.


Solution

  • Each time you release the library, it should arguably have a different version number. However, some releases only make changes to the internal workings of the library without affecting users at all other than by fixing bugs. Other releases may also add new functions to the library, but the interface details of all the existing functions are the same as before, so software written to use an older version of the library will continue to work with the new version. Other changes may break backwards compatibility; a function interface changes, a structure changes size, or a function is dropped (or a global variable — perish the thought — changes, etc).

    The 'bug fix only' versions might not bother with renumbering the library, but if you previously had liberror.so.1.0.2, the new version might be liberror.so.1.0.3, a change in the release number.

    The 'additional features' versions should be given a new minor number, so the new version after liberror.so.1.0.2 might be liberror.so.1.1.0.

    If you break compatibility, then you use a new version number, so the new version after liberror.so.1.0.2 might be liberror.so.2.0.0.

    Code built to use liberror.so.1.0.2 can and will use either liberror.so.1.0.3 or liberror-1.1.0 without problem, but will not attempt to use liberror.so.2.0.0 or later versions.


    What code (in a GNU binutils stack, for example) controls which versions will be linked to, and is this behavior fixed or overridable?

    Good question. This is my understanding, but I might have some details wrong (in which case, someone will probably point out the error of my ways). The theory above is nice an easy; this is a little less easy.

    You may have noticed that there are 'development' packages for libraries as well as the 'standard' versions of the libraries. The difference between them is part of the explanation.

    If you're an ordinary end user who is not writing programs using a library but simply running programs that someone else has written, then you typically end up with one file and one symlink in the installation directory. Continuing with the hypothetical liberror.so.1.0.2 example (installed in /usr/local/lib), you would find in the base release:

        liberror.so.1.0.2   — the real shared object
        liberror.so.1       — symlink to the the real shared object
    

    If you installed the development version, you'd probably find some header files in /usr/local/include, some man pages (perhaps in /usr/local/man, perhaps in /usr/share instead), and an extra symlink:

        liberror.so         — another symlink, either to liberror.so.1 or to liberror.so.1.0.2
    

    When the program using it is compiled, you might specify:

    gcc -I/usr/local/include usererror.c -o usererror -L/usr/local/lib -lerror
    

    This will link with the name liberror.so, but reading the metadata from the liberror.so.1.0.2 file, it would know that the version to use is liberror.so.1.0.2 or later (but not liberror.so.2.0.0 or later).

    Now let's suppose you upgrade the installation to liberror.so.2.0.0. You now have files:

    liberror.so.1.0.2   — the real shared object
    liberror.so.1       — symlink to the the real shared object
    liberror.so.2.0.0   — the real shared object
    liberror.so.2       — symlink to the the real shared object
    liberror.so         — another symlink, either to liberror.so.2 or to liberror.so.2.0.0
    

    Old code built to use liberror.so.1 still runs using that library. New code built to use liberror.so.2 also runs using the new library. And at link time, new programs pick up liberror.so.2.0.0 via the symlink liberror.so.

    You can control it so that the default on your system is still liberror.so.1 by adjusting the liberror.so symlink to point to liberror.so.1.0.2. The only tricky part is making sure that the correct versions of the headers are available for compilation. It is a bad idea to build with the headers for liberror.so.2 and link with liberror.so.1 because the one thing you know for sure is that the interfaces are different!


    Some raw data from a Red Hat Enterprise Linux 5 (RHEL5) x86_64 machine.

    $ cd /lib64
    $ ls libc*
    -rwxr-xr-x 1 root root 1713088 2009-01-05 16:32 libc-2.5.so
    lrwxrwxrwx 1 root root      11 2012-02-22 15:05 libcap.so -> libcap.so.1
    lrwxrwxrwx 1 root root      14 2012-02-22 15:05 libcap.so.1 -> libcap.so.1.10
    -rwxr-xr-x 1 root root   17384 2006-11-14 01:36 libcap.so.1.10
    -rwxr-xr-x 1 root root  197744 2009-01-05 16:32 libcidn-2.5.so
    lrwxrwxrwx 1 root root      14 2012-02-22 15:05 libcidn.so.1 -> libcidn-2.5.so
    lrwxrwxrwx 1 root root      17 2012-02-22 15:05 libcom_err.so.2 -> libcom_err.so.2.1
    -rwxr-xr-x 1 root root   10000 2008-09-30 13:27 libcom_err.so.2.1
    -rwxr-xr-x 1 root root   48600 2009-01-05 16:32 libcrypt-2.5.so
    -rwxr-xr-x 1 root root 1048728 2005-10-31 06:47 libcrypto.so.0.9.6b
    -rwxr-xr-x 1 root root 1365504 2008-12-16 08:09 libcrypto.so.0.9.8e
    lrwxrwxrwx 1 root root      19 2012-02-22 15:05 libcrypto.so.2 -> libcrypto.so.0.9.6b
    lrwxrwxrwx 1 root root      19 2012-02-22 15:05 libcrypto.so.4 -> libcrypto.so.0.9.8e
    lrwxrwxrwx 1 root root      19 2012-02-22 15:05 libcrypto.so.6 -> libcrypto.so.0.9.8e
    lrwxrwxrwx 1 root root      15 2012-02-22 15:05 libcrypt.so.1 -> libcrypt-2.5.so
    lrwxrwxrwx 1 root root      11 2012-02-22 15:05 libc.so.6 -> libc-2.5.so
    $
    

    You can see the libc.so.6 is a symlink to libc-2.5.so. You can also a number of versions of libcrypto, not including the link-time library libcrypto.so. You can also see libraries with only two parts to the version number, etc. The represented libraries are libc, libcap, libcidn, libcom_err, libcrypt and libcrypto.

    See also: Semantic Versioning 2.0.0