Directories Searched by the Runtime Linker
The runtime linker looks in two default locations for
dependencies. When processing 32-bit objects, the default
locations are /lib
and
/usr/lib
. When processing 64-bit
objects, the default locations are /lib/64
and
/usr/lib/64
. Any dependency specified
as a simple file name is prefixed with these default directory
names. The resulting path name is used to locate the actual
file.
The dependencies of a dynamic
object can be displayed using
ldd
(1). For example, the file
/usr/bin/cat
has the following
dependencies.
$ ldd /usr/bin/cat
libc.so.1 => /lib/libc.so.1
libm.so.2 => /lib/libm.so.2
The file /usr/bin/cat
has a dependency, or
needs, the files
libc.so.1
and
libm.so.2
.
The dependencies recorded in an object can be inspected
using
elfdump
(1). Use this command to display the
file's .dynamic
section, and look for entries
that have a NEEDED
tag. In the following example,
the dependency libm.so.2
, displayed in the
previous
ldd
(1) example, is not recorded in the file
/usr/bin/cat
.
ldd
(1) shows the total
dependencies of the specified file, and
libm.so.2
is actually a dependency of
/lib/libc.so.1
.
$ elfdump -d /usr/bin/cat
Dynamic Section: .dynamic:
index tag value
[0] NEEDED 0x211 libc.so.1
...
In the previous
elfdump
(1) example, the dependencies are
expressed as simple file names. In other words, there is no '/' in
the name. The use of a simple file name requires the runtime linker
to generate the path name from a set of default search rules. File
names that contain an embedded '/', are used as provided.
The simple file name recording is the standard, most
flexible mechanism of recording dependencies. The -h
option of the link-editor records a simple name within the
dependency. See Naming Conventions and Recording a Shared Object Name.
Frequently, dependencies are distributed in directories other than
/lib
and /usr/lib
,
or /lib/64
and
/usr/lib/64
. If a dynamic
object needs to locate dependencies in another directory, the
runtime linker must explicitly be told to search this
directory.
You can specify additional search path, on a per-object basis, by recording a runpath during the link-edit of an object. See Directories Searched by the Runtime Linker for details on recording this information.
A runpath recording can be displayed
using
elfdump
(1). Reference the
.dynamic
entry that has the
RUNPATH
tag. In the following example,
prog
has a dependency on
libfoo.so.1
. The runtime linker must
search directories /home/me/lib
and
/home/you/lib
before it looks in the
default location.
$ elfdump -d prog | egrep "NEEDED|RUNPATH"
[1] NEEDED 0x4ce libfoo.so.1
[3] NEEDED 0x4f6 libc.so.1
[21] RUNPATH 0x210e /home/me/lib:/home/you/lib
Another way to add to the runtime linker search path is
to set one of the LD_LIBRARY_PATH
family of
environment variables. This environment variable, which is analyzed
once at process startup, can be set to a colon-separated list of
directories. These directories are searched by the runtime linker
before any runpath specification or default
directory.
These environment variables are well suited to debugging purposes,
such as forcing an application to bind to a local dependency. In the
following example, the file prog
from the
previous example is bound to libfoo.so.1
, found
in the present working directory.
$ LD_LIBRARY_PATH=. prog
Although useful as a temporary mechanism of influencing the runtime
linker's search path, the use of LD_LIBRARY_PATH
is
strongly discouraged in production software. Any executables
that can reference this environment variable will have their search
paths augmented. This augmentation can result in an overall
degradation in performance. Also, as pointed out in Using an Environment Variable and Directories Searched by the Runtime Linker,
LD_LIBRARY_PATH
affects the
link-editor.
Environmental search paths can result in a 64-bit executable
searching a path that contains a 32-bit library that matches
the name being looked for. Or, the other way around. The runtime
linker rejects the mismatched 32-bit library and continues its
search looking for a valid 64-bit match. If no match is found,
an error message is generated. This rejection can be observed in
detail by setting the LD_DEBUG
environment variable
to include the files
token. See Runtime Linker Debugging Facility.
$ LD_LIBRARY_PATH=/lib/64 LD_DEBUG=files /usr/bin/ls
....
00283: file=libc.so.1; needed by /usr/bin/ls
00283:
00283: file=/lib/64/libc.so.1 rejected: ELF class mismatch: 32-bit/64-bit
00283:
00283: file=/lib/libc.so.1 [ ELF ]; generating link map
00283: dynamic: 0xef631180 base: 0xef580000 size: 0xb8000
00283: entry: 0xef5a1240 phdr: 0xef580034 phnum: 3
00283: lmid: 0x0
00283:
00283: file=/lib/libc.so.1; analyzing [ RTLD_GLOBAL RTLD_LAZY ]
....
If a dependency cannot be located,
ldd
(1) indicates that the object cannot be
found. Any attempt to execute the application results in an
appropriate error message from the runtime linker.
$ ldd prog libfoo.so.1 => (file not found) libc.so.1 => /lib/libc.so.1 libm.so.2 => /lib/libm.so.2 $ prog ld.so.1: prog: fatal: libfoo.so.1: open failed: No such file or directory