I have an executable which needs to link with libtest.so
dynamically,so I put them in the same directory,then :
cd path_to_dir
./binary
But got this:
error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
How can it be unable to find libtest.so
which is already in the same directory as the executable itself?
While you can set LD_LIBRARY_PATH to let the dynamic linker know where to look, there are better options. You can put your shared library in one of the standard places, see
/etc/ld.so.conf
(on Linux) and/usr/bin/crle
(on Solaris) for the list of these placesYou can pass
-R <path>
to the linker when building your binary, which will add<path>
to the list of directories scanned for your shared library. Here's an example. First, showing the problem:libtest.h:
libtest.c:
hello.c:
Makefile (tabs must be used):
Let's run it:
How to fix it? Add
-R <path>
to the linker flags (here, by settingLDFLAGS
).Looking at the binary, you can see that it needs
libtest.so.0
:The binary will look for its libraries, apart from the standard places, in the specified directory:
If you want the binary to look in the current directory, you can set the RPATH to
$ORIGIN
. This is a bit tricky, because you need to make sure that the dollar sign is not interpreted by make. Here's one way to do it:The loader never checks the current directory for shared objects unless it is explicitly directed to via
$LD_LIBRARY_PATH
. See theld.so(8)
man page for more details.To load the shared objects from the same directory as your executable, simply execute:
Note: It will not modify the LD_LIBRARY_PATH variable of your system. The change only affects to this, and only this, execution of your program.
For anyone using CMake for their build, you can set the
CMAKE_EXE_LINKER_FLAGS
to the following:This will properly propagate the linker flags for all build types (e.g., Debug, Release, etc...) to look for .so files in the current working directory first.
For anyone that still struggles without an answer I found one myself with the following suggestion:
You could try updating the ld.so.cache using:
sudo ldconfig -v
Worked for me.
There can be subtle situations showing the same symptoms. I use to build a CMake project, both locally at
/path/to/myproj
and remotely on a server, at/path/to/myproj-deploy
. Project contains an.so
build artifact and multiple ELF files depending on that.When I pulled back binaries from the build server, I found out that (locally) calling ELFs results in the same problems. Thanks to authomatthias, calling
ends up in a non-surprising consequence: CMake system hardcoded remote path into the
RUNPATH
, demonstrating some non-portability (without proper additional actions, I suppose)The dynamic linker will decide where to look for libraries. In case of Linux, the dynamic linker usually is
GNU ld.so
(or an alternative that will usually behave identical for compatibility reasons).To quotes from the Wikipedia:
Source: https://en.wikipedia.org/wiki/Rpath
I got it working with this :
and to run :