Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why LD_LIBRARY_PATH is BAD and the correct way to load dynamic libraries

Tags:

So, I have a program that runs with OpenBlas and I want to compile it. The linking process looks like this:

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -L/opt/OpenBLAS/lib -lopenblas

So far so good. If I remove the -L option, I get an error in the linking process

/usr/bin/ld: cannot find -lopenblas

With the -Leverything links without errors. However, when I try to run it I get the following error:

./prog: error while loading shared libraries: libopenblas.so.0: cannot open shared object file: No such file or directory

If I set the env variable LD_LIBRARY_PATH to /opt/OpenBlas/lib I can run the program, but many sources like http://xahlee.info/UnixResource_dir/_/ldpath.html consider this to be a bad practice and I can understand almost all the reasoning. The other method mentioned in the article (modify the ld configuration) is also considered to be somewhat a bad practice. Finally, you could just add a symlink to the library in /usr/lib. A big problem with the last two methods is that you need sudo access.

So my question is how can I compile and run a program linked to a shared library that is not located in a default path (/usr/lib) without using LD_LIBRARY_PATHand sudo access. In the article they say that you can just 'write' in the binary where to look for shared libraries but I do not know how to do that (the -L flag does not seem to be doing it). I would appreciate if anyone could explain this matter, since I've been looking everywhere and I'm very confused (some references seem to suggest that the flag `-L' should do it but I does not work for me). Thank you in advance.

like image 334
skd Avatar asked Sep 18 '14 17:09

skd


People also ask

Why is LD_LIBRARY_PATH bad?

In contrast to that, globally setting the LD_LIBRARY_PATH (e.g. in the profile of a user) is harmful because there is no setting that fits every program. The directories in the LD_LIBRARY_PATH environment variable are considered before the default ones and the ones specified in the binary executable.

Why do we need LD_LIBRARY_PATH?

In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories; this is useful when debugging a new library or using a nonstandard library for special purposes.

What should be LD_LIBRARY_PATH?

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. It's better to avoid the use of LD_LIBRARY_PATH and use alternatives.

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 ).


2 Answers

Add the path to the runtime library search path.

gcc -Wl,-rpath=/opt/OpenBlas/lib ...

What the -L option does at link time, the -rpath option does at run time.

like image 57
Dietrich Epp Avatar answered Oct 22 '22 02:10

Dietrich Epp


On linux, it is also possible to use $ORIGIN in rpath to mean the directory path to the application and build a relative rpath from there. You would then move the library to a known relative path to the binary.

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -Wl,-rpath=\$ORIGIN/lib -L/opt/OpenBLAS/lib -lopenblas

You can also use the full path to the libary, and it will be linked in:

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include /opt/OpenBLAS/lib/libopenblas.so

If you run "ldd" on the executable, you should see the full path encoded.

like image 26
Juan Avatar answered Oct 22 '22 02:10

Juan