Libtool has its own formal versioning system. It is not as flexible as some, but it is definitely the simplest of the more powerful versioning systems.

Think of a library as exporting several sets of interfaces, arbitrarily represented by integers. When a program is linked against a library, it may use any subset of those interfaces.

Libtool's description of the interfaces that a program uses is simple:
it encodes the least and the greatest interface numbers in the resulting
binary (`first-interface`, `last-interface`).

The dynamic linker is guaranteed that if a library supports *every*
interface number between `first-interface` and `last-interface`,
then the program can be relinked against that library.

Note that this can cause problems because libtool's compatibility requirements are actually stricter than is necessary.

Say `libhello` supports interfaces 5, 16, 17, 18, and 19, and that
libtool is used to link `test` against `libhello`.

Libtool encodes the numbers 5 and 19 in `test`, and the dynamic
linker will only link `test` against libraries that support
*every* interface between 5 and 19. So, the dynamic linker refuses
to link `test` against `libhello`!

In order to eliminate this problem, libtool only allows libraries to
declare consecutive interface numbers. So, `libhello` can declare at
most that it supports interfaces 16 through 19. Then, the dynamic
linker will link `test` against `libhello`.

So, libtool library versions are described by three integers:

`current`- The most recent interface number that this library implements.
`revision`- The implementation number of the
`current`interface. `age`- The difference between the newest and oldest interfaces that this
library implements. In other words, the library implements all the
interface numbers in the range from number
`current``-`

`age`to`current`.

If two libraries have identical `current` and `age` numbers,
then the dynamic linker chooses the library with the greater
`revision` number.