【发布时间】:2011-09-11 09:44:18
【问题描述】:
我正在尝试学习如何将 GCC 的链接器 (ld) 中的 -rpath 选项与 $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' 吗?
【问题讨论】:
-
抱歉之前的编辑。 NoScript 隐藏了预览,我以为我在写原始文本。
-
由于这个问题有点混乱,我在这里重写了:stackoverflow.com/questions/6311016/…