2

我正在尝试学习如何使用-rpathGCC 的链接器(ld)中的选项$ORIGIN

我正在尝试我能想到的最简单的例子(见下文),我阅读的所有链接似乎都说我做得正确。

但是,当我运行可执行文件时,它找不到共享对象,除非我从$ORIGIN.

在可执行文件(main.run)上使用 readelf -d 显示:


0x0000000000000001 (NEEDED) Shared library: [lib/foo.so]
...
0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
...

文件结构(相关文件)为:

  • /make/test/dll_test/
    • main.run
    • lib/
      • foo.so

从 dll_test 中执行工作正常。从其他地方(/make/test)执行会出现错误:

dll_test/main.run:加载共享库时出错:lib/foo.so:无法打开共享对象文件:没有这样的文件或目录

我正在使用-l:foo.so而不是-lfoo,但这不应该影响任何事情(我希望)。



源文件

dll_test/src/foo.cpp


int foo()
    { return 1; }

dll_test/src/main.cpp


int foo();

#include <iostream>


int main()
  {
    std::cout << foo() << std::endl;
  }


构建脚本

dll_test/make.sh


mkdir -p -v obj
mkdir -p -v lib

g++ -c -o obj/foo.o src/foo.cpp -fPIC
g++ -shared -o lib/foo.so obj/foo.o

g++ -c -o obj/main.o src/main.cpp
g++ -o main.run obj/main.o -Wl,-rpath,'$ORIGIN' -Llib -l:foo.so



要进行构建,请在它们各自的位置创建这些文件,然后从 dll_test(或项目根目录所在的任何位置)中简单地运行“sh make.sh”。它应该生成“dll_test/main.run”。

从 dll_test 中运行“main.run”应该可以工作(打印 1)。
从 dll_test 中运行“main.run”失败。为什么?

此外,foo.so 的路径存储在 main.run 作为 [lib/foo.so]。我可以让它成为 [foo.so] 以便我可以使用 -Wl,-rpath,'$ORIGIN/lib' 吗?

4

1 回答 1

0

你需要-Wl,-rpath,'$ORIGIN/lib'而不是仅仅'$ORIGIN'.

编辑:你真的进入了-l:foo.so吗?这似乎很奇怪......你应该对-Wl,-rpath,'$ORIGIN/lib' -Llib -lfoo.so. 如果这不起作用,请添加-Wl,-soname,libfoo.so到共享库的链接器命令。我不确定这会解决“lib/foo.so”问题,但值得一试:)

于 2011-06-10T07:47:28.687 回答