The wrong shared library is being linked

jsj*_*jsj 6 c linker gcc shared-libraries

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
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

(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?

har*_*mic 1

ld-linux.so库是实际控制运行时链接哪个库的库。另一方面,GCC 的 -L 选项仅影响库的编译时搜索路径。

手册页说:

解析库依赖项时,动态链接器首先检查每个依赖项字符串以查看它是否包含斜杠(如果在链接时指定了包含斜杠的库路径名,则可能会发生这种情况)。如果找到斜杠,则依赖项字符串将被解释为(相对或绝对)路径名,并使用该路径名加载库。

如果没有斜杠,则它将沿着预定义的搜索路径(也在手册页中指定)进行搜索。

要获得您想要的行为,您有以下选择:

  1. 链接时指定库的绝对路径,或者

  2. 将 LD_LIBRARY_PATH 设置为指向包含您的库的目录,或者

  3. 链接时使用 -rpath 选项以将包含库的目录包含在搜索路径中(注意,要将链接器选项从 gcc 传递到链接器,请使用-Wl,--rpath=/my/path