Skip to content

Commit f89ff95

Browse files
committed
ported
1 parent 0b36c36 commit f89ff95

File tree

1 file changed

+135
-132
lines changed

1 file changed

+135
-132
lines changed

docs/rpath-support.md

+135-132
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,157 @@
1-
.. _rpath_support:
2-
3-
Support for RPATH
4-
=================
1+
# Support for RPATH {: #rpath_support }
52

63
Since EasyBuild v3.5.2, (stable) support is available for using RPATH.
74

8-
.. contents::
9-
:depth: 3
10-
:backlinks: none
11-
12-
13-
.. _rpath_support_what:
14-
15-
What is RPATH?
16-
--------------
17-
18-
RPATH is a mechanism to include a list of directories in a binary where required shared libraries may be available.
19-
These locations are considered by the dynamic loader (``ld*.so``) to locate the libraries that are required by a particular binary.
5+
## What is RPATH? {: #rpath_support_what }
206

21-
Hence, instructing the dynamic linker (``ld``) to include RPATH entries in a binary is an alternative to specifying library locations
22-
through ``$LD_LIBRARY_PATH``.
7+
RPATH is a mechanism to include a list of directories in a binary where
8+
required shared libraries may be available. These locations are
9+
considered by the dynamic loader (`ld*.so`) to locate the libraries that
10+
are required by a particular binary.
2311

24-
For more information on RPATH, see https://linux.die.net/man/8/ld-linux
12+
Hence, instructing the dynamic linker (`ld`) to include RPATH entries in
13+
a binary is an alternative to specifying library locations through
14+
`$LD_LIBRARY_PATH`.
2515

16+
For more information on RPATH, see
17+
<https://linux.die.net/man/8/ld-linux>
2618

27-
.. _rpath_support_why:
28-
29-
Why RPATH?
30-
----------
19+
## Why RPATH? {: #rpath_support_why }
3120

3221
Using RPATH can be interesting for a number of reasons:
3322

34-
* it can help to avoid a (too) large environment, since:
35-
36-
* ``$LD_LIBRARY_PATH`` does not need to be set anymore for all dependencies providing libraries
37-
* it leads to fewer runtime dependencies (and hence fewer modules need to be loaded)
38-
39-
* binaries can be used without problems w.r.t. resolving required libraries in other environments
40-
41-
* it may result in better startup performance, since ``$LD_LIBRARY_PATH`` does not have to be iterated over
42-
43-
A minor downside is that it becomes less trivial to move installations of dependencies to a different location
44-
(which is something that you should not do without good reason anyway).
45-
46-
47-
.. _rpath_support_enable:
48-
49-
Enabling RPATH linking
50-
----------------------
51-
52-
To instruct EasyBuild to enable RPATH linking, use the ``--rpath`` configuration option.
53-
54-
55-
.. _rpath_support_implementation:
56-
57-
Implementation
58-
--------------
59-
60-
When EasyBuild is configured to use RPATH, wrapper scripts are put in place for the dynamic linker commands (``ld``, ``ld.gold``),
61-
as well as for every compiler command that is part of the toolchain being used. This is done during the ``prepare`` step.
62-
63-
The wrapper scripts will analyze and rewrite the list of arguments supplied to the command they are wrapping as needed, i.e.:
64-
65-
* inject an ``-rpath`` argument for every ``-L`` argument that specifies a library directory (with some exceptions, see also :ref:`rpath_support_filtered_paths`)
66-
* filter out arguments that affect RPATH (e.g., ``--enable-new-dtags``)
67-
* ensure that the library subdirectories (``lib``, ``/lib64``) of the installation directory also have an RPATH entry
68-
* include additional arguments related to RPATH (e.g. ``--disable-new-dtags``)
69-
70-
As such, ``ps`` may show something like::
71-
72-
\_ /bin/bash /tmp/eb-M3393U/tmpRVJqwr/rpath_wrappers/gcc -O2 example.c -L/example -lexample
73-
| \_ /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
74-
75-
Here, ``/tmp/eb-M3393U/tmpRVJqwr/rpath_wrappers/gcc`` is the wrapper script for ``gcc``,
76-
which tweaks the list of command line arguments for ``gcc``
77-
before calling out to the real ``gcc`` command (i.e., ``/example/software/GCCcore/4.9.3/bin/gcc`` in this example).
78-
79-
.. _rpath_support_impl_logs:
80-
81-
RPATH wrapper script log files
82-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83-
84-
When EasyBuild is used in debug mode (``--debug``), the RPATH wrapper script will generate log files in
85-
the temporary directory used by EasyBuild, for debugging purposes::
86-
87-
$ ls -l /tmp/eb-_hoff5/rpath_wrapper*log | sed 's/vsc40023/example/g'
88-
-rw-rw-r-- 1 example example 739692 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_gcc.log
89-
-rw-rw-r-- 1 example example 27814 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_g++.log
90-
-rw-rw-r-- 1 example example 1589626 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_ld.gold.log
91-
-rw-rw-r-- 1 example example 8870 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_ld.log
92-
93-
These log files include details on every captured compiler/linker command, i.e. the original list of arguments,
94-
the tweaked list of arguments that includes the injected ``-rpath`` arguments, etc., and may be helpful to debug the RPATH support.
95-
96-
.. _rpath_support_impl_overhead:
97-
98-
Overhead of RPATH wrapper scripts
99-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
100-
101-
Wrapping each compiler and linker command being executed comes at a cost,
102-
especially since the wrapper (shell) script calls out to a Python script (``rpath_args.py``) to do the heavy lifting.
103-
104-
Some early benchmarking has shown that this overhead is quite limited however,
105-
with observed slowdowns of the build and installation procedure of 10-15%.
106-
107-
108-
.. _rpath_support_filtered_paths:
109-
110-
Filtering RPATH entries via ``--rpath-filter``
111-
----------------------------------------------
112-
113-
To avoid that the wrapper scripts inject RPATH entries for particular locations,
114-
EasyBuild can be configured with an RPATH filter via ``--rpath-filter``.
115-
116-
The specified value should be a comma-separated list of (Python) regular expressions for paths.
117-
Only paths that *match* either of the specified patterns will be filtered out.
118-
119-
For example, to filter out locations in either ``/opt/lib`` or ``/apps/lib``, use::
120-
121-
eb --rpath-filter='/opt/lib.*,/apps/lib.*'
122-
123-
By default, no RPATH entries will be injected for system locations
124-
that start with either ``/lib`` (incl. ``/lib64``) or ``/usr``
125-
(which is equivalent with ``--rpath-filter='/lib.*,/usr.*'``).
23+
- it can help to avoid a (too) large environment, since:
24+
- `$LD_LIBRARY_PATH` does not need to be set anymore for all
25+
dependencies providing libraries
26+
- it leads to fewer runtime dependencies (and hence fewer modules
27+
need to be loaded)
28+
- binaries can be used without problems w.r.t. resolving required
29+
libraries in other environments
30+
- it may result in better startup performance, since
31+
`$LD_LIBRARY_PATH` does not have to be iterated over
12632

