use RPATH but not RUNPATH?
Asked Answered
B

3

46

This page 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 suggests:

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?

Botnick answered 1/11, 2011 at 14:18 Comment(1)
I found this article from cmake's handling of RPATH/RUNPATH informative, so leave it here for the next googlerRabiah
I
49

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 neither DT_RPATH nor 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.

Ingar answered 6/11, 2011 at 15:13 Comment(4)
problem is, RUNPATH is recommended over RPATH, and RPATH is deprecated, but RUNPATH is currently not supported by all systems. so what I do today to make application work? as Qt article show, when using plugins it is useful to use RPATH more than RUNPATH. so the whole situation is very confusing hereBotnick
@zaharpopov, The best approach I would recommend and follow myself is to produce applications which are nicely integrated in the target platform, which would include, among other things, not distributing competing versions of the platform's shared libraries. I think this is the root of the problem and hacks and slashes around DT_RPATH and friends are an ill-directed effort trying to side-step the problem instead of solving it.Ingar
this not simple. with Qt problem was the app wants newer version of Qt libs than exist on system. some systems have outdated Qt SOs, so what would you do then? i think it make sense distribute Qt SOs with you if you need a specific versionBotnick
@zaharpopov, yes, it may make sense for the application vendors, which are generally concerned only with their own application and not with the big picture. But it does not make sense from the point of view of system vendors and integrators and it's them who deprecated DT_RPATH.Ingar
G
38

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:

  1. DT_RPATH in the ELF binary, unless DT_RUNPATH set.
  2. LD_LIBRARY_PATH entries, unless setuid/setgid
  3. DT_RUNPATH in ELF binary
  4. /etc/ld.so.cache entries, unless -z nodeflib given at link time
  5. /lib, /usr/lib unless -z nodeflib
  6. Done, "not found".
Gala answered 4/6, 2013 at 16:21 Comment(0)
O
18

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.

Ovid answered 28/1, 2014 at 14:51 Comment(8)
This answer explains the need for DT_RUNPATH, but not why DT_RPATH is deprecated. Both have their own usage, and DT_RUNPATH breaks libtool when LD_LIBRARY_PATH is used: bugs.debian.org/cgi-bin/bugreport.cgi?bug=859732Prosaic
@Prosaic One reason for deprecation could be that the behavior of DT_RPATH to not be overridable is generally undesired. It has to work that way for compatibility reasons, thus if the behavior cannot be changed as desired, it will be removed instead and first step is to deprecate it.Burgh
@Burgh If you want the path to be overridable, then you can use DT_RUNPATH. There is no need to drop DT_RPATH.Prosaic
@Prosaic There is, if you don't want to have anything that is not overridable as DT_RPATH isn't and that cannot be changed anymore, so it can only be dropped and removed. That's exactly what I already explained in my fist comment. You say "you have the choice" but this choice is maybe not desired as it may have security implications for example.Burgh
@Burgh What you're saying does not make any sense. I repeat: If you want the path to be overridable, use DT_RUNPATH. And the choice is desired as there are cases where DT_RUNPATH will just break. And there are obviously no security implications with the choice.Prosaic
@Prosaic It's not about me wanting something to be overriable, it's about the Linux developers (those people developing Linux itself!) not wanting that something exists which isn't overridable and RT_PATH is not overridable, thus it must stop existing. If you don't get that, then I can't help you. I'm pretty sure every other reader here understands what I'm saying.Burgh
@Burgh They could make DT_RPATH overridable by some other environment variable (well, I think that LD_PRELOAD can already be used for that, but with drawbacks). Alternatively, they could introduce a new environment variable that would have a lower precedence than DT_RUNPATH (thus the user could use that instead of LD_LIBRARY_PATH). Both would solve the issue with libtool.Prosaic
link dead, this works for now: akkadia.org/drepper/dsohowto.pdfSchear

© 2022 - 2024 — McMap. All rights reserved.