我制作了一个使用两个共享库(我编译的)的程序,并且放置如下:
/home_directory_where_I_compile_and_run_everything
-->/lib/libjson_linux-gcc-4.4.6_libmt.so
-->/lib/libre2.so.0
当我编译我的程序时,我将这些库的相对位置传递给链接器,如下所示:
g++ ...... stuff ........ my_program.cc lib/libjson_linux-gcc-4.4.6_libmt.so lib/libre2.so.0
它编译得很好,但是在运行程序时找不到 libre2.so,如果我用 ldd 检查它,会发生以下情况:
....
lib/libjson_linux-gcc-4.4.6_libmt.so (0x00007f62906bc000)
libre2.so.0 => not found
....
显然,它确实承认 libjson 上的路径是相对的,但它不会在 libre2.so.0 上这样做(它会修剪所有路径并只留下 libre2.so.0)
有人能告诉我为什么会这样吗?
另外,有没有办法通过 g++ 参数来修改它?
最好的。
* 更新 *哇,看看这个!我已将 libre2.so.0 的名称更改为 stuff.so,然后尝试编译基本相同,如下所示:
g++ ...... stuff ........ my_program.cc lib/libjson_linux-gcc-4.4.6_libmt.so lib/stuff.so
无论如何它都失败了;它不仅失败了,而且失败了,因为它找不到“libre2.so.0”。
为什么?
*更新#2 *
输出为readelf -d the_program.o
0x0000000000000001 (NEEDED) Shared library: [lib/libjson_linux-gcc-4.4.6_libmt.so]
0x0000000000000001 (NEEDED) Shared library: [libre2.so.0]
现在,如果我可以将 [libre2.so.0] 改为 [lib/libre2.so.0] 就好了。
*更新#3 *
正如@troubadour 发现的那样:
当可执行文件与具有 DT_SONAME 字段的共享对象链接时,当可执行文件运行时,动态链接器将尝试加载由 DT_SONAME 字段指定的共享对象,而不是使用链接器提供的文件名。
这就是为什么它适用于 libjson .....so 而不是 libre2.so.0。(libjson .....so 没有 SONAME 条目)。
我终于找到了我正在寻找的确切问题:
有没有办法告诉 gcc 链接器忽略共享库文件上的 SONAME 条目并链接到特定的文件路径?