2017-07-14 39 views
1

我們有一個使用R框架的Cocoa應用程序。我們的目的不是將R與應用程序一起發佈,因爲用戶可能會在本地安裝自己的版本。我們所面臨的問題是如何針對具有多個版本的框架適當地減弱鏈接。可可 - 對框架弱鏈接 - 忽略版本?

我們是弱連接攻擊:

  • 框架構建設置設置爲optional在鏈接的二進制
  • 添加爲-weak_framework>其他連接標誌
  • 我們做通常的「類存在」檢測在代碼中嘗試使用R.前

這裏發生了什麼:

  • 如果安裝了與我們鏈接的相同版本的R,則一切正常。
  • 如果沒有安裝R,一切都很好。我們檢測到缺席,並優雅地失敗。
  • 我們的麻煩是當我們鏈接到一個版本(讓我們說3.1)和用戶有不同的版本(讓我們說3.2)。然後我們得到錯誤can't resolve symbol (some sybmol) in (my app) because dependent dylib #1 could not be loaded

我想這是有道理的,因爲我們建立對3.1,它不存在 - 3.2是。我只是不清楚如何正確處理這種外部庫的弱鏈接,並允許它使用不同的版本。或者我完全錯過了如何完全鏈接薄弱的船。這是完全可能的。

非常感謝任何指導。

謝謝

回答

1

@eww和我繼續調查這一點,這裏就是我們能夠找到。當框架和應用程序正在編譯時,它們引用了R.framework的特定版本。我們可以通過運行到看到這一點:

otool -L /Applications/StatTag.app/Contents/Frameworks/RCocoa.framework/RCocoa 
/Applications/StatTag.app/Contents/Frameworks/RCocoa.framework/RCocoa: 
    @rpath/RCocoa.framework/Versions/A/RCocoa (compatibility version 1.0.0, current version 1.0.0) 
    **/Library/Frameworks/R.framework/Versions/3.3/Resources/lib/libR.dylib (compatibility version 3.3.0, current version 3.3.2)** 
    /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1252.0.0) 
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1) 
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1253.0.0) 

經過一番搜索,this post來到了這避讓我們在如何改變R.framework提及是「當前」,而不是特定版本

install_name_tool -change /Library/Frameworks/R.framework/Versions/3.3/Resources/lib/libR.dylib /Library/Frameworks/R.framework/Versions/Current/Resources/lib/libR.dylib /Applications/StatTag.app/Contents/Frameworks/RCocoa.framework/RCocoa 

現在,我們可以看到它引用當前版本的文件夾:

otool -L /Applications/StatTag.app/Contents/Frameworks/RCocoa.framework/RCocoa 
/Applications/StatTag.app/Contents/Frameworks/RCocoa.framework/RCocoa: 
    @rpath/RCocoa.framework/Versions/A/RCocoa (compatibility version 1.0.0, current version 1.0.0) 
    /Library/Frameworks/R.framework/Versions/Current/Resources/lib/libR.dylib (compatibility version 3.3.0, current version 3.3.2) 
    /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1252.0.0) 
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1) 
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1253.0.0) 

什麼絆倒了我們多一點是,當這個被內置到我們的最終應用,T以下是引用RCocoa和R的其他本地框架,這意味着我們必須多次運行install_name_tool。樂於報道的事情現在正在起作用。