OS X 下的共享对象位置有时很棘手。当您直接调用时dlopen()
,您可以自由指定库的绝对路径,这很好。但是,如果您加载一个库,而该库又需要加载另一个库(这似乎是您的情况),那么您将无法控制使用其直接路径指定库所在的位置。
您可以在运行主程序之前设置一些环境变量,告诉动态加载器在哪里搜索东西。一般来说,这些都是一个坏主意(但您可以通过OS X 系统上的man dyld命令了解它们)。
当一个 OS X 动态库被创建时,它被赋予了一个安装名称;此名称嵌入在二进制文件中,可以使用otool
命令查看。otool -L mach-o_binary
将列出您提供文件名的 mach-o 二进制文件的动态库引用;例如,这可以是主可执行文件或 dylib。
当动态库静态链接到另一个可执行文件(主可执行文件或另一个 dylib)时,将找到该 dylib 链接的预期位置基于写入其中的位置(在构建时,或之后应用的更改)。在您的情况下,它似乎phys_services.so
与libphys-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。