skd
skd

Reputation: 1977

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

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.

Upvotes: 23

Views: 9401

Answers (2)

Juan
Juan

Reputation: 3775

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.

Upvotes: 8

Dietrich Epp
Dietrich Epp

Reputation: 213807

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.

Upvotes: 25

Related Questions