Shared libraries (under Linux)
On computers a library is a collection of code that can be used by other programs. There are static and shared libraries. Software that was built with static libraries can be used standalone, while shared libraries create dependences, because their code needs to be loaded dynamically at runtime.
A great advantage of shared libraries is simplified code maintenance, a disadvantage are dependence issues which sometimes are experienced as dependency hell.
Shared library search path
Practical issues with shared libraries are that they must be
installed on the computer one is using and that the software that
depends on them must find them. The shared library search path for all
software that can be installed within a Linux distrubution is definded
in /etc/ld.so.conf. On HPC system that search path
regularly needs to be extended for software that is installed outside
the Linux distribution. The search path can be extended by two
methods:
- the software knows where its libraries are (i.e. it has RPATH or RUNPATH burnt-in, see below, which can be achieved if the software was built of the HPC system itself,
 - the search path can be extended via the environment variable LD_LIBRARY_PATH (which is easy but should be used with care, see below).
 
$LD_LIBRARY_PATH
The first thing to note about LD_LIBRARY_PATH is that setting it globally can have side effects: (all kinds of) software might crash or behave differently than before because of changes in libraries. A crash is the nicer possiblility because it is clear that something went wrong. Different behaviour can mean irreproducibility of even wrong results which might not be noticed.
Recommendations
Setting LD_LIBRARY_PATH should be avoided.
A clean way is to specify LD_LIBRARY_PATH before the actual command on a single command-line (it will then only affect that command):
$LD_LIBRARY_PATH=... ./a.out
Alternatively, LD_LIBRARY_PATH can be set in wrapper scripts.
RPATH and RUNPATH
A method preferable over LD_LIBRARY_PATH is to set the search path via RPATH or RUNPATH. This happens when software is built. The difference between RPATH and RUNPATH is that LD_LIBRARY_PATH takes predence over RUNPATH while RPATH remains unaffected.
$LD_RUN_PATH
This section is relevant for building software.
If the environment variable LD_RUN_PATH is set at link-time it will
be used to generate RPATH or RUNPATH entries. This will only happen if
the loader option -rpath ist not set. Otherwise
LD_RUN_PATH is ignored. In the latter case one can still add LD_RUN_PATH
with the (GNU) compiler option
-Wl,-rpath="$LD_RUN_PATH".
According to the loader man-page (man ld) RPATH entries
are generated by default. RUNPATH entries are generated if the loader
option --enable-new-dtags is set (but to our experience
this is not always the case). Setting RPATH can be enforced with the
loader option --disable-new-dtags.
Below is recipe for compiling without LD_LIBRARY_PATH. Assume that LD_LIBRARY_PATH is set in the environment you are working with and that LIBRARY_PATH and LD_RUN_PATH are not set. Then one can set LIBRARY_PATH and LD_RUN_PATH and remove LD_LIBRARY_PATH. In addition it is indicated how loader flags can be set it the build enviroment uses the LDFLAGS variable.
$export LIBRARY_PATH=$LD_LIBRARY_PATH$export LD_RUN_PATH=$LD_LIBRARY_PATH$export LDFLAGS="-Wl,-rpath='$LD_RUN_PATH' -Wl,--disable-new-dtags"$unset LD_LIBRARY_PATH
The effect should be that LD_LIBRARY_PATH is not needed when running the software built, which would have been necessary otherwise.