Brettin Consulting  


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.