How do you specify the location of libraries to a binary? (linux)
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?
Solution 1:
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.)
Solution 2:
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