127-
.. note:: If you are specifying ``--rpath--filter``, the default filter is *overwritten*,
128-
so if you want to retain the filtering for system locations you should also
129-
include ``/lib.*`` and ``/usr.*``.
33+
A minor downside is that it becomes less trivial to move installations
34+
of dependencies to a different location (which is something that you
35+
should not do without good reason anyway).
13036

131-
For example, to also filter out paths starting with ``/example``::
37+
## Enabling RPATH linking {: #rpath_support_enable }
13238

133-
eb --rpath-filter='/lib.*,/usr.*,/example.*'
39+
To instruct EasyBuild to enable RPATH linking, use the `--rpath`
40+
configuration option.
41+
42+
## Implementation {: #rpath_support_implementation }
13443

44+
When EasyBuild is configured to use RPATH, wrapper scripts are put in
45+
place for the dynamic linker commands (`ld`, `ld.gold`), as well as for
46+
every compiler command that is part of the toolchain being used. This is
47+
done during the `prepare` step.
13548

136-
.. _rpath_support_LD_LIBRARY_PATH:
49+
The wrapper scripts will analyze and rewrite the list of arguments
50+
supplied to the command they are wrapping as needed, i.e.:
13751

138-
Relation to ``$LD_LIBRARY_PATH``
139-
--------------------------------
52+
- inject an `-rpath` argument for every `-L` argument that specifies a
53+
library directory (with some exceptions, see also
54+
[Filtering RPATH entries via `--rpath-filter`][rpath_support_filtered_paths])
55+
- filter out arguments that affect RPATH (e.g., `--enable-new-dtags`)
56+
- ensure that the library subdirectories (`lib`, `/lib64`) of the
57+
installation directory also have an RPATH entry
58+
- include additional arguments related to RPATH (e.g.
59+
`--disable-new-dtags`)
60+
61+
As such, `ps` may show something like:
62+
63+
``` console
64+
\_ /bin/bash /tmp/eb-M3393U/tmpRVJqwr/rpath_wrappers/gcc -O2 example.c -L/example -lexample
65+
| \_ /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
66+
```
67+
68+
Here, `/tmp/eb-M3393U/tmpRVJqwr/rpath_wrappers/gcc` is the wrapper
69+
script for `gcc`, which tweaks the list of command line arguments for
70+
`gcc` before calling out to the real `gcc` command (i.e.,
71+
`/example/software/GCCcore/4.9.3/bin/gcc` in this example).
72+
73+
### RPATH wrapper script log files {: #rpath_support_impl_logs }
74+
75+
When EasyBuild is used in debug mode (`--debug`), the RPATH wrapper
76+
script will generate log files in the temporary directory used by
77+
EasyBuild, for debugging purposes:
78+
79+
``` console
80+
$ ls -l /tmp/eb-_hoff5/rpath_wrapper*log | sed 's/vsc40023/example/g'
81+
-rw-rw-r-- 1 example example 739692 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_gcc.log
82+
-rw-rw-r-- 1 example example 27814 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_g++.log
83+
-rw-rw-r-- 1 example example 1589626 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_ld.gold.log
84+
-rw-rw-r-- 1 example example 8870 Nov 16 15:50 /tmp/eb-_hoff5/rpath_wrapper_ld.log
85+
```
86+
87+
These log files include details on every captured compiler/linker
88+
command, i.e. the original list of arguments, the tweaked list of
89+
arguments that includes the injected `-rpath` arguments, etc., and may
90+
be helpful to debug the RPATH support.
91+
92+
### Overhead of RPATH wrapper scripts {: #rpath_support_impl_overhead }
93+
94+
Wrapping each compiler and linker command being executed comes at a
95+
cost, especially since the wrapper (shell) script calls out to a Python
96+
script (`rpath_args.py`) to do the heavy lifting.
97+
98+
Some early benchmarking has shown that this overhead is quite limited
99+
however, with observed slowdowns of the build and installation procedure
100+
of 10-15%.
101+
102+
## Filtering RPATH entries via `--rpath-filter` {: #rpath_support_filtered_paths }
103+
104+
To avoid that the wrapper scripts inject RPATH entries for particular
105+
locations, EasyBuild can be configured with an RPATH filter via
106+
`--rpath-filter`.
107+
108+
The specified value should be a comma-separated list of (Python) regular
109+
expressions for paths. Only paths that *match* either of the specified
110+
patterns will be filtered out.
111+
112+
For example, to filter out locations in either `/opt/lib` or
113+
`/apps/lib`, use:
114+
115+
``` shell
116+
eb --rpath-filter='/opt/lib.*,/apps/lib.*'
117+
```
118+
119+
By default, no RPATH entries will be injected for system locations that
120+
start with either `/lib` (incl. `/lib64`) or `/usr` (which is equivalent
121+
with `--rpath-filter='/lib.*,/usr.*'`).
122+
123+
!!! note
124+
If you are specifying `--rpath--filter`, the default filter is *overwritten*,
125+
so if you want to retain the filtering for system locations you
126+
should also include `/lib.*` and `/usr.*`.
127+
For example, to also filter out paths starting with `/example`:
140128

