我正在尝试链接库的修改版本(LAME)。
我下载了源代码,进行了修改并构建了共享对象文件。
然后我将共享库文件复制到我想要链接到的项目的./lib
文件夹中。另一个项目只是一个简单的工具来测试我的修改。我还复制了LAME ./include
的相关标题。
我建立了我的安全带:
gcc -c src/harness.c -o obj/harness.o
gcc obj/harness.o -o bin/harness -L./lib/ -libmp3lame
但令我惊讶的是:
$ 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)
(/usr/lib/...
库已链接,而不是线束项目目录中./lib
中的库。
然后我将自定义的libmp3lame.so的名称更改为libsomeothername.so并尝试链接..发生了同样的事情 - 安装的libmp3lame已链接而不是我自定义的。
这里发生了什么?为什么编译器不会按照它所说的去做?为什么/usr/lib/.../libmp3lame
即使未使用该名称也会链接 ?
答案 0 :(得分:3)
我使用LD_DEBUG=all
来查看链接器发生了什么,因为LD_LIBRARY_PATH=...
应该链接到正确的库。
事实证明,链接器 在那里寻找,但期望找到libmp3lame.so.0
而不是我在那里的libmp3lame.so
。最后用.0
重命名库来修复问题。
我现在可以跑了:
LD_LIBRARY_PATH=./lib ./bin/harness
我想要的lib是链接的。
LD_DEBUG=all
似乎很有用。
答案 1 :(得分:1)
ld-linux.so库是实际控制哪个库在运行时链接的库。另一方面,GCC的-L选项仅影响库的编译时搜索路径。
手册页说:
在解析库依赖关系时,动态链接器首先检查 每个依赖关系字符串,以查看它是否包含斜杠(这可能会发生 如果在链接时指定了包含斜杠的库路径名)。 如果找到斜杠,则依赖关系字符串将被解释为a (相对或绝对)路径名,并使用它加载库 路径名。
如果没有斜杠,则它会沿着预定义的搜索路径进行搜索(也在手册页中指定)。
要获得所需的行为,您有以下选择:
指定链接时库的绝对路径,或
将LD_LIBRARY_PATH设置为指向包含您的库的目录,或
链接时使用-rpath选项以在搜索路径中包含包含库的目录(注意:将链接器选项从gcc传递到链接器,使用-Wl,--rpath=/my/path