Support for RPATH¶
Since EasyBuild v3.5.2, (stable) support is available for using RPATH.
What is RPATH?¶
RPATH is a mechanism to include a list of directories in a binary where
required shared libraries may be available. These locations are
considered by the dynamic loader (
ld*.so) to locate the libraries that
are required by a particular binary.
Hence, instructing the dynamic linker (
ld) to include RPATH entries in
a binary is an alternative to specifying library locations through
For more information on RPATH, see https://linux.die.net/man/8/ld-linux
Using RPATH can be interesting for a number of reasons:
- it can help to avoid a (too) large environment, since:
$LD_LIBRARY_PATHdoes not need to be set anymore for all dependencies providing libraries
- it leads to fewer runtime dependencies (and hence fewer modules need to be loaded)
- binaries can be used without problems w.r.t. resolving required libraries in other environments
- it may result in better startup performance, since
$LD_LIBRARY_PATHdoes not have to be iterated over
A minor downside is that it becomes less trivial to move installations of dependencies to a different location (which is something that you should not do without good reason anyway).
Enabling RPATH linking¶
To instruct EasyBuild to enable RPATH linking, use the
When EasyBuild is configured to use RPATH, wrapper scripts are put in
place for the dynamic linker commands (
ld.gold), as well as for
every compiler command that is part of the toolchain being used. This is
done during the
The wrapper scripts will analyze and rewrite the list of arguments supplied to the command they are wrapping as needed, i.e.:
- inject an
-rpathargument for every
-Largument that specifies a library directory (with some exceptions, see also Filtering RPATH entries via
- filter out arguments that affect RPATH (e.g.,
- ensure that the library subdirectories (
/lib64) of the installation directory also have an RPATH entry
- include additional arguments related to RPATH (e.g.
ps may show something like:
\_ /bin/bash /tmp/eb-M3393U/tmpRVJqwr/rpath_wrappers/gcc -O2 example.c -L/example -lexample | \_ /example/software/GCCcore/4.9.3/bin/gcc -Wl,-rpath=$ORIGIN/../lib -Wl,-rpath=$ORIGIN/../lib64 -Wl,--disable-new-dtags -Wl,-rpath=/example -O2 example.c -L/example -lexample
/tmp/eb-M3393U/tmpRVJqwr/rpath_wrappers/gcc is the wrapper
gcc, which tweaks the list of command line arguments for
gcc before calling out to the real
gcc command (i.e.,
/example/software/GCCcore/4.9.3/bin/gcc in this example).
RPATH wrapper script log files¶
When EasyBuild is used in debug mode (
--debug), the RPATH wrapper
script will generate log files in the temporary directory used by
EasyBuild, for debugging purposes:
$ ls -l /tmp/eb-_hoff5/rpath_wrapper*log | sed 's/vsc40023/example/g' -rw-rw-r-- 1 example example 739692 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_gcc.log -rw-rw-r-- 1 example example 27814 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_g++.log -rw-rw-r-- 1 example example 1589626 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_ld.gold.log -rw-rw-r-- 1 example example 8870 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_ld.log
These log files include details on every captured compiler/linker
command, i.e. the original list of arguments, the tweaked list of
arguments that includes the injected
-rpath arguments, etc., and may
be helpful to debug the RPATH support.
Overhead of RPATH wrapper scripts¶
Wrapping each compiler and linker command being executed comes at a
cost, especially since the wrapper (shell) script calls out to a Python
rpath_args.py) to do the heavy lifting.
Some early benchmarking has shown that this overhead is quite limited however, with observed slowdowns of the build and installation procedure of 10-15%.
Filtering RPATH entries via
To avoid that the wrapper scripts inject RPATH entries for particular
locations, EasyBuild can be configured with an RPATH filter via
The specified value should be a comma-separated list of (Python) regular expressions for paths. Only paths that match either of the specified patterns will be filtered out.
For example, to filter out locations in either
By default, no RPATH entries will be injected for system locations that
start with either
/usr (which is equivalent
If you are specifying
--rpath--filter, the default filter is overwritten,
so if you want to retain the filtering for system locations you
should also include
For example, to also filter out paths starting with
As mentioned above (Why RPATH?),
using RPATH avoids the need to update
$LD_LIBRARY_PATH for every
However, there is a chicken-or-egg situation: even though a particular dependency itself can be built and installed using RPATH, it does not mean that software packages that require it have to built with RPATH...
Hence, EasyBuild does not automatically exclude
update statements from the generated module files. You need to configure
EasyBuild to do so, using the
---filter-env-vars configuration option.
eb --rpath --filter-env-vars=LD_LIBRARY_PATH example.eb
To consistently configure EasyBuild to both use RPATH and not include
$LD_LIBRARY_PATH update statements in generated module files, you can
use either environment variables or a configuration file; see