The usual dynamic linker on Linux uses a cache to find its libraries. The cache is stored in /etc/ld.so.cache
, and is updated by ldconfig
which looks on the paths it’s given in /etc/ld.so.conf
(and nowadays typically files in /etc/ld.so.conf.d
). Its contents can be listed by running ldconfig -p
.
So there is no default value for LD_LIBRARY_PATH
, default library lookup doesn’t need it at all. If LD_LIBRARY_PATH
is defined, then it is used first, but doesn’t disable the other lookups (which also include a few default directories).
The ld.so(8)
manpage has the details:
If a shared object dependency does not contain a slash, then it is
searched for in the following order:
Using the directories specified in the DT_RPATH
dynamic section
attribute of the binary if present and DT_RUNPATH
attribute does
not exist. Use of DT_RPATH
is deprecated.
Using the environment variable LD_LIBRARY_PATH
, unless the
executable is being run in secure-execution mode (see below), in
which case it is ignored.
Using the directories specified in the DT_RUNPATH
dynamic section
attribute of the binary if present.
From the cache file /etc/ld.so.cache
, which contains a compiled
list of candidate shared objects previously found in the augmented
library path. If, however, the binary was linked with the -z nodeflib
linker option, shared objects in the default paths are
skipped. Shared objects installed in hardware capability
directories (see below) are preferred to other shared objects.
In the default path /lib
, and then /usr/lib
. (On some 64-bit
architectures, the default paths for 64-bit shared objects are
/lib64
, and then /usr/lib64
.) If the binary was linked with the
-z nodeflib
linker option, this step is skipped.
If LD_LIBRARY_PATH
is not set or is empty, it is ignored. If it is set to empty values (with LD_LIBRARY_PATH=:
for example), those empty values are interpreted as the current directory.