Search code examples
clinuxgccshared-librariesdynamic-linking

use RPATH but not RUNPATH?


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?


Solution

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