Libtool Version Numbers
Author John R. Sheets explains the mystery behind the libtool versioning system.
The path to creating new versions of shared libraries can be a twisted, precarious maze. You have to juggle distribution versions with library versions. The main software package might go through major alterations without a single change to the supporting libraries, and vice versa. It's dangerous to mix package version numbers with library versions because the two are not synonymous. Package versions are fairly arbitrary, and mostly for the end user's benefit. Shared-library versions, however, refer to very specific changes in functionality. The dynamic library loader uses this version number to determine which implementation of the library to load. If you have only one libfoo.so file, the choice is easy. On UNIX, however, it's possible to have many versions of the same library in the same directory at the same time. The library version number is the loader's only hope for finding the correct library for a given application.
You can set the version for a library with an _LDFLAGS primary in your Makefile.am file, with the -version-info flag:
The three numbers stand for CURRENT:REVISION:AGE, or C:R:A for short. The libtool script typically tacks these three numbers onto the end of the name of the .so file it creates. The formula for calculating the file numbers on Linux and Solaris is (C - A).(A).(R), so the example given here would create the file libfoo.so.3.2.1. Other operating systems might use a different library file-name convention; libtool takes care of the details.
As you release new versions of your library, you will update the library's C:R:A. Although the rules for changing these version numbers can quickly become confusing, a few simple tips should help keep you on track. The libtool documentation goes into greater depth.
In essence, every time you make a change to the library and release it, the C:R:A should change. A new library should start with 0:0:0. Each time you change the public interface (i.e., your installed header files), you should increment the CURRENT number. This is called your interface number. The main use of this interface number is to tag successive revisions of your API.
The AGE number is how many consecutive versions of the API the current implementation supports. Thus, if the CURRENT library API is the sixth published version of the interface and it is also binary compatible with the fourth and fifth versions (i.e., the last two), the C:R:A might be 6:0:2. When you break binary compatibility, for example by removing a public function call, you need to set AGE to 0 and, of course, increment CURRENT.
The REVISION marks a change in the source code of the library that doesn't affect the interface, like a minor bug fix. Anytime you increment CURRENT, you should set REVISION back to 0.
John R. Sheets has been following the GNOME project on a day-to-day basis for more than two years, since GNOME was only six months old. He is a software developer for CodeWeavers, Inc., where he works on Wine and GNOME. In his free time, he is helping the WorldForge Project to create a free online multiplayer gaming environment. John is the author of Writing GNOME Applications (Addison-Wesley, 2001), and the maintainer of the OpenBooks Web site.