LD_LIBRARY_PATH

jdavidb on 2006-07-18T18:25:43

I hate this environment variable. It is presently necessary for me to set this in order for Oracle.so to load properly. But I can't just set $ENV{LD_LIBRARY_PATH}. The only value of LD_LIBRARY_PATH that matters is the value it had at the beginning of the process; changes to it during the execution of the process have no effect on shared object loading.

hmmm...

Update: 2006-07-19T14:40Z: Nothing that mentions LD_LIBRARY_PATH should leave out the fact that if you do a simple Google search for this variable you will learn about how it is abused as your first result, and so therefore there is no longer any excuse for the messes I continue to see with this variable. Every system administrator on the planet should be familiar with what this article has to say. Every UNIX software vendor on the planet should be familiar with what this article has to say, and those who do not are negligent. Documentation writers who continue to recommend setting this variable for the usual (wrong) purposes are negligent. If this variable has to be set in your environment 100% of the time (i.e., from a shell config file), something is most likely wrong.

I'm not sure if I find this variable set on the new system because Oracle recommended it be done, but I'm betting that's the case. Oracle is one of the few proprietary software vendors I still would choose to use on a regular basis, but this is just inexcusable. The facts on this situation have been out there for years. I'm just a lowly developer with less experience, yet somehow I seem to know more about this than people who should be well aware of it.

It bears mentioning that on the previous system, LD_LIBRARY_PATH is not set at all in the environment of my own account nor the account that runs all of our cron jobs.


Hmm…

Aristotle on 2006-07-18T19:48:11

$ENV{ LD_LIBRARY_PATH } = $whatever;
exec { $0 } $0, @ARGV

?

Re:Hmm…

jdavidb on 2006-07-19T13:35:24

Yes, this is more or less the workaround I came up with. (Although I'm unfamiliar with that block syntax passed to exec and am about to go look that up and learn something new. :) ).

It's not my preference, but it beats a wrapper all to pieces. I can write a routine which checks LD_LIBRARY_PATH, returns if it's already been modified, and then modifies it and re-execs. And then I can throw that routine into a module for every single program on this box to use. (Sigh.)

My only fear so far is what happens when I try this from cron and the script isn't sure what directory it is running out of, but soon I'll have that tested and know if it works or not.

But really, as I just said in my other post to Uri, the real solution is for Oracle.so to get compiled right so that this is not necessary. LD_LIBRARY_PATH should only have to be set to override libraries that already work for certain testing or compilation purposes. You shouldn't have to set it to get things to work in the first place.

Re:Hmm…

Aristotle on 2006-07-19T14:43:03

You could try adding the pertinent directory to /etc/ld.so.conf (assuming this is Linux; maybe on Unices as well, but I have no experience with them).

Re:Hmm…

Aristotle on 2006-07-19T14:44:43

(After which, of course, you’ll have to run ldconfig to refresh the linker run time bindings.)

Re:Hmm…

jdavidb on 2006-07-19T17:28:09

It's Solaris, and even if it weren't I could not do that because it would mess up many, many other apps. Everything else on this box needs the other library directory.

Be sure to check out Why LD_LIBRARY_PATH is bad if you haven't already. It mentions ld.so.conf . :)

set %ENV before you load the libs

uri on 2006-07-19T03:51:14

the libs use the env value as they see it when they start up. so if you set %ENV before you load the other libs it should work fine:

BEGIN {
      $ENV{LD_LIBRARY_PATH} = 'path_to_lib' ;
}

use FooLib ;

uri

Re:set %ENV before you load the libs

jdavidb on 2006-07-19T13:32:44

Based on what I was seeing yesterday, that is not correct. Oracle.so does not load at compilation time. All I do is use DBI. If I understand correctly, DBD::Oracle is not loaded until I say DBI->connect("dbi:Oracle...").

But just in case I was misunderstanding, I tried what you are suggesting, two ways: by putting the setting of LD_LIBRARY_PATH in a BEGIN block, as you suggested, and also by throwing 'use DBI' into a string eval, just for good measure, to make certain that the load must occur after the variable is changed.

I found reference to this issue online, including a statement by somebody that he'd seen docs saying to set LD_LIBRARY_PATH in a BEGIN block but that it "didn't seem to work anymore" and he wanted to know what changed.

The real answer is that Oracle.so should be compiled to know where to look for the libraries it is linked to. But no amount of mucking with -R and LD_RUN_PATH has seemed to have helped me so far. I suppose I should try directly compiling my own Oracle.so from the command-line and seeing if it works, because so far all I've tried is setting these via options to Makefile.PL.