注意:现在完整的工作示例如下.原始问题如下:
我在使用ld的-rpath参数时遇到问题$ORIGIN.
由于我找不到一个完整的例子,我以为我会尝试自己写一个,以便我和其他人可以在以后使用它.一旦我开始工作,我会整理它.
示例项目构建一个共享库和一个链接到所述库的可执行文件.
它非常小(3个文件,22行包含buildscript).
您可以从这里下载项目
文件结构(构建前):
project/
src/
foo.cppmain.cppmake.shproject/src/foo.cpp
int foo()
{ return 3; }
Run Code Online (Sandbox Code Playgroud)
project/src/main.cpp
int foo();
#include <iostream>
int main()
{
std::cout << foo() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
project/make.sh
# Make directories:
mkdir -p -v obj
mkdir -p -v lib
mkdir -p -v run
# Build the library:
g++ -c -o obj/foo.o src/foo.cpp -fPIC
g++ -shared -o lib/foo.sh obj/foo.o
# Build the executable: …Run Code Online (Sandbox Code Playgroud) 如果共享库链接到二进制文件,并且共享库还依赖于其他库,那么共享库的 RPATH 和二进制文件的 RPATH 的优先级(链接器搜索顺序)是什么?二进制文件的 RPATH 能否覆盖共享库中的 RPATH?我在共享库 RPATH 中设置的 $ORIGIN 是指 lib 位置还是二进制位置?
提前致谢。
我有一个libA.so,它依赖于libB.so,它位于../libB/(来自libA.c).我试图以这样的方式编译事物,我不必设置任何环境变量.我有:
cc -std=c99 -c -fPIC -I../libB/ -Wall libA.c
cc -std=c99 -shared libA.o -L../libB -lB -o libA.so
Run Code Online (Sandbox Code Playgroud)
编译好了.当我运行一个用dlopen加载libA的程序时,我得到:
dyld: Library not loaded: libB.so
Referenced from: libA/libA.so
Reason: image not found
Trace/BPT trap: 5
Run Code Online (Sandbox Code Playgroud)
所以libA在运行时没有找到libB.我找到了这个解决方案来改变Mac OS X上的运行时路径:
install_name_tool -change libB.so @loader_path /../ libB.so libA.so
但我想找到一个适用于OS X和Linux的解决方案.再一次,我试图让最终用户尽可能少做,所以我不希望他们必须设置环境变量,我必须使用cc(对我来说是Apple LLVM版本4.2(clang-425.0) .27)(基于LLVM 3.2svn),我也希望它也适用于Linux,所以大概是cc = gcc).
编辑 我的问题可能比我意识到的更复杂.我在C中创建这个动态库,但是尝试在python中使用它.我可以在python中使用libB.so(没有依赖关系)没有问题,当我从python中加载libA.so时它找到它(参见上面的错误),就在那时,libA.so意识到它没有'知道在哪里可以找到libB.so. 如果我在下面正确理解你的答案,解决方案依赖于在编译可执行文件时设置链接器路径,在我的例子中是python.
有没有办法告诉libA.so在编译时在哪里查找libB.so?我之后可以在OSX上使用install_name_tool来完成它,但是在编译器上没有办法可以在OSX和Linux上运行吗?