Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between LD_LIBRARY_PATH and -L at link time?

I'm having problems with LD_LIBRARY_PATH at link time (this question has nothing to do with run time).

The link line looks like this when I run make (this is a Linux system using g++ version 4.1.x):

g++ a.o b.o c.o -o myapp \  -L/long/path/to/libs/ \  -L/another/long/path/ \  -labc -ldef -lghi 

The -l options reference shared libraries (e.g., libabc.so) which exist in the directories specified by the -L options. Those directories also appear in LD_LIBRARY_PATH. With that configuration, the link is successful, and I can run the application.

If I remove the directories from LD_LIBRARY_PATH, then I get a single error line such as:

/usr/bin/ld: cannot find -labc 

On the other hand, if I remove the directories from the list of -L options, then I get many warnings such as:

/usr/bin/ld: warning: libabc.so, needed by /long/path/to/libs/libxyz.so,     not found (try using -rpath or -rpath-link) 

and then many more errors, such as:

/long/path/to/libs/libdef.so: undefined reference to `Foo::Bar<Baz>::junk(Fred*)' 

Can someone explain the difference between LD_LIBRARY_PATH and -L? I would like to understand this stuff in depth, so references are greatly appreciated!

Also, what do I have to add to the link line to avoid using LD_LIBRARY_PATH?

EDIT: When directories were missing from -L, the compiler suggested to "try using -rpath or -rpath-link". I don't think I've ever seen those options in a makefile before. Have you? Not sure if that would help the LD_LIBRARY_PATH problem though.

like image 842
Dan Avatar asked Dec 15 '09 03:12

Dan


People also ask

What does LD_LIBRARY_PATH mean?

LD_LIBRARY_PATH is the default library path which is accessed to check for available dynamic and shared libraries. It is specific to linux distributions. It is similar to environment variable PATH in windows that linker checks for possible implementations during linking time.

What is the difference between PATH and LD_LIBRARY_PATH?

PATH is for specifying directories of executable programs. LD_LIBRARY_PATH is used to specify directories of libraries. From other point of view, PATH is used primarily by the shell, while LD_LIBRARY_PATH is used by the dynamic loader (usually ld-linux.so ).

What does export LD_LIBRARY_PATH do?

LD_LIBRARY_PATH is an environmental variable used in Linux/UNIX Systems. It is used to tell dynamic link loaders where to look for shared libraries for specific applications. It is useful until you don't mess with it.

What is Oracle LD_LIBRARY_PATH?

Use the LD_LIBRARY_PATH environment variable to specify directory paths that the linker should search for libraries specified with the -l library option. Multiple directories can be specified, separated by a colon.


2 Answers

There are two answers to this question, part of the answer lies in the compile-time linking (i.e gcc -lfoo -L/usr/lib ... which in turn calls ld), and run-time linker lookups.

When you compile your program, the compiler checks syntax, and then the linker ensures that the symbols required for execution exist (i.e variables / methods / etc), among other things. LD_LIBRARY_PATH, as has been noted, has the side-effect of altering the way gcc/ld behave as well as the way the the run-time linker behaves by modifying the search path.

When you run your program, the run-time linker actually fetches the shared libraries (on disk or from memory if possible), and loads in the shared symbols / code / etc. Again, LD_LIBRARY_PATH affects this search path implicitly (sometimes not a good thing, as has been mentioned.)

The correct fix for this without using LD_LIBRARY_PATH on most Linux systems is to add the path that contains your shared libraries to /etc/ld.so.conf (or in some distributions, create a file in /etc/ld.so.conf.d/ with the path in it) and run ldconfig (/sbin/ldconfig as root) to update the runtime linker bindings cache.

Example on Debian:

jewart@dorfl:~$ cat /etc/ld.so.conf.d/usrlocal.conf  /usr/local/lib 

Then when the program is executed, the run-time linker will look in those directories for libraries that your binary has been linked against.

If you want to know what libraries the run-time linker knows about, you can use:

jewart@dorfl:~$ ldconfig -v   /usr/lib: libbfd-2.18.0.20080103.so -> libbfd-2.18.0.20080103.so libkdb5.so.4 -> libkdb5.so.4.0 libXext.so.6 -> libXext.so.6.4.0 

And, if you want to know what libraries a binary is linked against, you can use ldd like such, which will tell you which library your runtime linker is going to choose:

jewart@dorfl:~$ ldd /bin/ls linux-vdso.so.1 =>  (0x00007fffda1ff000) librt.so.1 => /lib/librt.so.1 (0x00007f5d2149b000) libselinux.so.1 => /lib/libselinux.so.1 (0x00007f5d2127f000) libacl.so.1 => /lib/libacl.so.1 (0x00007f5d21077000) libc.so.6 => /lib/libc.so.6 (0x00007f5d20d23000) 
like image 86
John Ewart Avatar answered Sep 16 '22 22:09

John Ewart


The settings of LD_LIBRARY_PATH has the highest precedence, so when it is set, the set of directories mentioned by LD_LIBRARY_PATH are searched first even before the standard set
of directories. So in your case setting of LD_LIBRARY_PATH is influencing the lookup of
the libraries mentioned with -l option. Without LD_LIBRARY_PATH some of the dependencies
might have been resolved from the standard set of directories.

Though setting of LD_LIBRARY_PATH help with debugging and to try out a newer version of
a library its usage in the general development environment setup and deployment is considered bad.

Also refer this HOWTO from Linux Documentation for more details on Shared Libraries

like image 45
sateesh Avatar answered Sep 18 '22 22:09

sateesh