Solaris: What is the difference between .so and .so.1 files?
Solution 1:
This question is not specific to Solaris.
When you install a shared library (or a piece of software that provides a shared library), you get three files, they all look similar but have different purposes.
-
libfoo.so.1.0.0
‒ This is the (regular) data file. It contains the library itself. You could have multiple of these, with different versions. Inside this file, there is an ELF field called SONAME, which is set tolibfoo.so.1
. On Linux, runobjdump -p libfoo.so.1.0.0 | grep SONAME
to find out. -
libfoo.so
→libfoo.so.1.0.0
‒ This is a symlink which is used when compiling software against libfoo. When you specify-lfoo
to the linker, it will look for exactlylibfoo.so
. Normally,libfoo.so
is never a regular file, it is always a symlink which points to the version of libfoo which you want to use for linking. In a complex build environment, you could have multiple versions of the library, and you use this symlink to choose, against which version you want to link. -
libfoo.so.1
→libfoo.so.1.0.0
‒ This is also a symlink, which is used when you run binaries that need your library. Remember the SONAME field I mentioned? When you link a binary against libfoo, the binary will record the SONAME of the library and will use it at runtime.
This setup allows you to have multiple versions of the same library installed alongside each other. Different binaries may require different versions of the library, and each binary will find the right version of the library. Usually, the SONAME of the library is changed by the upstream when there is a backward-incompatible API change. All the old binaries still use the old API, while newly linked binaries use the new one.
Some packaging projects, Debian would be one example, use different package names for different versions of a library. This allows you to install and uninstall each version of the shared library independently.
There are some edge cases. For example, dependencies between shared libraries can lead to two versions being pulled in at the same time. Consider:
foo → libbar.so.1, libbaz.so.1
libbar.so.1 → libbaz.so.1
Imagine that we install a new version of libbaz and recompile foo. Now we have:
foo → libbar.so.1, libbaz.so.2
libbar.so.1 → libbaz.so.1
At runtime, foo will load libbaz.so.2
and libbar.so.1
, and libbar.so.1
will load libbaz.so.1
. See the problem? Two versions of libbaz are loaded at the same time. I'm not entirely sure what's the exact consequence in terms of the layout of the code in memory, but in practice this results in crashes.
Solution 2:
Yes, the ".1" indicates the version number. This makes it possible to have multiple versions of the same library side-by-side, whereas the most common version has a link with no version number.
If there is no need to distinguish between different versions, the version suffix might not be present.