How do you specify the location of libraries to a binary? (linux)

34

14

For this question I'll be using a specific example, but really this generalizes to pretty much any binary on linux that can't seem to find its' dependent libraries. So, I have a program that won't run because of missing libraries:

./cart5: error while loading shared libraries: libcorona-1.0.2.so: cannot open shared object file: No such file or directory

ldd sheds some light on the issue:

linux-vdso.so.1 =>  (0x00007fff18b01000)
libcorona-1.0.2.so => not found
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/libstdc++.so.6 (0x00007f0975830000)
libm.so.6 => /lib/libm.so.6 (0x00007f09755af000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f0975399000)
libc.so.6 => /lib/libc.so.6 (0x00007f0975040000)
libz.so.1 => /lib/libz.so.1 (0x00007f0974e2b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0975b36000)

However, corona is installed:

oliver@human$ find / -name libcorona-1.0.2.so 2> /dev/null

/usr/local/lib64/libcorona-1.0.2.so
/home/oliver/installed/corona-1.0.2/src/.libs/libcorona-1.0.2.so

How do I tell the binary where to look for the "missing" library?

Mala

Posted 2010-09-25T07:40:25.023

Reputation: 5 998

Answers

43

For a once-off, set the variable LD_LIBRARY_PATH to a colon-separated list of directories to search. This is analogous to PATH for executables, except that the standard system directories are additionally searched after the ones specified through the environment.

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

If you have a program that keeps libraries in a non-standard location and isn't able to find them on its own, you can write a wrapper script:

#!/bin/sh
if [ -n "$LD_LIBRARY_PATH" ]; then
  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
else
  LD_LIBRARY_PATH=/usr/local/lib64
fi
export LD_LIBRARY_PATH
exec /path/to/cart5 "$@"

The list of standard system directories is kept in /etc/ld.so.conf. Recent systems allow this file to include other files; if yours contains something like include /etc/ld.so.conf.d/*.conf, create a new file called /etc/ld.so.conf.d/mala.conf containing the directories you want to add. After you change /etc/ld.so.conf or an included file, run /sbin/ldconfig for your changes to take effect (this updates a cache).

(LD_LIBRARY_PATH also applies to many other unices, including FreeBSD, NetBSD, OpenBSD, Solaris and Tru64. HP-UX has SHLIB_PATH and Mac OS X has DYLD_LIBRARY_PATH. /etc/ld.so.conf has analogs on most unices but the location and syntax differs more widely.)

Gilles 'SO- stop being evil'

Posted 2010-09-25T07:40:25.023

Reputation: 58 319

1Fantastic, thank you very much. I had no idea about /etc/ld.so.conf, and it will be very useful to me in the future. – Mala – 2010-09-26T06:26:45.333

15

If you want to avoid LD_LIBRARY_PATH, you can also do this, during linking:

gcc -o exename -L/path/to/dynamiclib/ -lnameofLib \
    -Wl,-R/path/to/dynamiclib/ sourceCode1.c ...

The -Wl,... is used to pass extra commands to the linker, and in this case, with -R you tell the linker to store this path as the "default search path" for the .so.

I keep notes of many small tips like this one, at my site:

https://www.thanassis.space/tricks.html

ttsiodras

Posted 2010-09-25T07:40:25.023

Reputation: 588

But if the library in question itself has shared libraries to look up, the rpath stored in the binary isn't applied recursively to the sub-library lookups. I haven't found a way around this other than setting LD_LIBRARY_PATH in the environment, which then does get applied to recursive lookups... – Ethan – 2017-05-27T18:56:10.713

@Ethan: True. But what's also true is that the usual scenarios where you want to "package" shared libraries for some binary, is one where you placed them all together; e.g. /opt/mypackage/bin/someBinary will need libs that you store in /opt/mypackage/lib/. Pretty much all proprietary SW installed under /opt follows this rule - which means that the way shown above will cover all such installs. They will then usually add also a symlink under /usr/bin that points to the binary under /opt - knowing that the "default search path" will find the .sos under the appropriate /opt/.../lib folder. – ttsiodras – 2017-05-28T20:08:11.720

yeah, in my case I was wanting to test a package by linking against its build directory rather than installing it... (but the package had several internal .so's with some inter-dependencies... variety of workarounds but just annoying) – Ethan – 2017-05-29T21:13:25.707

0

This indicates libcorona is not installed in the correct path. Move libcorona directory to the correct path, the issue will be resolved..

Rathi

Posted 2010-09-25T07:40:25.023

Reputation: 1

How is this better than other answers? – Toto – 2018-03-05T10:52:30.247

@Toto unlike the other answers, you're basically manually installing the files... Though that doesn't exactly mean this answer is better, but it IS an option that should be considered (people do this in Windows too by copying libraries to system32/sysWOW64 when their apps can't find them), not that it's recommended, because it's strongly discouraged. – Tcll – 2019-06-15T12:22:26.647