Swiss Frank
Swiss Frank

Reputation: 2422

Shared library names have version extension that linker isn't looking for?

I have some shared libraries, most I believe installed via Red Hat packages: ncurses, cap, uuid, xml2.

[root@mycomputer~]# rpm -ql libuuid-2.23.2-43.el7_4.2.x86_64
/usr/lib64/libuuid.so.1
/usr/lib64/libuuid.so.1.3.0
/usr/share/doc/libuuid-2.23.2
/usr/share/doc/libuuid-2.23.2/COPYING

> l /usr/lib64/*uuid*
-rwxr-xr-x. 1 root root 20040 Nov  9  2017 /usr/lib64/libuuid.so.1.3.0
lrwxrwxrwx. 1 root root    16 Jul  3  2018 /usr/lib64/libuuid.so.1 -> libuuid.so.1.3.0

A vendor's example program's makefile has -luuid on the link line, and the linker complains:

/usr/bin/ld: cannot find -luuid

I run strace -f make ... >& makeout to capture all the system calls made by make and its descendant processes. -f means "follow child processes too.")

When I grep that output file for the string uuid I see it's never looking for a file with the .1 extension.

[pid 21920] open("/opt/nmr/sap/sybaseASE/sybclient-16.0.3-7/OCS-16_0/lib/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/opt/nmr/sap/sybaseASE/sybclient-16.0.3-7/OCS-16_0/lib/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib64/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib64/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/lib/../lib64/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/lib/../lib64/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib/../lib64/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib/../lib64/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/x86_64-redhat-linux/lib64/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/x86_64-redhat-linux/lib64/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib64/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib64/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/local/lib64/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/local/lib64/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/lib64/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/lib64/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/x86_64-redhat-linux/lib/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/x86_64-redhat-linux/lib/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/local/lib/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/local/lib/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/lib/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/lib/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib/libuuid.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 21920] open("/usr/lib/libuuid.a", O_RDONLY) = -1 ENOENT (No such file or directory)

I understand the mechanism of a soft link from a file like /usr/lib64/libuuid.so (without the .1 suffix) to a specific version, say, libuuid.so.1.3.0 The linker actually does a readlink(), I believe, to find out the ultimate file that libuuid.so points to, and embeds the target of that link libuuid.so.1.3.0 into the binary. That way, even should the "latest" version of uuid become 1.4.0 in the future, and libuuid.so be re-pointed to that new version, for example, this binary would still be linked with 1.3.0 at runtime.

But how is the compiler meant to get from libuuid.so to libuuid.so.1?

Upvotes: 0

Views: 349

Answers (1)

Chris Maes
Chris Maes

Reputation: 37792

you need to install libuuid-devel which contains:

/usr/lib64/libuuid.so -> libuuid.so.1.3.0

and the header files you probably need.

After compilation, your binary knows that he has been built with libuuid.so.1, so at execution he will not need libuuid.so but libuuid.so.1...

Upvotes: 3

Related Questions