= Library Versioning
---
== Library::Version
This package contains a class representing Library versions and methods to
manage them. And a means to link/load a versioned library. Please refer to the
doccumentation for Library and Library::Version and the tests for api usage.
The versioning system supported is that of gnu libtool, and this is explained
below.
Taken from http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91
== 11.4 Library Versioning
It is important to note from the outset that the version number of your project
is a very different thing to the version number of any libraries shipped with
your project. It is a common error for maintainers to try to force their
libraries to have the same version number as the current release version of the
package as a whole. At best, they will break binary compatibility unnecessarily,
so that their users won't gain the benefits of the changes in their latest
revision without relinking all applications that use it. At worst, they will
allow the runtime linker to load binary incompatible libraries, causing
applications to crash.
Far better, the Libtool versioning system will build native shared libraries
with the correct native library version numbers. Although different
architectures use various numbering schemes, Libtool abstracts these away behind
the system described here. The various native library version numbering schemes
are designed so that when an executable is started, the runtime loader can,
where appropriate, choose a more recent installed library version than the one
with which the executable was actually built. This allows you to fix bugs in
your library, and having built it with the correct Libtool version number, have
those fixes propogate into any executables that were built with the old buggy
version. This can only work if the runtime loader can tell whether it can load
the new library into the old executable and expect them to work together. The
library version numbers give this information to the runtime loader, so it is
very important to set them correctly.
The version scheme used by Libtool tracks interfaces, where an interface is the
set of exported entry points into the library. All Libtool libraries start with
`-version-info' set to `0:0:0' -- this will be the default version number if you
don't explicitly set it on the Libtool link command line. The meaning of these
numbers (from left to right) is as follows:
*current*
The number of the current interface exported by the library. A current value of
`0', means that you are calling the interface exported by this library interface
0.
*revision*
The implementation number of the most recent interface exported by this library.
In this case, a revision value of `0' means that this is the first
implementation of the interface. If the next release of this library exports
the same interface, but has a different implementation (perhaps some bugs have
been fixed), the revision number will be higher, but current number will be the
same. In that case, when given a choice, the library with the highest revision
will always be used by the runtime loader.
*age*
The number of previous additional interfaces supported by this library. If age
were `2', then this library can be linked into executables which were built with
a release of this library that exported the current interface number, current,
or any of the previous two interfaces. By definition age must be less than or
equal to current. At the outset, only the first ever interface is implemented,
so age can only be `0'.
For later releases of a library, the `-version-info' argument needs to be set
correctly depending on any interface changes you have made. This is quite
straightforward when you understand what the three numbers mean:
1)
If you have changed any of the sources for this library, the revision number
must be incremented. This is a new revision of the current interface.
2)
If the interface has changed, then current must be incremented, and revision
reset to `0'. This is the first revision of a new interface.
3)
If the new interface is a superset of the previous interface (that is, if the
previous interface has not been broken by the changes in this new release), then
age must be incremented. This release is backwards compatible with the previous
release.
4)
If the new interface has removed elements with respect to the previous
interface, then you have broken backward compatibility and age must be reset to
`0'. This release has a new, but backwards incompatible interface.
For example, if the next release of the library included some new commands for
an existing socket protocol, you would use -version-info 1:0:1. This is the
first revision of a new interface. This release is backwards compatible with the
previous release. Later, you implement a faster way of handling part of the
algorithm at the core of the library, and release it with -version-info 1:1:1.
This is a new revision of the current interface.
Unfortunately the speed of your new implementation can only be fully exploited
by changing the API to access the structures at a lower level, which breaks
compatibility with the previous interface, so you release it as -version-info
2:0:0. This release has a new, but backwards incompatible interface.
When deciding which numbers to change in the -version-info argument for a new
release, you must remember that an interface change is not limited to the API of
the library. The notion of an interface must include any method by which a user
(code or human) can interact with the library: adding new builtin commands to a
shell library; the format used in an output file; the handshake protocol
required for a client connecting over a socket, and so on.
Additionally, If you use a development model which has both a stable and an
unstable tree being developed in parallel, for example, and you don't mind
forcing your users to relink all of the applications which use one of your
Libtool libraries every time you make a release, then libtool provides the
`-release' flag to encode the project version number in the name of the library,
See section 11.2.1 Creating Libtool Libraries with Automake. This can save you
library compatibility problems later if you need to, say, make a patch release
of an older revision of your library, but the library version number that you
should use has already been taken by another earlier release. In this case, you
could be fairly certain that library releases from the unstable branch will not
be binary compatible with the stable releases, so you could make all the stable
releases with `-release 1.0' and begin the first unstable release with `-release
1.1'.