How are shared library dependency paths determined on Linux?

Kev picture Kev · Nov 17, 2011 · Viewed 7.9k times · Source

When I run ldd against a shared library such as libphp5.so I see that it has a dependency on libmysqlclient.so.16:

$ ldd ./libphp5.so
libmysqlclient.so.16 => /usr/lib/mysql/libmysqlclient.so.16 
[other dependencies snipped out]

Are these dependency filenames and paths (/usr/lib/mysql/libmysqlclient.so.16) baked into the shared library binary? Or is this path determined by some other means such as via /etc/ld.so.conf.d/mysql-i386.conf, which incidentally contains:

/usr/lib/mysql/

One other thing is puzzling me:

There is a shared library I have that I compile from source. This has a dependency on libmysqlclient_r. The gcc compiler switches to produce this this library look like:

gcc -shared -L/usr/lib/mysql -lmysqlclient_r [+various other switches]

When I do ldd mylib.so I see:

libmysqlclient_r.so.16 => /usr/lib/mysql/libmysqlclient_r.so.16 (0x0055c000)

However in the /usr/lib/mysql directory I see:

-rwxr-xr-x. libmysqlclient_r.so -> libmysqlclient_r.so.16.0.0
lrwxrwxrwx. libmysqlclient_r.so.16 -> libmysqlclient_r.so.16.0.0
-rwxr-xr-x. libmysqlclient_r.so.16.0.0
lrwxrwxrwx. libmysqlclient.so -> libmysqlclient.so.16.0.0
lrwxrwxrwx. libmysqlclient.so.16 -> libmysqlclient.so.16.0.0
-rwxr-xr-x. libmysqlclient.so.16.0.0

libmysqlclient_r.so is a symbolic link to libmysqlclient_r.so.16.0.0, so why does ldd show the dependency as libmysqlclient_r.so.16. Is there some magic I'm missing here?

Having been a Windows dev for many years I'm a bit new to gcc and development on Linux.

My Linux distribution is CentOS 6.0 x86-32bit.

Answer

Employed Russian picture Employed Russian · Nov 17, 2011

You can see which paths are coming from where by running

LD_DEBUG=libs ldd ./libphp5.so

Are these dependency filenames and paths (/usr/lib/mysql/libmysqlclient.so.16) baked into the shared library binary?

The filename almost certainly is. The path usually isn't. You can see what is baked into the binary with

readelf -d ./libphp5.so

Look for (NEEDED) and (RPATH) entries.

Also give man ld.so a read. There are many factors that affect how dynamic loader searches for shared libraries: ld.so.conf, LD_LIBRARY_PATH, whether the executable is suid or not, how glibc was configured, which -rpath settings were given at link time, etc. etc.