问题
This page - http://labs.qt.nokia.com/2011/10/28/rpath-and-runpath/ - says about order for library search in ld.so:
Unless loading object has RUNPATH:
RPATH of the loading object,
then the RPATH of its loader (unless it has a RUNPATH), ...,
until the end of the chain, which is either the executable
or an object loaded by dlopen
Unless executable has RUNPATH:
RPATH of the executable
LD_LIBRARY_PATH
RUNPATH of the loading object
ld.so.cache
default dirs
And then suggest:
When you ship binaries, either use RPATH and not RUNPATH or ensure LD_LIBRARY_PATH is set before they are run.
So, using RPATH
with RUNPATH
is bad because RUNPATH
kind-of cancels RPATH
so indirect dynamic loading doesn't work as expected? But why then RPATH
got deprecated in favor of RUNPATH
?
Can somebody explain the situation?
回答1:
When you ship a binary, it's good to provide means for the users to accommodate the binary to the specifics of their own system, among other things, adjusting library search paths.
A user can generally tweak LD_LIBRARY_PATH
and /etc/ld.so.conf
, both of which are with lower precedence than DT_RPATH
, i.e. you can't override what is hardcoded in the binary, whereas if you use DT_RUNPATH
instead, a user can override it with LD_LIBRARY_PATH
.
(FWIW, I think ld.so.conf
should also take precedence over DT_RUNPATH
, but, anyway, at least we've got LD_LIBRARY_PATH
).
Also, I strongly disagree with the suggestion above to use DT_RPATH
. IMO, its best to use nether DT_RPATH
not DT_RUNPATH
in shipped binaries.
unless
you ship all your dependent libraries with your executables and wish to ensure that things JustWork(tm) after installation, in this case use DT_RPATH
.
回答2:
Chill's answer is exactly right; I wanted to simply add some color, from a recent reading of the glibc source ([master 8b0ccb2], in 2.17). To be clear, if a library is not found in the location specified by a given level, the next level is tried. If a library is found at a given level, the search stops.
Dynamic Library Search Order:
- DT_RPATH in the ELF binary, unless DT_RUNPATH set.
- LD_LIBRARY_PATH entries, unless setuid/setgid
- DT_RUNPATH in ELF binary
- /etc/ld.so.cache entries, unless -z nodeflib given at link time
- /lib, /usr/lib unless -z nodeflib
- Done, "not found".
回答3:
But why then RPATH got deprecated in favor of RUNPATH?
When DT_RPATH was introduced, it had precedence over all other parameters. This made impossible to override the libraries search path even for development purposes. Therefore another parameter, LD_RUNPATH, was introduced that has lower precedence than LD_LIBRARY_PATH.
More details can be found in the "How to write shared libraries" work written by Ulrich Drepper.
来源:https://stackoverflow.com/questions/7967848/use-rpath-but-not-runpath