On Linux, the ld.so(8)
man page discusses the search order for dynamic libraries. It says that DT_RPATH
is deprecated, and also mentions DT_RUNPATH
. There is no mention of the -rpath
linker option.
The ld(1)
man page mentions the -rpath
and -rpath-link
options, but never mentions DT_RPATH
or DT_RUNPATH
except in a describing the library search order, which of course does not match the information given in ld.so(8)
.
Finally there is an LD_RUN_PATH
environment variable. ld(1)
says it used if the -rpath
and -rpath-link
options are not set, but ld.so(8)
does not mention it.
My intuition is that -rpath
actually sets DT_RPATH
, and -rpath-link
sets DT_RUNPATH
, but I cannot find this confirmed anywhere. I have always used -rpath
; if it is the same as DT_RPATH
than I should not use it, but the how-to articles I've found on dynamic linking say to use it, so I'm not sure it's the same.
Could someone clarify how DT_RPATH
and DT_RUNPATH
are set, and whether they are the same as -rpath
and -rpath-link
?
When you are compiling a program, you create object files and then link them together. You may use GNU ld(1) to link them, there are also other linkers, LLVM linker. A linker combines object files into executable. GNU ld(1) is part of binutils with documentation available here.
When you execute an already compiled ready to use executable then the dynamic linker ld.so(8) finds the libraries on the system that the executable depends on, loads them and executes the executable. ld.so(8) is a shared library usually distributed as part of C standard library, usually on linux that's glibc, but there are also other, like musl.
I think it's confusing that both these programs are named "linker". One is like "compiling linker" and the other is "executable linker".
How do I set DT_RPATH or DT_RUNPATH?
Edit the elf file to include specific section.
When creating the elf file with GNU ld, nowadays you set RUNPATH section with -rpath=something
. You can set RPATH
section with --disable-new-dtags -rpath=something
. RPATH is deprecated, so normally -rpath
sets RUNPATH. https://www.javaer101.com/en/article/1127068.html *This does not check out on my system and I have to compile with gcc -Wl,--enable-new-dtags -Wl,-rpath=/tmp
to set RUNPATH...
You can also set sections in any ELF file after compilation. See Can I change 'rpath' in an already compiled binary?
whether they are the same as -rpath and -rpath-link?
From ld documentation:
The difference between -rpath and -rpath-link is that directories specified by -rpath options are included in the executable and used at runtime, whereas the -rpath-link option is only effective at link time.
And the documentation also explains how -rpath-link
works. It's to specify directories for searching dependent shared libraries.
Finally there is an LD_RUN_PATH environment variable
When compiling an executable GNU ld(1) also searches libraries in directories specified in this variable.
The -rpath
command line option used to create a DT_RPATH
entry in the .dynamic
section, but since DT_RPATH
was deprecated in favor of DT_RUNPATH
, modern linker versions use DT_RUNPATH
instead. This means that using -rpath
on a really old linker, you will create a dynamic section entry with .d_val = DT_RPATH
, but if your linker is up to date, you will create one with .d_val = DT_RUNPATH
instead.
The -rpath-link
option is an option which does not create any entry, but is used to supersede the DT_RUNPATH
entry present in the dynamic section of a library that is being linked. Therefore, when compiling, you should usually not need it. You can find more information on man 1 ld
(scroll down to -rpath-link=
) or in this other answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With