I am trying to link against a modified version of a library (LAME).
I downloaded the source, made the modifications and build the shared object file.
I then copied the shared library file into the ./lib
folder of the project I wanted to link to. The other project was just a trivial harness to test my modifications. I also copied the relevant header from LAME's ./include
.
I built my harness:
gcc -c src/harness.c -o obj/harness.o
gcc obj/harness.o -o bin/harness -L./lib/ -libmp3lame
But to my suprise:
$ ldd ./bin/harness
linux-vdso.so.1 => (0x00007fffbc5fe000)
libmp3lame.so.0 => /usr/lib/x86_64-linux-gnu/libmp3lame.so.0 (0x00007f10d9468000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f10d90a0000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f10d8d9b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f10d9713000)
(The /usr/lib/...
library was linked instead of the one in ./lib
in the harness' project directory.
I then changed the name of my customised libmp3lame.so to libsomeothername.so and tried to link that.. the same thing happened - the installed libmp3lame was linked instead of my custom one.
What is going on here? Why won't the compiler just do what it's told? Why would /usr/lib/.../libmp3lame
get linked even when that name isn't used?
I used LD_DEBUG=all
to see what was happening with the linker, as LD_LIBRARY_PATH=...
should have linked to the correct library.
As it turned out, the linker was looking there, but expected to find libmp3lame.so.0
rather than the libmp3lame.so
I had there. Renaming the library with .0
on the end fixed the problem.
I can now run:
LD_LIBRARY_PATH=./lib ./bin/harness
and the lib I wanted is linked.
LD_DEBUG=all
seems pretty useful.
The ld-linux.so library is the one that actually controls which library gets linked in at run time. The -L option to GCC, on the other hand, only affects the compile-time search path for libraries.
The man page says:
When resolving library dependencies, the dynamic linker first inspects each dependency string to see if it contains a slash (this can occur if a library pathname containing slashes was specified at link time). If a slash is found, then the dependency string is interpreted as a (relative or absolute) pathname, and the library is loaded using that pathname.
If there is no slash, then it searches along the pre-defined search path (also specified in the man page).
To get the behaivour you want, you have the following options:
Specify the absolute path to the library when linking, or
Set the LD_LIBRARY_PATH to point to the directory containing your library, or
Use the -rpath option when linking to include the directory containing your library in the search path (NB. to pass linker options from gcc to the linker, use -Wl,--rpath=/my/path
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