Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Set LD_LIBRARY_PATH and restart program

by runrig (Abbot)
on Aug 17, 2011 at 21:37 UTC ( [id://920804]=CUFP: print w/replies, xml ) Need Help??

I'm running into some of the same problems outlined in PATH is not setting - PERL and DBI, DBD::Oracle and LD_LIBRARY_PATH (problem summary: LD_LIBRARY_PATH and sometimes other environment variables need to be set/unset to certain values before the program starts in order to run correctly), so here is my solution to it. Comments welcome...
package FixInit; sub import { return if $ENV{FIXINIT_PM}; my $class = shift; my @chk = $^C ? '-c' : (); $ENV{FIXINIT_PM} = 1; my @path; while ( my $dir = shift @_ ) { last if $dir eq "--"; push @path, $dir; } $ENV{LD_LIBRARY_PATH} = join ":", @path; my %env = @_; $ENV{keys %env} = values %env; exec $^X => @chk, $0, @ARGV; die "Could not exec $^X $0: $!"; } 1; __END__ =head1 NAME FixInit - Fix library path and ENV variables and restart program =head1 SYNOPSIS # Before all other use statements use FixInit; # or use FixInit qw(libpath1 libpath2 -- env1 value1 env2 value2); =head1 DESCRIPTION LD_LIBRARY_PATH interferes with the path used when some libraries were compiled. It should only be used as a last resort. Setting LD_LIBRARY_PATH at runtime does no good, as it is already cached by the linker, so we set it, and restart the program with the original arguments. This library should be used before any other libraries to make sure it works correctly. An alternative would be to reset LD_LIBRARY_PATH and any environment variables in a shell wrapper, and then run your program from the wrapp +er. =cut

Replies are listed 'Best First'.
Re: Set LD_LIBRARY_PATH and restart program (improvements)
by tye (Sage) on Aug 18, 2011 at 04:01 UTC

    Usually you want these solutions to add directories to the path, not just overwrite the current list with a new list.

    As noted in the threads you mentioned, some versions of some operating systems notice that perl is exec'ing perl (itself) and then avoid repeating some of the work of loading dependencies. This can lead to this solution still not working.

    That is why some of the solutions previously provided did something like:

    exec "env", $^X, $0, @ARGV # ^^^^^ have perl exec env that execs perl

    - tye        

      In my case, I do want it to overwrite the path, because the 'default' environment "they" have picked for us has a bunch of crap in LD_LIBRARY_PATH, and I want shared lib paths to default to the path that the other shared libs were compiled under, not get overridden by LD_LIBRARY_PATH.

      E.g., (On Solaris) I've compiled a new libxml2 in a non-standard place, and compiled XML::LibXML against that new version. With LD_LIBRARY_PATH unset, it finds the right libxml2. If I leave LD_LIBRARY_PATH set, it finds the old version and complains. I've tried adding '-i' to the LDDLFLAGS when compiling XML::LibXML to try and say 'ignore LD_LIBRARY_PATH' (-R/path was already being used), but it doesn't seem to work, so this is my BandAid(tm).

      And it seems to work ok without the "env" (though if this were a universal portable solution, I'd put it in).

      Oh, and if you want to add paths instead of overwrite it, I'm sure you could just pass the current value of LD_LIBRARY_PATH in to the import list along with other paths.

      Update: AFAICT, my main issue seems to be that "they" decided to put "/usr/lib" in LD_LIBRARY_PATH, which, if my recent research has led me to a correct conclusion, is a bad bad thing.

Re: Set LD_LIBRARY_PATH and restart program
by runrig (Abbot) on Aug 19, 2011 at 23:44 UTC
    Here is a more flexible version that can remove paths or add paths to the beginning or end of the path (note: if you add to the beginning, they will be added in reverse order):
    sub import { return if $ENV{FIXINIT_PM}; my $class = shift; my @chk = $^C ? '-c' : (); $ENV{FIXINIT_PM} = 1; my @path = split /:/, $ENV{LD_LIBRARY_PATH}; while ( my $dir = shift @_ ) { last if $dir eq "--"; if ( $dir =~ s/^-// ) { if ($dir eq 'all') { @path = (); next; } @path = grep $_ ne $dir, @path; next; } if ( $dir =~ s/^\+// ) { unshift @path, $dir; next; } push @path, $dir; } $ENV{LD_LIBRARY_PATH} = join ":", @path; my %env = @_; $ENV{keys %env} = values %env; exec $^X => @chk, $0, @ARGV; die "Could not exec $^X $0: $!"; }
    New pod:
    =head1 SYNOPSIS # Use before all other use statements # Unset LD_LIBRARY_PATH use FixInit; # Add paths to end of LD_LIBRARY_PATH and set some variables # "--" divides paths and env variables use FixInit qw(libpath1 libpath2 -- env1 value1 env2 value2); # Add paths to beginning of LD_LIBRARY_PATH # (Will get added in reverse order) use FixInit qw(+libpath2 +libpath1); # Remove paths from LD_LIBRARY_PATH use FixInit qw(-libpath1 -libpath2);
Re: Set LD_LIBRARY_PATH and restart program
by elwarren (Priest) on Oct 05, 2011 at 19:38 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://920804]
Approved by ikegami
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-16 12:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found