首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RPATH未能扩展

RPATH未能扩展
EN

Stack Overflow用户
提问于 2014-03-07 21:51:54
回答 2查看 1.5K关注 0票数 3

我在OS上构建了一个可执行文件(名为demux),它总是无法加载,我找不到原因:

代码语言:javascript
复制
$ ./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显示了以下内容:

代码语言:javascript
复制
$ 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)

和:

代码语言:javascript
复制
$ 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/…)在可执行文件的旁边。要确保此运行时搜索路径正确,请执行以下操作:

代码语言:javascript
复制
$ 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?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-08 00:26:00

我用一个快速的测试项目重现了你的问题。当我将尾随斜杠附加到LD_RUNPATH_SEARCH_PATH构建设置时,它是固定的。

而不是:

代码语言:javascript
复制
@executable_path

你应该试试

代码语言:javascript
复制
@executable_path/

otool -l的输出现在如下所示:

代码语言:javascript
复制
      cmd LC_RPATH
  cmdsize 32
     path @executable_path/ (offset 12)

通常,您可以在https://github.com/liyanage/macosx-shell-scripts/blob/master/checklibs.py上使用我的dyld分析器脚本检查toplevel可执行文件(在本例中为"demux")。

代码语言:javascript
复制
./checklibs.py demux

这个工具试图忠实地再现dyld的解析逻辑。它通常可以提供一个提示,说明哪些引用不起作用,但在这种情况下,它没有发现丢失的拖尾斜杠的问题。我将相应地更新它,以匹配dyld的行为。

票数 4
EN

Stack Overflow用户

发布于 2014-03-07 23:14:40

demux包含一个@rpath链接,RPATH包含@executable_path,但是dyld手册页说,“您甚至可以添加一个以@loader_path开头的LC_RPATH加载命令路径”,这似乎意味着在RPATH中@executable_path是不允许的。

如果demux直接包含@executable_path而不是间接定向到RPATH,那么它就能工作了。

有关血淋淋的细节,请参阅曼迪尔德dyld.cpp

如果这是demux.c

代码语言:javascript
复制
#include <stdio.h>

int foo();

int main() {
    printf("%d\n", foo());
}

这是lib/sfeMovie.c

代码语言:javascript
复制
int foo() {
    return 42;
}

这是你的Makefile

代码语言:javascript
复制
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。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22261396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档