use RPATH but not RUNPATH?

20,424

Solution 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.

Solution 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:

  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".

Solution 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.

Share:
20,424
zaharpopov
Author by

zaharpopov

Коммунизм!

Updated on December 21, 2021

Comments

  • zaharpopov
    zaharpopov over 2 years

    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?

  • zaharpopov
    zaharpopov over 12 years
    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 here
  • chill
    chill over 12 years
    @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.
  • zaharpopov
    zaharpopov over 12 years
    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 version
  • chill
    chill over 12 years
    @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.
  • vinc17
    vinc17 almost 7 years
    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=859732
  • Mecki
    Mecki over 4 years
    @vinc17 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.
  • vinc17
    vinc17 over 4 years
    @Mecki If you want the path to be overridable, then you can use DT_RUNPATH. There is no need to drop DT_RPATH.
  • Mecki
    Mecki over 4 years
    @vinc17 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.
  • vinc17
    vinc17 over 4 years
    @Mecki 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.
  • Mecki
    Mecki over 4 years
    @vinc17 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.
  • vinc17
    vinc17 over 4 years
    @Mecki 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.
  • shibormot
    shibormot over 2 years
    link dead, this works for now: akkadia.org/drepper/dsohowto.pdf