Library versions, SONAMEs,and symbol versions
Could someone please explain how library version numbers, shared object
names (SONAME), and symbol version are used in Debian?
I have a problem with libcurl.so.4 and a binary linked against it. In
Debian stretch I have the package libcurl3 installed and can run a
binary (I have no source code for it) linked against that libcurl.
Although the package is libcurl3, it installs libcurl.so.4.4.0, with
symlinks libcurl.so.4 and libcurl.so.3 pointing to it, and it has
SONAME libcurl.so.4. Many of the dynamic symbols are versioned as
CURL_OPENSSL3 e.g.:
$nm -D --with-symbol-versions /usr/lib/x86_64-linux-gnu/libcurl.so.4.4.0 | grep curl_easy_init
0000000000032430 T curl_easy_init@@CURL_OPENSSL_3
and that's what my binary needs:
$ readelf -a my-binary | grep NEEDED.*curl
0x0000000000000001 (NEEDED) Shared library: [libcurl.so.4]
$ nm -D --with-symbol-versions my-binary | grep curl_easy_init
U curl_easy_init@CURL_OPENSSL_3
In buster there is no libculr3 package but libcurl4, which installs
libcurl.so.4.5.0 which also has SONAME libcurl.so.4 but the symbol
versions have changed:
$ nm -D --with-symbol-versions libcurl.so.4.5.0 | grep curl_easy_init
000000000002f470 T curl_easy_init@@CURL_OPENSSL_4
That causes my-binary to fail because it doesn't find the needed
symbol curl_easy_init@CURL_OPENSSL_3 in libcurl.so.4.
So my questions are
- Why do many libraries have version numbers that don't match their
SONAME? I often find that confusing.
- Shouldn't a shared library's interface not change under any
circumstances unless it also changes its SONAME? AFAIUI, that's the
whole idea behind SONAME: Interface and/or behavior changes always
cause the SONAME to be changed.
If new versions of symbols like curl_easy_init@CURL_OPENSSL_4 are
introduced, the old one must be kept for compatibility,
i.e. curl_easy_init@CURL_OPENSSL_3.
Otherwise, it's not even possible to install an old version of the
library to make my-binary run. The problem is that the old library
would need to change the symlink libcurl.so.4 to point to the old
shared library file. And again, I think this kills the main idea of
SONAMEs.
- Given that some libraries don't do it that way, is there a way to
run a binary with ignoring the symbol versions? I.e. I assuming that
the function curl_easy_init@CURL_OPENSSL_4 will work with my-binary,
can I run it using that new symbol instead of the old one, i.e. don't
care about the symbol version?
Steve
Reply to: