GCC and RPATH
A well known issue1 with GCC is that it links with dynamic libraries it provides (libgcc_s.so.1
and libstdc++.so.6
for C++). Finding the right version of those libraries has to be arranged by the programmer or the user of the program. Obviously, Linux distributions arrange that for the version of GCC they provide, but if you are using a self-compiled GCC, the distribution provided library may or may not be compatible with your version of GCC, and even if it is that is not really useful if your goal is to test how your code behaves with that version of GCC.
One solution is to use the LD_LIBRARY_PATH
variable. That is not always convenient, and may be error-prone when working with several versions of GCC.
Another way is to record the path where to search dynamic libraries in the executable. That called RPATH or RUNPATH (the two are slightly different, see below). You can do that again in two ways: by specifying the arguments to GCC so that it does the registering or by modifying GCC’s specs file so that the argument are used automatically.
Passing explicitly argument to set the RPATH
g++ -Wl,-rpath=/path/to/correct/lib/dir -o prog obj1.o obj2.o ...
GCC Spec for RPATH
It is possible to have the argument be passed automatically by modifying the specs file.
First find the place where the specs file should be put by using:
gcc -print-search-dirs
Use the install one.
Change to that directory and dump the default content:
gcc -dumpspecs > specs
Edit the specs file to add
%{!static:%{!static-pie:-rpath=/path/to/the/libraries/lib/%M}}
at the start of the line following the one containing
*link_gcc_c_sequence:
With a recent GCC that’ll look like this:
*link_gcc_c_sequence: %{!static:%{!static-pie:-rpath=/usr/local/gcc-12.2/lib/%M}} %{static|static-pie:--start-group} %G %{!nolibc:%L} %{static|static-pie:--end-group}%{!static:%{!static-pie:%G}}
Difference between RPATH and RUNPATH
The ld.so
man page gives the full detail on how dynamic libraries are found. The major difference between RPATH and RUNPATH is that the RPATH is searched before the directories given by LD_LIBRARY_PATH while the RUNPATH is searched after. Note that you can’t easily give both using GNU ld, and that if you succeed in another way, the RPATH is ignored.
RUNPATH is specified in the same way as RPATH (thus with the -rpath
option to ld, so using -Wl,-rpath
with gcc) but with an additional argument --enable-new-dtags
which indicates that RUNPATH should be used instead (I don’t know what other effect it may have, I never saw any). There is a way to disable that settings if it is the default with --disable-new-dtags
(I’ve never noticed a ld so configured, but I’ve stopped to look for them and the difference between RPATH and RUNPATH is subtle enough that I may not have noticed).