Mac dylib動態庫載入路徑問題(以OpenCV為例)
在自己的Mac上寫了一個基於OpenCV的簡單程式;需要傳給其他人共同除錯,但是可執行檔案在他人的Mac上無法執行;執行時會提示:
dyld: Library not loaded: /usr/local/Cellar/opencv/2.4.12/lib/libopencv_features2d.2.4.dylib
這樣就引申出來一個問題:在xcode下編譯出的程式,在開發機器上執行是沒有問題的。但是給其他使用者用,就可能出問題。因為使用者不一定有這個庫。
有兩種方法可以解決這個問題;一是給其他使用者也安裝依賴的庫檔案;二是將所有的dylib隨行釋出,消除依賴。
第一種方案不考慮,大部分時候這樣做並不現實;下面說說如何隨行釋出dylib。
單純將依賴的dylib檔案拷貝到可執行檔案目錄下一同傳輸過去是不能消除依賴的;執行的時候還是報錯;
在編譯一個動態庫的時候, 你需要指定 INSTALL_PATH. 也就是它的安裝路徑;編譯完成後如果一個可執行程式使用了該動態庫, 那麼在編譯可執行程式的時候, 動態庫的 INSTALL_PATH 會被記錄到可執行程式中, 用來定位這個動態庫。
因此我們首先需要將用到的dylib檔案都拷貝到可執行檔案目錄下,然後改變動態庫的INSTALL_PATH;將其改到可執行檔案所在目錄;
需要注意的是:如果依賴多個動態庫,用到的動態庫已會依賴其他動態庫,因此用到的所有的動態庫的依賴動態庫路徑都需要修改。
以OpenCV為例子,假設最終編譯出來的可執行檔案為 macimgproc
;執行命令:otool -L macimgproc
可看到如下的輸出:
macimgproc:
/usr/local/opt/opencv/lib/libopencv_calib3d.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_contrib.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_core.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_features2d.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_flann.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_gpu.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_highgui.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_imgproc.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_legacy.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_ml.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_nonfree.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_objdetect.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_ocl.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_photo.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_stitching.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_superres.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_video.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_videostab.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.4.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
說明macimgproc依賴所有的OpenCV動態庫檔案;因此首先需要將所有動態庫檔案拷貝到macimgproc所在目錄,然後需要將macimgproc檔案中的所有/usr/local/opt/opencv/lib/libopencv_xxx
修改為@executable_path/libopencv_xxx
;
@executable_path
表示可執行檔案所在目錄;指示所有OpenCV動態庫從可執行檔案所在目錄查詢;
更多@executable_path
的介紹以及其他變數參見文章 @rpath, @loader_path, @executable_path。
使用命令install_name_tool -change {old.dylib} {new.dylib} {filename}
修改動態庫的INSTALL_PATH,例如:
install_name_tool -change /usr/local/Cellar/opencv/2.4.12/lib/libopencv_flann.2.4.dylib @executable_path/libopencv_flann.2.4.dylib macimgproc
執行後重新otool -L macimgproc
可看到如下的輸出:
macimgproc:
...
/usr/local/opt/opencv/lib/libopencv_features2d.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
@executable_path/libopencv_flann.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/opt/opencv/lib/libopencv_gpu.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
...
依次修改所有依賴即可。
整個OpenCV庫大概有19個dylib檔案,因此寫了一個簡單的批量修改指令碼:
#!/usr/bin/ruby
Preview=0
def fix_opencv_lib_link(file,rlib)
if(rlib.include?('libopencv'))
name = rlib.split('/').last
cmd = "install_name_tool -change #{rlib} @executable_path/#{name} #{file}"
if Preview == 1
puts "Preivew: #{cmd}"
else
`#{cmd}`
end
else
puts "ignore rlib: #{rlib}";
end
end
def fix_file_rely_lib(file)
puts "===============start change #{file}==============="
linklibs = `otool -L #{file}`.split("\n")
linklibs.delete_at(0)
linklibs.each_with_index do |rlib,i|
rlib = rlib.split()[0]
fix_opencv_lib_link(file,rlib)
end
end
def doopencvlist
# puts "Preview: #{Preview}"
`ls |grep libopencv`.split().each_with_index do |file,i|
fix_file_rely_lib(file)
end
end
def viewlib(file)
puts `otool -L #{file}`
end
if __FILE__ == $0
if ARGV[0] == 'preview'
Preview = 1;
doopencvlist();
elsif ARGV[0] == 'view'
`ls |grep libopencv`.split().each_with_index do |file,i|
# puts "===============start view #{file}==============="
viewlib(file)
end
elsif ARGV[0] == 'do'
doopencvlist();
elsif ARGV[0] == 'previewfile'
Preview = 1;
fix_file_rely_lib(ARGV[1])
elsif ARGV[0] == 'file'
fix_file_rely_lib(ARGV[1])
else
puts "please input command [preview,do,previewfile,file,view] "
end
end
參考連結
http://blog.csdn.net/openglnewbee/article/details/17783909
如何使用第三方的dylib
@rpath, @loader_path, @executable_path
Apple Developer:Overview of Dynamic Libraries
Apple Developer: Run-Path Dependent Libraries
相關文章
- 為.Net專案新增動態庫載入路徑
- Jtti:linux怎麼更改預設的動態庫載入路徑?JttiLinux
- QtCreator 跨平臺開發新增動態庫教程(以OpenCV庫舉例)- Windows篇QTOpenCVWindows
- vue render載入img的src路徑問題Vue
- DLL動態庫動態載入
- QLibrary 載入動態庫
- 以opencv為例說明cmake中的findpackage()OpenCVPackage
- 路徑問題
- QML中載入圖片不顯示,路徑出錯問題
- 使用dlopen載入動態庫
- 動態頁面資料載入不全的問題
- 領域驅動設計問題域分析-以bilibili OGV業務為例
- opencv - 1 - 初入門徑OpenCV
- 遞迴路徑問題遞迴
- 資源路徑問題
- 分散式資料庫入門:以國產資料庫 TDSQL 為例分散式資料庫SQL
- Android native層動態載入so庫Android
- 蟻群演算法介紹(以TSP問題為例)演算法
- 關於顯示載入動態連結庫模組及解除安裝的問題
- qt5.14.2 MSVC opencv(不結合vs)路徑新增問題 測試透過QTOpenCV
- laravel 載入 bootstrap js庫的問題LaravelbootJS
- 演算法——路徑問題演算法
- 載入動態連結庫——dlopen dlsym dlclose
- Mac使用Docker時,卷預設掛載路徑/var/lib/docker/volumes不存在問題MacDocker
- 啟動優化之動態庫延遲載入優化
- 動態規劃---例題3.最大子段和問題動態規劃
- .Net Core利用反射動態載入類庫的方法(解決類庫不包含Nuget依賴包的問題)反射
- drozer模組的編寫及模組動態載入問題研究
- 檔案路徑問題( ./ 和 ../ 和 @/ )
- VsCode相對路徑的問題VSCode
- Linux執行時動態庫搜尋路徑優先順序Linux
- 遞迴、迭代和動態規劃:以九宮格鍵盤為例遞迴動態規劃
- 探索 React Native 的 bundle 載入路徑React Native
- QT 檔案相對路徑載入QT
- 動態載入UserControl
- 以MySQL為例,來看看maven-shade-plugin如何解決多版本驅動共存的問題?MySqlMavenPlugin
- 瀏覽器解析html檔案src靜態資源路徑問題瀏覽器HTML
- 微服務架構 | *2.3 Spring Cloud 啟動及載入配置檔案原始碼分析(以 Nacos 為例)微服務架構SpringCloud原始碼
- iOS中動/靜態庫支援bitcode的問題iOS