One interesting but little known fact among users and developers alike is the reason why shared libraries are installed on systems with multiple file names. This ties a bit into the problem of
.la files, but that’s not my topic here.
Shared libraries, especially when built and installed through libtool, usually get installed with one file, and two symlinks:
libfoo.so.X.Y.Z. The reasoning for this is not always clear, so I’ll try to shed some light on the matter, for future reference, maybe it can help solving trouble for others in the future:
- first of all, the real file is the one with the full version:
libfoo.so.X.Y.Z: this because libtool uses some crazy-minded versioning scheme that should make it consistent to add or remove interfaces… in truth it usually just drives developers crazy when they start wondering which value they have to increase (hint: no, the three values you set into libtool flags are not the same three you get in the filename);
- the presence of the other two names are due to the presence of two linker programs: the build-time linker (or link editor) and the runtime (or dynamic) linker:
ld.so; each one uses a different name for the library;
- the link editor (
ld) when linking a library by short name (
-lfoo) isn’t in the known about which version you’re speaking of, so it tries its best to find the library transforming it to
libfoo.so, without any version specification; so that’s why the link with the unversioned name is there;
- the dynamic linker, when looking up the libraries to load, uses the NEEDED entries in the .dynamic section of the ELF file; those entries are created based on the SONAME entry (in the same section) of the linked library; since the link editor found the library as
libfoo.soit wouldn’t be able to use the filename properly; the SONAME also serves to indicate the ABI compatibility, so it is usually versioned (with one or more version components depending on the operating system’s convention — in Gentoo systems, both Linux and FreeBSD, the convention is one component, but exceptions exist); in this case, it’d be
libfoo.so.X; so this is what the dynamic linker looks up, it’s also not in the known about the full version specification.
Now there are a few things to say about this whole situation with file names: while libtool takes care of creating the symlinks by itself, not all build systems do so; one very common reason for that is that they have no experience of non-GNU systems (here the idea of “GNU system” is that of any system that uses the GNU C library). The thing is,
ldconfig on GNU systems does not limit itself at regenerating the
ld.so cache, but it also ensures that all the libraries are well symlinked (I sincerely forgot whether it takes care of
.so symlinks as well or just SONAME-based symlinks, but I’d expect only the latter). A few packages have been found before explicitly relied on ldconfig to do that using a GNU-specific parameter (a GNU lock-in — might sound strange but there are those as well) that takes care of fixing the links without changing the
And there our beloved
.la files come back in the scene. One of the things that
.la files do is provide an alternative to the
libfoo.so translation for the linkers that don’t do that by themselves (mostly very old linkers, or non-ELF based linkers). And once again this is not useful to us, at least in main tree, since all our supported OSes (Linux, FreeBSD, with all three the supported C libraries) are new enough to properly take care of that by themselves.