我在OS X上构建了一个总是无法加载的可执行文件(名为demux),我找不到原因:
$ ./demux
RPATH failed to expanding @rpath/sfeMovie.framework/Versions/2.0/sfeMovie to: @executable_path/sfeMovie.framework/Versions/2.0/sfeMovie
dyld: Library not loaded: @rpath/sfeMovie.framework/Versions/2.0/sfeMovie
Referenced from: …current_dir/./demux
框架紧挨着可执行文件。 Otool显示以下内容:
$ otool -L sfeMovie.framework/Versions/2.0/sfeMovie
sfeMovie.framework/Versions/2.0/sfeMovie:
@rpath/sfeMovie.framework/Versions/2.0/sfeMovie (compatibility version 2.0.0, current version 2.0.0)
和
$ otool -L demux
demux:
@rpath/sfeMovie.framework/Versions/2.0/sfeMovie (compatibility version 2.0.0, current version 2.0.0)
鉴于此,我认为将@executable_path添加到可执行文件的运行时搜索路径将允许它查看任何框架和库,其相对安装名称仅以@rpath为前缀(如@ rpath / sfeMovie.framework / ...)和可执行文件旁边的。要确保此运行时搜索路径正确无误:
$ otool -l demux | grep LC_RPATH -A 2
cmd LC_RPATH
cmdsize 32
path @executable_path (offset 12)
但这失败了,我不知道为什么。对我来说@ executable_path / sfeMovie.framework / Versions / 2.0 / sfeMovie看起来是正确的路径,但它仍然失败...是否有误用@rpath或@executable_path?
答案 0 :(得分:4)
我能够通过快速测试项目重现您的问题。当我在LD_RUNPATH_SEARCH_PATH
构建设置中附加一个尾部斜杠时修复了它。
而不是:
@executable_path
你应该试试
@executable_path/
otool -l
的输出现在看起来像这样:
cmd LC_RPATH
cmdsize 32
path @executable_path/ (offset 12)
通常,您可以使用我的dyld分析器脚本在https://github.com/liyanage/macosx-shell-scripts/blob/master/checklibs.py
检查您的顶级可执行文件(在本例中为“demux”)./checklibs.py demux
此工具试图忠实地再现dyld
的分辨率逻辑。它通常可以提供有关哪些引用不起作用的提示,但在这种情况下,它不会捕获缺少尾部斜杠的问题。我会相应地更新它以匹配dyld
的行为。
答案 1 :(得分:0)
demux
包含@rpath
链接,RPATH包含@executable_path
,但dyld man page表示,“您甚至可以添加LC_RPATH
加载命令路径以@loader_path
开头,这似乎意味着RPATH中不允许@executable_path
。
如果demux
直接包含@executable_path
而不是间接到RPATH
,那么它就会有效。
如果是demux.c
:
#include <stdio.h>
int foo();
int main() {
printf("%d\n", foo());
}
这是lib/sfeMovie.c
:
int foo() {
return 42;
}
这是您的Makefile
:
run:
$(MAKE) clean
$(MAKE) demux
cd .. && "$(shell pwd -P)/demux"
demux: demux.o lib/sfeMovie.dylib
cc -o $@ $^
install_name_tool \
-change \
'lib/sfeMovie.dylib' \
'@executable_path/lib/sfeMovie.dylib' \
$@
lib/sfeMovie.dylib: lib/sfeMovie.o
cc -shared -o $@ $<
clean::
rm -f demux *.o lib/*.o lib/*.dylib
然后demux
正确加载库,即使当前目录不是包含demux
的目录。但是,如果sfeMovie
引用了许多其他库,那么您可能仍需要RPATH。