The runtime linker looks in one default location for dependencies. This location is /usr/lib when processing 32–bit objects, and /usr/lib/64 when processing 64–bit objects. Any dependency specified as a simple file name is prefixed with this default directory name. The resulting path name is used to locate the actual file.
The dependencies of a dynamic executable or shared 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 => /usr/lib/libc.so.1 libdl.so.1 => /usr/lib/libdl.so.1 |
The file /usr/bin/cat has a dependency, or needs, the files libc.so.1 and libdl.so.1.
The dependencies recorded in an object can be inspected using dump(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 libdl.so.1, 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 libdl.so.1 is actually a dependency of /usr/lib/libc.so.1.
$ dump -Lvp /usr/bin/cat /usr/bin/cat: [INDEX] Tag Value [1] NEEDED libc.so.1 ......... |
In the previous dump(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 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 /usr/lib or /usr/lib/64. If a dynamic executable or shared 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.
Any runpath recording can be displayed using dump(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.
$ dump -Lvp prog prog: [INDEX] Tag Value [1] NEEDED libfoo.so.1 [2] NEEDED libc.so.1 [3] RUNPATH /home/me/lib:/home/you/lib ......... |
Another way to add to the runtime linker's search path is to set the environment variable LD_LIBRARY_PATH
. 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 dynamic 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 matching the name being looked for. Or, vice versa. The runtime linker rejects
the mismatched 32–bit library and continues down its search path looking for a valid 64–bit match. If no match is found, an error message is generated. This can be observed in detail by setting
the LD_DEBUG
environment variable to include the files token. See Debugging Library.
$ LD_LIBRARY_PATH=/usr/bin/64 LD_DEBUG=files /usr/bin/ls ... 00283: file=libc.so.1; needed by /usr/bin/ls 00283: 00283: file=/usr/lib/64/libc.so.1 rejected: ELF class mismatch: \ 00283: 32-bit/64-bit 00283: 00283: file=/usr/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=/usr/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 => /usr/lib/libc.so.1 libdl.so.1 => /usr/lib/libdl.so.1 $ prog ld.so.1: prog: fatal: libfoo.so.1: open failed: No such file or directory |