I have some code that uses some shared libraries (c code on gcc). When compiling I have to explicitly define the include and library directories using -I and -L, since they aren't in the standard places. When I try to run the code, I get the following error:
./sync_test
./sync_test: error while loading shared libraries: libsync.so: cannot open shared object file: No such file or directory
However, do the following, everything works just fine:
export LD_LIBRARY_PATH="/path/to/library/"
./sync_test
Now, the strange part is, this only works once. If I try and run sync_test again I get the same error unless I run the export command first. I tried adding the following to my .bashrc, but it made no difference:
LD_LIBRARY_PATH="/path/to/library/"
Use
export LD_LIBRARY_PATH="/path/to/library/"
in your .bashrc otherwise, it'll only be available to bash and not any programs you start.
Try -R/path/to/library/ flag when you're linking, it'll make the program look in that directory and you won't need to set any environment variables.
EDIT: Looks like -R is Solaris only, and you're on Linux.
An alternate way would be to add the path to /etc/ld.so.conf and run ldconfig. Note that this is a global change that will apply to all dynamically linked binaries.
You should avoid setting LD_LIBRARY_PATH in your .bashrc. See "Why LD_LIBRARY_PATH is bad" for more information.
Use the linker option -rpath while linking so that the dynamic linker knows where to find libsync.so during runtime.
gcc ... -Wl,-rpath /path/to/library -L/path/to/library -lsync -o sync_test
EDIT:
Another way would be to use a wrapper like this
#!/bin/bash
LD_LIBRARY_PATH=/path/to/library sync_test "$@"
If sync_test starts any other programs, they might end up using the libs in /path/to/library which may or may not be intended.
Did you 'export' in your .bashrc?
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/path/to/library"
You can just put this all on one line:
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/library" ./sync_test
Should make things a little easier, even if it doesn't change anything fundamental
Instead of overriding the library search path at runtime with LD_LIBRARY_PATH, you could instead bake it into the binary itself with rpath. If you link with GCC adding -Wl,-rpath,<libdir> should do the trick, if you link with ld it's just -rpath <libdir>.
What you also can do, if it's something you installed on your system, is to add the directory that contains the shared libraries to your /etc/ld.so.conf file, or make a new file in /etc/ld.so.conf.d/
(I've both checked RHEL5 and Ubuntu distribution so I think it's generic for linux)
The ldconfig program will make sure they are system-wide included.
See the following link for more information: www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/dlls.html
You could add in your code a call system with the new definition:
sprintf(newdef,"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%s:%s",ld1,ld2);
system(newdef);
But, I don't know it that is the rigth solution but it works.
Regards
来源:https://stackoverflow.com/questions/695530/why-do-i-have-to-define-ld-library-path-with-an-export-every-time-i-run-my-appli