The direct (perhaps obvious) answer is that the search path for the libraries you are looking at with
ldd does not include the directories where the library's own dependencies are located. Normally, unless a library's dependencies are found in system-wide standard locations, the library should have been built with a run path specified (by using the environment variable
$LD_RUN_PATH or the appropriate linker option). Otherwise the libraries will not be found later on at run time, as you have found with
So why does Thunderbird work anyway despite this "problem"?
There are a few ways that the necessary libraries might be found anyway despite the missing run path:
- The environment variable
$LD_LIBRARY_PATH is set at run time and supplies a list of additional directories to search in.
- The necessary directory might have gotten included into the search path because it was found in the run path of some other unrelated library that happened to be loaded prior the the current one. By the way, I'm not sure if this works as an accident of implementation of if the standard specifies it. One way or the other, it is fragile because it crucially depends on the exact order in which libraries are loaded.
- The library might have been loaded manually by the application using the
dlopen() function given a full pathname.
Thunderbird appears to be using the last of those techniques. I looked at
strace output of what it does at startup and it seems to do this:
- Locate the directory where its own binary comes from. This is always possible because the shell script helper that launches Thunderbird does so with a full pathname.
- Open the text file
dependentlibs.list found in that directory.
- For each filename in this text file, in order, prepend the same directory to form a full path name, and load that as a library using
- Now all those dependent libraries like
libldap60.so which you mentioned are "preloaded", and other libraries that require them don't need to find them again.
Notice that the order or the files listed in
dependentlibs.list is significant.
The reason Thunderbird does this is so that the directory where it is located does not have to be hardcoded into either the application or into the run path of any of its internal libraries.
I don't know what Java does, but it is no doubt something similar.