Background: What LD_LIBRARY_PATH Does
LD_LIBRARY_PATH is an environment variable you set to give the run-time
shared library loader (ld.so) an extra set of directories to look for
when searching for shared libraries. Multiple directories can be listed,
separated with a colon (:). This list is prepended to the existing list
of compiled-in loader paths for a given executable, and any system
default loader paths.
The Problem: The perl Interperter Loads Shared Libraries Before A
Script Runs
You can't set LD LIBRARY PATH in a perl programm itself. This environment
variable only affects child processes of the process where you set it.
It helps if you remember that perl is the running process that has to
load shared libraries, not the Perl script. As a result, changes to
environment variables in the script don't necessarily help the loader
running for perl find the shared libraries. Most of the examples that
follow will focus on the Oracle shared libraries used by DBD::Oracle.
To expand slightly with details for Solaris as a specific example (Linux is
similar): perl XS libraries (such as DBI and DBD::Oracle) consist of a
shared object which is pulled in at run-time via dlopen(), which in turn is
an entry point into the run-time linker (ld.so.1). When you build
DBD::Oracle, the linker establishes a dependency between the Oracle.so
you generate when you build DBD::Oracle and the appropriate Oracle
library (libclntsh).
If you set LD_LIBRARY_PATH its value is added to the front of the RUNPATH
stored in any shared objects that are loaded However ld.so.1 only looks at
the value of LD_LIBRARY_PATH at process startup, and ld.so.1 actually runs
*before* the main() of your program - in this case the main() of the perl
interpreter. For this reason, setting LD_LIBRARY_PATH inside your perl
script will have no effect, as it will happen *after* ld.so.1 has already
read the value. If however the script sets LD_LIBRARY_PATH and then
re-execs itself, when ld.so.1 runs again it will see the value of
LD_LIBRARY_PATH in the environment and act accordingly.
Common Solutions: Managing Environment Variable LD_LIBRARY_PATH
I either set all my environment variables before starting Perl, or
set them in the script and then have it exec() itself. The following code
example illustrates setting LD_LIBRARY_PATH in a perl program and then
having it exec() itself again. This will work because exec() uses the same
same instance of the perl interpreter.
BEGIN
{
if (!defined($ENV{'ORACLE_HOME'}))
{
$ENV{'ORACLE_HOME'} = "/opt/ivas/oracle/product/8.1.6";
$ENV{'LD_LIBRARY_PATH'} = $ENV{'ORACLE_HOME'} . "/lib";
exec($^X, $0, @ARGV);
}
}
UNIX Operating System Solutions
Some OS's (e.g. Linux) have a configurable loader. You can configure what
run-time paths to look in by modifying /etc/ld.so.conf. Add the path to
/etc/ld.so.conf and then run ldconfig. This only needs to be done once,
and will make the libraries available to all processes. However, some
flavors of UNIX don't support /etc/ld.so.conf and, unfortunately, it
appears that Solaris does not support this.
Notes From Solaris Man Pages
Dynamic applications consist of one or more dynamic objects.
They are typically a dynamic executable and its shared
object dependencies. As part of the initialization and exe-
cution of a dynamic application, an interpreter is called to
complete the binding of the application to its shared object
dependencies. In Solaris, this interpreter is referred to as
the runtime linker.
During the link-editing of a dynamic executable, a special
.interp section, together with an associated program header,
is created. This section contains a pathname specifying the
program's interpreter. The pathname to the interpreter can
be specified when the executable is being constructed by the
-I option to ld(1) the link-editor. The default name sup-
plied by the link-editor is that of the runtime linker,
/usr/lib/ld.so.1.
The runtime linker performs the following functions:
o It opens and processes any applicable configuration
file. Configuration files may be employed to alter
default search paths, provide a directory cache and
provide alternative object dependencies. See crle(1).
By default, the configuration file /var/ld/ld.config
is used for 32-bit objects and /var/ld/64/ld.config
for 64-bit objects. Alternative configuration files
can be specified with the LD_CONFIG environment vari-
able, or encoded within a dynamic executable using the
-c option of ld(1).
The runtime linker uses a prescribed search path for locat-
ing the dynamic dependencies of an object. The default
search paths are the runpath recorded in the object, fol-
lowed by /usr/lib for 32-bit objects or /usr/lib/64 for 64-
bit objects. This latter component can be modified using a
configuration file created with crle(1). The runpath is
specified when the dynamic object is constructed using the
-R option to ld(1). LD_LIBRARY_PATH can be used to indicate
directories to be searched before the default directories.
Note on XS
The special language called XS is used to specify an interface between
a perl module and a C function that you want access to from within perl.
|