[Mac] 修正链接 dylib/so 库时 "dyld: Library not loaded" 问题
2015年1月8日
有时候我们使用一些第三方预编译的库,或者自己编译的库放在另外一台机器上时,常常遇到:
1 | dyld: Library not loaded |
这类的错误,这是因为在 Mac 系统中,默认搜索库的路径是 /usr/lib ,并不像 Windows 一样 dll 放在和 exe 同级目录下也会被搜索到。
每一个 dylib 库自身有一个 id 值会告诉可执行文件自己的位置,例如下面是一个 OpenCV 的 cv2.so 库,我们可以使用如下命令查看其信息:
1 | otool -L cv2.so |
信息如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | cv2.so: /Users/valiantliu/Documents/Develop/opencv-2.4.9/osx_static/lib/Release/cv2.so (compatibility version 0.0.0, current version 0.0.0) /System/Library/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.6) /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 21.0.0) /System/Library/Frameworks/QTKit.framework/Versions/A/QTKit (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore (compatibility version 1.2.0, current version 1.10.0) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1343.14.0) /System/Library/Frameworks/OpenCL.framework/Versions/A/OpenCL (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1151.16.0) /System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo (compatibility version 1.2.0, current version 1.8.0) /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1151.16.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) |
这个库是我在另外一台机器编译的,当时的编译路径就是:
1 | /Users/valiantliu/Documents/Develop/opencv-2.4.9/osx_static/lib/Release/ |
但是当我在另外一台电脑链接这个库时就会出现 dyld: Library not loaded 错误,因为这时这个库已经不再它自己标识的路径下了。比如我现在的路径就是:
1 | /Users/skylook/Documents/Develop/QAR_Animation/QAR/Library/OpenCV/libs/OSX |
如何解决呢?
方法1:使用 export 命令将现在目录添加到系统搜索库的路径下:
1 | export DYLD_LIBRARY_PATH=/Users/skylook/Documents/Develop/QAR_Animation/QAR/Library/OpenCV/libs/OSX |
但是这种方法显然很不爽,难道每次都要这样做么?
方法2:使用 install_name_tool 工具修改 so 库 id 标识
由于这种方法可以使用相对路径,同时可以使用 @loader_path 代替可执行文件路径,因此只需这样写:
1 | install_name_tool -id @loader_path/../../../Library/OpenCV/libs/OSX/cv2.so cv2.so |
这样 cv2.so 文件的 id 就被修改成相对路径。在另外的 Mac 机上,只要相对路径保持,那么就不会出现这个问题了。
参考文献:
http://www.zhaoxiaodan.com/mac/ios/macos%E5%8A%A8%E6%80%81%E5%BA%93%E5%8A%A0%E8%BD%BD%E5%88%86%E6%9E%90.html