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 -L
everything 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_PATH
and 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.
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.
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.
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.
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 ).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With