12

我是这个领域的新手。我的笔记本电脑是 Macbook air,软件:OS X 10.8.5 (12F45)。我正在运行一个代码,它给了我以下错误:

dlopen(/Users/ramesh/offline/build_icerec/lib/icecube/phys_services.so, 2):库未加载:/Users/ramesh/offline/build_icerec/lib/libphys-services.dylib 引用自:/Users/ramesh/离线/build_icerec/lib/icecube/phys_services.so 原因:找不到图像

我做了谷歌搜索,找到了各种各样的答案。我认为有效的方法是使用

“ -install_name @rpath/lib ”。

我的问题是,如何-install_name @rpath/lib在我的情况下使用?

4

1 回答 1

30

OS X 下的共享对象位置有时很棘手。当您直接调用时dlopen(),您可以自由指定库的绝对路径,这很好。但是,如果您加载一个库,而该库又需要加载另一个库(这似乎是您的情况),那么您将无法控制使用其直接路径指定库所在的位置。

您可以在运行主程序之前设置一些环境变量,告诉动态加载器在哪里搜索东西。一般来说,这些都是一个坏主意(但您可以通过OS X 系统上的man dyld命令了解它们)。

当一个 OS X 动态库被创建时,它被赋予了一个安装名称;此名称嵌入在二进制文件中,可以使用otool命令查看。otool -L mach-o_binary将列出您提供文件名的 mach-o 二进制文件的动态库引用;例如,这可以是主可执行文件或 dylib。

当动态库静态链接到另一个可执行文件(主可执行文件或另一个 dylib)时,将找到该 dylib 链接的预期位置基于写入其中的位置(在构建时,或之后应用的更改)。在您的情况下,它似乎phys_services.solibphys-services.dylib. 因此,首先,运行otool -L phys_services.so以找到dylib 所在位置的确切期望。

install_name_tool命令可用于更改库的预期位置。它可以在静态链接之前针对 dylib 运行(在这种情况下,您无事可做),或者可以针对加载它的可执行文件运行以重写这些期望。用于此的命令模式是install_name_tool -change <old_path> <new_path>因此,例如,如果otool -L phys_services.so向您展示/usr/lib/libphys-services.dylib并且您想要移动您在问题中提出的期望,您可以使用install_name_tool -change /usr/lib/libphys-services.dylib @rpath/lib/libphys-services.dylib phys_services.so.

dyld 手册页(man dyld)会告诉你如何使用@rpath,以及其他宏@loader_path 和@executable_path。

于 2014-03-21T13:30:43.363 回答