Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

(tye)Re: programatically setting the LD_LIBRARY_PATH

by tye (Sage)
on Nov 20, 2001 at 23:13 UTC ( [id://126587]=note: print w/replies, xml ) Need Help??

in reply to programatically setting the LD_LIBRARY_PATH

Note that doing a Super Search for articles that mention LD_LIBRARY_PATH might have gotten you enough information to get past this problem. I didn't find the answer neatly wrapped up (but I only looked at a couple of the hits), though, so here is one...

You likely can't set LD_LIBRARY_PATH from within the running process no matter how early you do it as the linker/loader has already started loading the process and has cached the value of LD_LIBRARY_PATH. Previously I've work around this by execing the perl executable so that it must reload and will see the new LD_LIBRARY_PATH that I have set. On some operating systems, even that isn't enough as the linker/loader notices that we are execing the same executable and doesn't bother to reinitialize. For such cases, you have to exec a different executable and ask it to exec perl for you.

Something close to the following should work:

BEGIN { my $need= '/usr/local/sybase/lib'; my $ld= $ENV{LD_LIBRARY_PATH}; if( ! $ld ) { $ENV{LD_LIBRARY_PATH}= $need; } elsif( $ld !~ m#(^|:)\Q$need\E(:|$)# ) { $ENV{LD_LIBRARY_PATH} .= ':' . $need; } else { $need= ""; } if( $need ) { exec 'env', $^X, $0, @ARGV; } }

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: (tye)Re: programatically setting the LD_LIBRARY_PATH
by GhodMode (Pilgrim) on Apr 08, 2004 at 13:16 UTC

    This is an old thread, but I've often had reason to refer back to it. Hopefully someone will also find the following useful.

    Tye's solution works perfectly. It seems to be the best solution for cron jobs on a server with a diverse environment. The only problem is the the BEGIN block sort of breaks the use of perl -c and perl -d. If I understand correctly, it's because those options sort of wrap the existing code in code that will just compile or debug the existing code.

    The following works, but only if the environment variables don't need to be set before the modules are loaded. Naturally, on a Windows system you will need to find an alternative method of determining an interactive shell...

    my $interactive = TRUE if ( ! system( 'tty -s' ) / 256 ); unless ($interactive) { unless ( $ENV{BEGIN_BLOCK} ) { $ENV{"ORACLE_HOME"} = '/opt/oracle/product/9.2.0'; $ENV{"LD_LIBRARY_PATH"} = '/opt/oracle/product/9.2.0/lib'; $ENV{BEGIN_BLOCK} = 1; exec 'env',$0,@ARGV; } }

    Credit for this goes to one of my (non-perlmonk) co-workers. I'm just taking the credit :D I've been using a variation of Tye's code until now.

    -- GhodMode
      If you're doing this because a Perl module has a dependency on a native library (e.g. XML::LibXML), and you need to load the library from a non-default path (e.g. you have a version of libxml2 not in /lib or /usr/lib) and you want to avoid modifying LD_LIBRARY_PATH in a wrapper script or some kind of pseudo-wrapper like that shown above, there is another alternative. In the .bs file for the module, place a call to dl_load_file passing the absolute name of the native library. I used an environment variable to store my custom library path:
      # Need to find libxml2. Cannot set LD_LIBRARY_PATH as it is already # cached by the linker. So we load libxml2 BEFORE loading # XML::LibXML's library. dl_load_file($ENV{FOO_PATH} . '/lib/os/');
        I was hoping I could use this if LD_LIBRARY_PATH was already set and it was finding the wrong version of the library in the path. Alas, it still finds and loads the wrong version after specifying the correct version here in the bootstrap file. If only there was a way to specify here to skip some of the other bootstrapping process.
        Evil! Thank you very much for sharing your solution!
Re^2: programatically setting the LD_LIBRARY_PATH
by mikeraz (Friar) on Jan 26, 2006 at 17:10 UTC

    Here's a "something close" for cases where you need multiple elements in your path.

    BEGIN { my $dir; my $needed_path = 0; my @need = ( "/usr/local/lib", "/usr/platform/SUNW,Ultra-80/lib", "/usr/lib" ); my $ld_path = $ENV{LD_LIBRARY_PATH}; if( ! $ld_path ) { $ENV{LD_LIBRARY_PATH} = join ":", @need; exec 'env', $^X, $0, @ARGV; } foreach $dir (@need) { if ( $ld_path !~ m/(^|:)\Q$dir\E(:|$)/ ) { $ENV{LD_LIBRARY_PATH} .= ':' . $dir; $needed_path = 1; } } if($needed_path) { exec 'env', $^X, $0, @ARGV; } }
    Be Appropriate && Follow Your Curiosity
Re: (tye)Re: programatically setting the LD_LIBRARY_PATH
by LanceDeeply (Chaplain) on Nov 21, 2001 at 00:39 UTC
    Thanks for explaining that one.
    I was going nuts.

    The super seach came back with a bunch of different ways to handle the prob too. I'm hooked.
Re^2: programatically setting the LD_LIBRARY_PATH
by shagbark (Acolyte) on Aug 09, 2013 at 17:17 UTC
    What if your Perl program uses system to call an executable program, which is the one that needs the library? Will setting LD_LIBRARY_PATH in the Perl code work then?
      Did you try it? Anyway, the answer should be yes. I have a few functions that go something like:
      sub exec_something { local $ENV{LD_LIBARY_PATH} = "...."; system some_command => @args; }

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://126587]
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (2)
As of 2024-06-15 21:38 GMT
Find Nodes?
    Voting Booth?

    No recent polls found

    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.