RPATH/RUNPATH issue, equivalent to -headerpad on OSX
Thu Jan 3 18:39:00 GMT 2008
this is my first mail to this list, so please be patient.
I am working on the build system for KDE4 and in KDE we are relying a lot on
A problem we have is that
-it is not possible to change the RPATH/RUNPATH inside an existing executable
-linking takes a lot of time
I am sure not only we (KDE) have this problem.
The issue is the following:
Let's say you have a project, which contains executables and shared libraries,
and the executables link to these shared libraries.
Let's also say that a previous version of the same project is already
installed on the system.
Now if you run the executables from the build directory, these executables
should link to the shared libraries in the build directory, i.e. not to the
shared libs installed on the system (since they don't represent the current
state of the project). Later on if you install the executables, the
RPATH/RUNPATH must not point to the build directory anymore.
With ELF files you have the following options to do that:
1) build the executables with RPATH to the build directory, and when
installing link them again with the modified RPATH for the install location
This works correctly and convenient, but it takes a lot of time (really a lot
for big projects).
2) build the executables without RPATH and with or without RUNPATH, and rely
on LD_LIBRARY_PATH. This means that if you want to run the executables from
the build tree, you have to make sure that the env. var. LD_LIBRARY_PATH is
set correctly. There are two ways to do that:
2a) manually. You don't want to do that. If you are working on different
projects with many shared libs you don't want to constantly call
environment-setup scripts or something like that, from time to time you will
forget that or mix it up or something.
2b) automatically create wrapper shell scripts for every executable which set
up LD_LIBRARY_PATH and then run the actual executable.
This approach doesn't work with RPATH, but works with RUNPATH. The problem
here is that it's inconvenient. The developer has to remember that he has to
run the shell script instead of the actual executable (e.g. myapp.sh instead
of myapp) and it is more work for the build system.
What would be nice would be if I could build everything with the RPATH/RUNPATH
pointing into the build tree, and when installing the project, I could just
change the RPATH/RUNPATH inside the executables. This takes (compared to
linking) almost no time, always the right libraries will be found and the
developers/users don't have to care about environment variables.
There is a tool called chrpath available which does that:
But this tool has a problem, it only works if the new RPATH is not longer than
the RPATH which is already in the ELF file (since it basically just patches
Since a few days CMake (http://www.cmake.org) supports chrpath, i.e. instead
of linking again when installing chrpath is used to modify the RPATH inside
the binaries. A workaround for the mentioned problem is implemented here: if
the RPATH for the install location is longer than the RPATH for the build
location, then the RPATH for the build location is padded with separator
characters. This works.
But of course it would be much nicer if there was an official way to do this.
On OSX there is the -headerpad <size> option for ld, which basically does just
that. So if you know that the RPATH for the install location is 200 byte
long, then you use -headerpad 200 and the linker will make sure that the
field for the instll name will be at least 200 byte long.
It would be nice if the ELF ld would offer a similar option,
e.g. -rpath-length=<size>, and then the RPATH field would have the specified
size. This would make it possible to safely modify the RPATH without
Maybe this would even make sense for binary distribution packages, where
(maybe) the install location could be selected and then the RPATH inside the
binaries of the package could be modified.
What do you think of that ?
More information about the Binutils