Dan*_*Dan 2 linux macos shared-libraries dynamic-linking cc
我有一个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上运行吗?
最重要的是,您的最终可执行文件必须知道您的库所在的位置.您可以完成这两种方式(1)导出LD_LIBRARY_PATH包含库的路径,或(2)使用,rpath以便您的可执行文件知道在哪里找到您的库.导出LD_LIBRARY_PATH通常看起来像这样:
LD_LIBRARY_PATH=/path/to/your/lib:${LD_LIBRARY_PATH}
export LD_LIBRARY_PATH
Run Code Online (Sandbox Code Playgroud)
我更喜欢使用rpath.使用rpath正常编译库(以下示例为扩展测试函数库libetf.so)
gcc -fPIC -Wall -W -Werror -Wno-unused -c -o lib_etf.o lib_etf.c
gcc -o libetf.so.1.0 lib_etf.o -shared -Wl,-soname,libetf.so.1
Run Code Online (Sandbox Code Playgroud)
然后编译使用此库的可执行文件,编译为object,然后将该对象链接为rpath给定的链接器选项.你会为两者提供的路径libA.so和libB.so你的情况.构建testso可执行文件:
gcc -O2 -Wall -W -Wno-unused -c -o testetf.o testetf.c
gcc -o testso testetf.o -L/home/david/dev/src-c/lib/etf -Wl,-rpath=/home/david/dev/src-c/lib/etf -letf
Run Code Online (Sandbox Code Playgroud)
使用ldd以确认该可执行文件已经正确定位您的图书馆:
$ ldd testso
linux-vdso.so.1 (0x00007fffd79fe000)
libetf.so.1 => /home/david/dev/src-c/lib/etf/libetf.so.1 (0x00007f4d1ef23000)
libc.so.6 => /lib64/libc.so.6 (0x00007f4d1eb75000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4d1f126000)
Run Code Online (Sandbox Code Playgroud)
注意: libetf.so.1指向/home/david/dev/src-c/lib/etf/libetf.so.1.
| 归档时间: |
|
| 查看次数: |
7371 次 |
| 最近记录: |