在Mac上使用完整路径连接动态库

23

我使用以下命令(由cmake生成)链接了一个嵌入Matlab引擎的Python扩展库。

c++ -mmacosx-version-min=10.6 -bundle -headerpad_max_install_names  -o library.so library.o /Applications/MATLAB_R2009b.app/bin/maci64/libeng.dylib /Applications/MATLAB_R2009b.app/bin/maci64/libmx.dylib -framework Python

导致

$ otool -L library.so
library.so:
    @loader_path/libeng.dylib (compatibility version 0.0.0, current version 0.0.0)
    @loader_path/libmx.dylib (compatibility version 0.0.0, current version 0.0.0)
    /System/Library/Frameworks/Python.framework/Versions/2.6/Python (compatibility version 2.6.0, current version 2.6.1)
    /opt/local/lib/gcc44/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.13.0)
    /opt/local/lib/gcc44/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.0)

然而,当我尝试使用该库时,我收到了一个错误信息:

ImportError: dlopen(./library.so, 2): Library not loaded: @loader_path/libmex.dylib
  Referenced from: ./library.so
  Reason: image not found

我认为问题出在链接器使用形式为@loader_path/libeng.dylib的matlab dylib文件,而不是使用完整路径,即使我已经向g++提供了完整路径。如何强制链接器使用完整路径?

我知道一种解决方案是使用

export DYLD_LIBRARY_PATH=/Applications/MATLAB_R2009b.app/bin/maci64:$DYLD_LIBRARY_PATH

那些库文件所在的位置是这里,但我希望避免使用它们,因为这会引起其他问题。


请参考我在这个链接中的回答:[Add_libray][1] [1]: https://dev59.com/7m445IYBdhLWcg3wZJiw#19245310 - itechnician
4个回答

33

使用 install_name_tool 手动更改文件

install_name_tool -change "@loader_path/libeng.dylib" "/Applications/MATLAB_R2009b.app/bin/maci64/libeng.dylib" library.so 
install_name_tool -change "@loader_path/libmx.dylib" "/Applications/MATLAB_R2009b.app/bin/maci64/libmx.dylib" library.so 

我可以将此用作临时解决方案,但我想知道是否存在更好的解决方案,其中链接器被给予使用完整路径的设置。


2
这很有用,但你说得对,应该有一种在CMake中实现这个的方法。 - eqzx
最终我需要执行反向操作;将绝对路径替换为涉及@loader_path的路径。dyld手册在解释dyld关于绝对路径和扩展@loader_path的行为方面非常有帮助。 - nornagon
使用install_name_tool的问题在于,如果库文件已经进行了代码签名,它就无法按预期工作,对吗? - noripcord

7
请注意,使用 DYLD_FALLBACK_LIBRARY_PATH 可以防止一些与 DYLD_LIBRARY_PATH 相关的问题。仅当在默认路径中找不到库时才会使用该路径。

使用这个命令刚刚打破了我所在的shell,并给了我以下错误信息: python dyld: Library not loaded: @loader_path/../lib/libpython2.7.dylib Referenced from: .../bin/python Reason: image not found Trace/BPT trap: 5 - Chris Withers

5
请查看ld命令的-rpath选项来控制此问题。您可能还会对https://github.com/bimargulies/jni-origin-testbed的内容感兴趣,这是一些相关技术的演示。
关键技术如下:
install_name_tool -change libsl2.so "@loader_path/libsl2.so" libsl1.so

1
你能再详细说明一下吗?我也遇到了同样的问题。我感觉我的构建项目中有几个路径没有指向正确的位置! - Yasin

-1

你也可以使用符号链接!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接