Sample Header Ad - 728x90

Linux so convention: is the .so link intended to come from dev packages?

0 votes
0 answers
213 views
On my Ubuntu jammy Linux PC, after installing the libuv1 package (apt-get install libuv1), I noticed that there was a file, named libuv.so.1.0.0 and a symbolic link to it, named libuv.so.1:
$ find /usr -name "libuv.so*" 2>/dev/null
/usr/lib/x86_64-linux-gnu/libuv.so.1.0.0
/usr/lib/x86_64-linux-gnu/libuv.so.1
$ ls -l /usr/lib/x86_64-linux-gnu/libuv.so*
lrwxrwxrwx 1 root root     14 Jan 15  2022 /usr/lib/x86_64-linux-gnu/libuv.so.1 -> libuv.so.1.0.0
-rw-r--r-- 1 root root 198744 Jan 15  2022 /usr/lib/x86_64-linux-gnu/libuv.so.1.0.0
$
From probably incomplete understandings, I was expecting there to also be a libuv.so symbolic link, something like /usr/lib/x86_64-linux-gnu/libuv.so -> libuv.so.1. I've seen this mix of presence/absence of the .so symlink, but never properly understood if there was a reason/convention behind that. I thought I might have stumbled into The Answer in this blog post . If I correctly understand the content of that post: - semantic-versioned .so files, e.g. libfoo.so.1.0.0 are the real files that symlinks ultimately resolve to; they are compiled with the soname option, e.g. gcc -I . foo.c -shared -Wl,-soname=libfoo.so.1 -o libfoo.so.1.0.0. - Because of the use of the soname option, when a binary is compiled with -lfoo (in an environment where there exists libfoo.so -> libfoo.so.1 -> libfoo.so.1.0.0 links), the compiler/linker will look for libfoo.so, which resolves to libfoo.so.1.0.0, which has been compiled with -soname=libfoo.so.1, therefore the binary will know that it needs libfoo.so.1 at runtime. (i.e. readelf -d on the binary would output something like 0x0000000000000001 (NEEDED) Shared library: [libfoo.so.1]) - When the binary is run in an environment with only libfoo.so.1 -> libfoo.so.1.0.0 (i.e no libfoo.so -> libfoo.so.1), it will run fine: because of the above, it will be looking for libfoo.so.1, not libfoo.so. *My conjecture*: this seems to imply that only when you are _developing_ with a shared library will you need the libfoo.so symlink because of the need to specify the -l flag, e.g. g++ use-foo.cpp -o ./use-foo -lfoo. In this case, the use of -lfoo means the compiler/linker will be looking for libfoo.so, not libfoo.so.*. The above seems to bear out with compiling a simple hello-world example that links dynamically, and also inspecting what is installed with the libuv1 vs. libuv1-dev packages:
$ apt-file list libuv1 | grep so.*
libuv1: /usr/lib/x86_64-linux-gnu/libuv.so.1
libuv1: /usr/lib/x86_64-linux-gnu/libuv.so.1.0.0
$
$ apt-file list libuv1-dev | grep so.*
libuv1-dev: /usr/lib/x86_64-linux-gnu/libuv.so
$
But then a wrench was thrown into the works, when I found files, _not symlinks_, like libmemusage.so (I'm just picking one example, at random):
$ ls -l /usr/lib/x86_64-linux-gnu/libmemusage.so
-rw-r--r-- 1 root root 18904 Sep 25 07:45 /usr/lib/x86_64-linux-gnu/libmemusage.so
My question is: **is there one comprehensive rule that describes the relationship between libfoo.so, libfoo.so.x, and libfoo.so.x.y.z, when and why any specific combination of them should exist, and when and why any of them should be files vs. symbolic links?** Is there any case where I, as a non-developer Linux PC user, am supposed to create any "missing" symbolic link (as in the very beginning of the question, where I saw libuv.so.1 but not libuv.so)? (Context to this question: in the past, I've been asked to create a "missing" libfoo.so symlink, when libfoo.so.x and/or libfoo.so.x.y.z existed, but I never properly understood why this was necessary, other than a half-baked notion that "there's always a bunch of .so files, and they seem to have "corresponding" .so.x and .so.x.y.z files). --- (I can see the case that this question might belong at Stack Overflow: it's tangentially related to programming, but I ultimately thought that the heart of the question was about Unix/Linux conventions. But please let me know if it's certain that this question is better suited for Stack Overflow.)
Asked by StoneThrow (1937 rep)
Jan 5, 2024, 09:25 PM