Error while loading shared libraries
Solution 1
What matters is what Linux distribution each machine uses, because they handle library paths differently. On the Gentoo (Sabayon) machine, if you want a third party library to be usable system-wide, you should:
-
Create a file under
/etc/env.d/
that will contain the additional environment setup. The files are named using the scheme[0-9][0-9]somename
- the two initial digits decide on the order in which they are used. A good practice requires that your custom settings are added (near) last, so99
is a proper beginning, as long as it works. Getting to the point: Create a file named like/etc/env.d/99mythirdpartylib
containing
LDPATH=/path/to/your/library
-
To make the changes active without reboot, run as root:
env-update && source /etc/profile
(which will update the environment as well as run
ldconfig
).
Reference, if you'd like one.
Solution 2
If you don't want to set a global library search path for your whole system with the /etc/env.d
approach, you can either:
Just set the LD_LIBRARY_PATH
to the PATH of your library (you did set it to the library itself, that won't work), the same which you set with the -L
parameter to gcc e.g.
export LD_LIBRARY_PATH="$PROJ/lib/3rdpartylib/:$LD_LIBRARY_PATH"
(the last part is for preserving the variable if it was already set, which it shouldn't be normally). This will only work in you current shell and you will have to set it again everytime.
Or you link using a 'static' library search paths like this:
gcc file1.o file2.o -L./lib/3rdpartylib -Wl,-rpath=./lib/3rdpartylib -l3rdpartylib -o myapp
-Wl
specifies commmand line arguments that will not be processed by gcc but instead be passed to the linker.
Since the library search path will be written into the binary, this will work even on different machines (provided the library exists)
PS: Since you're just talking about the case where you're developing a project, I think this temporary way is more appropriate than putting it in system-wide configuration files.
rahmu
Updated on September 18, 2022Comments
-
rahmu over 1 year
My project tree looks something like that:
src/ include/ Makefile lib/ lib/3rdparylib/
I didn't code
3rdpartylib
, but decided to embed its source code in my project packaging. I compile the software by doing the following steps:$ cd lib/3rdpartylib/ $ make $ ln -s 3rdpartylib.so.0 3rdpartylib.so
Then I compile each of my source files like this:
$ gcc -c src/file.c -I include -o file.o -l 3rdparylib -L lib/3rdpartylib -I lib/3rdpartylib/include
Then I link:
$ gcc file1.o file2.o -l3rdpartylib -L lib/3rdpartylib -o myapp
When I am on my main machine, it works perfectly. Today I tried to launch it on another machine. It compiled and linked without any problem. However when I tried to launch the application I got the following error message.
./myapp: error while loading shared libraries: 3rdpartylib.so.0: cannot open shared object file: No such file or directory
I tried doing the following:
export LD_LIBRARY_PATH=/path/to/3rdpartylib.so
It seems to work. But I understand that using LD_LIBRARY_PATH is a bad practice. It bothers me to have this variable set up every time I want to run my app.
What am I missing? Why does it work on my main machine (where LD_LIBRARY_PATH is not set to anything) and not on the other machine? Does it matter that the other machine is a virtual one?
If it is of any help, my main machine is a Debian box, and my "new" machine is a Sabayon (Gentoo), running in Virtualbox.
-
Admin over 12 yearsI don't see what's going on at the moment, but this may provide useful background.
-
-
rozcietrzewiacz over 12 yearsOn Gentoo this is not the way to do it: the top line of
/etc/ld.so.conf
proves it vividly, saying "ld.so.conf autogenerated by env-update; make all changes to contents of /etc/env.d directory" -
rozcietrzewiacz over 12 years...And
/etc/env.d
is sourced on each boot, so you'd loose all your changes. -
rozcietrzewiacz over 12 yearsIf that were the issue, wouldn't
ld
complain during building? The app is said to get built fine. -
fab over 12 yearsOk I don't know Gentoo,
env-update
will do exactly what I say :env-update will also extract the information from the LDPATH variable and use that to create /etc/ld.so.conf. After this, it will run ldconfig to recreate the /etc/ld.so.cache
. So your answer is better ;-)