A recent email discussion reminded me of how fragile, and
prevalent, LD_LIBRARY_PATH use it. Within a
development environment, this variable is very useful. I use
it all the time to experiment with new libraries.
But within a production environment, use of this
environment variable can be problematic. See Directories Searched
by the Runtime Linker in the Linkers and Libraries Guide for an
overview of LD_LIBRARY_PATH use at runtime.
People use this environment variable to establish search paths for
applications whose dependencies do not reside in constant
locations. Sometimes wrapper scripts are employed to set this
variable, other times users maintain an LD_LIBRARY_PATH
within their .profile. This latter model can often get out of hand
- try running:
% ldd -s /usr/bin/date
...
find object=libc.so.1; required by /usr/bin/date
search path=/opt/ISV/lib (LD_LIBRARY_PATH)
If you have a large number of LD_LIBRARY_PATH components
specified, you'll see libc.so.1 being wastefully searched
for, until it is finally found in /usr/lib. Excessive
LD_LIBRARY_PATH components don't help application startup
performance.
Wrapper scripts attempt to compensate for inherited
LD_LIBRARY_PATH use. For example, a version of acroread
reveals:
LD_LIBRARY_PATH="`prepend "$ACRO_INSTALL_DIR/$ACRO_CONFIG/lib:\
$ACRO_INSTALL_DIR/$ACRO_CONFIG/lib" "$LD_LIBRARY_PATH"`
The script is prepending its LD_LIBRARY_PATH requirement
to any inherited definition. Although this provides the necessary
environment for acroread to execute, we're still wasting time
looking for any system libraries in the acroread
sub-directories.
When 64-bit binaries came along, we had a bit of a dilemma with
how to interpret LD_LIBRARY_PATH. But, because of its
popularity, it was decided to leave it applicable to both class of
binaries (64 and 32-bit), even though its unusual for a directory
to contain both 64 and 32-bit dependencies. We also added
LD_LIBRARY_PATH_64 and LD_LIBRARY_PATH_32 as a means
of specifying search paths that are specific to a class of objects.
These class specific environment variables are used instead
of any generic LD_LIBRARY_PATH setting.
Which leads me back to the recent email discussion. Seems a
customer was setting both the _64 and _32 variables
as part of their startup script, because both 64 and 32 bit
processes could be spawned. However, one spawned process was
acroread. Its LD_LIBRARY_PATH setting was being overridden
by the _32 variable, and hence it failed to execute.
Sigh.
Is there a solution to this mess? I guess we could keep bashing
LD_LIBRARY_PATH into submission some way, but why not get
rid of the LD_LIBRARY_PATH requirement altogether? This can
be done. Applications and dependencies can be built to include a
runpath using ld(1), and the -R option. This path is
used to search for the dependencies of the object in which the
runpath is recorded.
If the dependencies are not in a constant location, use the
$ORIGIN token as part of the pathname.
Is there a limitation to $ORIGIN use?
Yes, as directed by the security folks, expansion of this token
is not allowed for secure applications., But then again, for secure
applications, LD_LIBRARY_PATH components are ignored for
non-secure directories anyway.
For a flexible mechanism of finding dependencies, use a runpath
that includes the $ORIGIN token, and try not to create
secure applications :-)