Creating relocatable Linux executables by setting RPATH with $ORIGIN

Luke Chen
3 min readJul 27, 2019

Lots of modern C/C++ projects leverage Autotools to create GNU building system e.g. generate make files based on the platform. Executable files (binaries) are generated during the make/compile process, and can be executed locally on the machine where the compilation is performed. However, if the same executable were moved onto a different machine, or simply a different folder on the same machine, the “library not found” error might be encountered while running the executable.

What is RPATH and $ORIGIN

RPATH stands for run-time search path. According to Wikipedia, “rpath designates the run-time search path hard-coded in an executable file or library. Dynamic linking loaders use the rpath to find required libraries.” Dynamic linking is a sort of “lazy” linking of required shared libraries not during the stage of compiling but the later stage of running one executable. A path to the shared libraries will be encoded into the header of the executable if rpath is set, overriding or supplementing the system default shared library searching paths, similar as one extends the chain of PATH system variable.

$ORIGIN is a special variable that indicate actual executable filename. It is resolved to where the executable is at run-time, and can be quite useful when setting RPATH.

How to check the value of RPATH/RUNPATH

There are various ways of checking the RPATH value for an executable or library. objdump, readelf and chrpath are 3 of the frequently used utilities.

$ objdump -x path/to/executable | grep RPATH

or

$ readelf -d path/to/executable | head -20

or

$ chrpath -l path/to/executable

RUNPATH, introduced after RPATH to make it easier to testing libraries (without needing to rebuild them every time), is gaining wider adoptions these days and making the latter obsolete. There’s another post covering more details on this topic. So don’t be surprised if an executable has RUNPATH instead of RPATH set.

Below screenshot provides an example of readelf output with RUNPATH and $ORIGIN:

“readelf” output with RUNPATH and $ORIGIN

--

--

Luke Chen

OpenSource & Automation make me excited. Release engineering @MongoDB