141-
As mentioned above (:ref:`rpath_support_why`), using RPATH avoids the need to update ``$LD_LIBRARY_PATH`` for every dependency.
129+
``` shell
130+
eb --rpath-filter='/lib.*,/usr.*,/example.*'
131+
```
142132

143-
However, there is a chicken-or-egg situation: even though a particular dependency itself can be built and installed using RPATH,
144-
it does not mean that software packages that require it *have* to built with RPATH...
133+
## Relation to `$LD_LIBRARY_PATH` {: #rpath_support_LD_LIBRARY_PATH }
145134

146-
Hence, EasyBuild does not automatically exclude ``$LD_LIBRARY_PATH`` update statements from the generated module files.
147-
You need to configure EasyBuild to do so, using the ``---filter-env-vars`` configuration option.
135+
As mentioned above ([Why RPATH?][rpath_support_why]),
136+
using RPATH avoids the need to update `$LD_LIBRARY_PATH` for every
137+
dependency.
148138

149-
For example::
139+
However, there is a chicken-or-egg situation: even though a particular
140+
dependency itself can be built and installed using RPATH, it does not
141+
mean that software packages that require it *have* to built with
142+
RPATH...
150143

151-
eb --rpath --filter-env-vars=LD_LIBRARY_PATH example.eb
144+
Hence, EasyBuild does not automatically exclude `$LD_LIBRARY_PATH`
145+
update statements from the generated module files. You need to configure
146+
EasyBuild to do so, using the `---filter-env-vars` configuration option.
152147

153-
To consistently configure EasyBuild to both use RPATH and not include ``$LD_LIBRARY_PATH`` update statements in generated
154-
module files, you can use either environment variables or a configuration file; see :ref:`configuring_easybuild`.
148+
For example:
149+
150+
``` shell
151+
eb --rpath --filter-env-vars=LD_LIBRARY_PATH example.eb
152+
```
153+
154+
To consistently configure EasyBuild to both use RPATH and not include
155+
`$LD_LIBRARY_PATH` update statements in generated module files, you can
156+
use either environment variables or a configuration file; see
157+
[Configuring EasyBuild][configuring_easybuild].

0 commit comments

Comments
 (0)