有時候我們使用一些第三方預編譯的庫,或者自己編譯的庫放在另外一台機器上時,常常遇到:
dyld: Library not loaded
這類的錯誤,這是因為在 Mac 系統中,默認搜索庫的路徑是 /usr/lib ,並不像 Windows 一樣 dll 放在和 exe 同級目錄下也會被搜索到。
每一個 dylib 庫自身有一個 id 值會告訴可執行文件自己的位置,例如下面是一個 OpenCV 的 cv2.so 庫,我們可以使用如下命令查看其信息:
otool -L cv2.so
信息如下:
/Users/xxx/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)
這個庫是我在另外一台機器編譯的,當時的編譯路徑就是:
/Users/xxx/Documents/Develop/opencv-2.4.9/osx_static/lib/Release/
但是當我在另外一台電腦鏈接這個庫時就會出現 dyld: Library not loaded 錯誤,因為這時這個庫已經不再它自己標識的路徑下了。比如我現在的路徑就是:
/Users/xxx/Documents/Develop/QAR_Animation/QAR/Library/OpenCV/libs/OSX
如何解決呢?
方法1:使用 export 命令將現在目錄添加到系統搜索庫的路徑下:
export DYLD_LIBRARY_PATH=/Users/xxx/Documents/Develop/QAR_Animation/QAR/Library/OpenCV/libs/OSX
但是這種方法顯然很不爽,難道每次都要這樣做么?
方法2:使用 install_name_tool 工具修改 so 庫 id 標識
由於這種方法可以使用相對路徑,同時可以使用 @loader_path 代替可執行文件路徑,因此只需這樣寫:
install_name_tool -id @loader_path/../../../Library/OpenCV/libs/OSX/cv2.so cv2.so
這樣 cv2.so 文件的 id 就被修改成相對路徑。在另外的 Mac 機上,只要相對路徑保持,那么就不會出現這個問題了。
