Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The wrong shared library is being linked

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?

like image 911
jsj Avatar asked Jun 23 '14 12:06

jsj


2 Answers

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.

like image 128
jsj Avatar answered Nov 01 '22 00:11

jsj


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:

  1. Specify the absolute path to the library when linking, or

  2. Set the LD_LIBRARY_PATH to point to the directory containing your library, or

  3. 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

like image 42
harmic Avatar answered Oct 31 '22 22:10

harmic