How do SO (shared object) numbers work?
Binaries themselves know which version of a shared library they depend on, and request it specifically. You can use ldd
to show the dependencies; mine for ls
are:
$ ldd /bin/ls
linux-gate.so.1 => (0xb784e000)
librt.so.1 => /lib/librt.so.1 (0xb782c000)
libacl.so.1 => /lib/libacl.so.1 (0xb7824000)
libc.so.6 => /lib/libc.so.6 (0xb76dc000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb76c3000)
/lib/ld-linux.so.2 (0xb784f000)
libattr.so.1 => /lib/libattr.so.1 (0xb76bd000)
As you can see, it points to e.g. libpthread.so.0
, not just libpthread.so
.
The reason for the symbolic link is for the linker. When you want to link against libpthread.so
directly, you give gcc
the flag -lpthread
, and it adds on the lib
prefix and .so
suffix automatically. You can't tell it to add on the .so.0
suffix, so the symbolic link points to the newest version of the lib to faciliate that
The numbers in the shared libraries are convention used in Linux to identify the API of a library. Typically the format is:
libFOO.so.MAJOR.MINOR
And as you noticed usually there is a symbolic link from libFOO.so to libFOO.so.MAJOR.MINOR. ldconfig is responsible for updating this link to the newest version.
The MAJOR is typically incremented when the API changes (new entry points are removed or the parameters or types changed). The MINOR typically is incremented for bug fix releases or when new APIs are introduced without breaking existing APIs.
A more extensive discussion can be found here: Dissecting shared libraries
Shared libraries should be versioned according to the following scheme:
blah.so.X.Y.Z
where
- X = backwards incompatible ABI release
- Y = backwards compatible ABI release
- Z = Internal changes only - no change to the ABI
Typically you only see the first digit like hello.so.1
because the first digit is the only thing needed to identify the "version" of the library since all the other digits are backwards compatible.
ldconfig
maintains a table of what shared libraries are available on a system and where the path to that library exists. You can verify this by running:
ldconfig -p
When a package is built for something like Red Hat, the shared libraries being called out in the binary will be looked up and added as dependencies of the package at RPM build time. Therefore, when you go to install the package, the installer will look up whether or not hello.so.1
is installed on the system by checking ldconfig
.
You can see the dependencies of a package by doing something like:
rpm -qpR hello.rpm
This system (unlike Windows) allows for multiple versions of the hello.so
to be installed on a system and be used by different applications at the same time.