簡體   English   中英

由於Mach-O標頭中缺少LC_VERSION_MIN,Xcode app存檔驗證因Mac App Store分發而失敗

[英]Xcode app archive validation fails for Mac App Store distribution due to lack of LC_VERSION_MIN in a Mach-O header

我有一個Swift項目,它使用NSTask調用命令行實用程序。

為了便於攜帶,我在應用程序的捆綁資源中包含了該命令行實用程序。

該實用程序非常復雜 - 它是一個Ruby解釋的應用程序,帶有一堆寶石,其中一些具有原生擴展。 這些gem都與Bundler一起安裝到實用程序中的標准供應商/目錄中。

我已經在第二台Mac上成功存檔,驗證,分發和運行應用程序,而第二台Mac上沒有通過開發者ID(“Mac App Store”外部)工作流程安裝的CLI實用程序(或Xcode)多次。

但是,存檔無法驗證Mac App Store分發時出現此錯誤:

2016-08-28 15:26:41 +0000 [MT]呈現:錯誤域= DVTFoundationNSBundleAdditionsErrorDomain Code = 1“無法在Info.plist CFBundleSupportedPlatforms中找到平台族或者在AbstractMemory.o中找到Mach-O LC_VERSION_MIN”UserInfo = {NSLocalizedDescription =無法在Info.plist CFBundleSupportedPlatforms中找到平台族或者在AbstractMemory.o中找到Mach-O LC_VERSION_MIN}

那么......為什么app工作流驗證會在MAS工作流程中失敗,而不是Developer ID工作流程會出現這樣的錯誤?


潛在的有趣點:

  • 該應用程序使用1個臨時例外權利讓它在主文件夾中讀取和寫入特定文件夾,而不必嘮叨用戶進行訪問。
  • 該應用程序不使用任何MAS特定功能/權利。
  • AbstractMemory.o是FFI ruby​​ gem的本機擴展的一部分,由CLI實用程序使用。
  • 我已嘗試使用設置為DWARF的調試信息格式進行驗證,也嘗試使用DWARF + dSYM進行驗證,但同樣的問題也會發生。
  • 沒有.dSYM文件在“復制包資源”設置中明確列出(盡管它們可能隱藏在CLI可執行文件的文件夾或gem本機擴展中)。
  • Xcode似乎鎖定了原生擴展的某些位,並嘗試以特殊方式處理它們。 以下位被提升到驗證對話框中“二進制和權利”列表的頂層,就在主.app工件下面,而其他位(如gem依賴文件夾中的純文本文件)不是:
    • 可執行文件(例如iconvxmlcatalog
    • .o文件(例如AbstractMemory.o
    • .bundle文件(例如ffi_c.bundlenokogiri.bundle
    • .dylib文件(例如libcapi.dyliblibcharset.dylib
    • .a文件(例如libcharset.a
  • 在“二進制和權利”列表中,主.app顯示為具有預期數量的權利(我添加的權限),但可執行文件.o,.a,.bundle和.dylib文件顯示為具有0權利。

TLDR

依賴項目最初是使用舊版本的Xcode和OS X編譯的,因此其中的許多Mach-O可執行文件在其標題中沒有LC_VERSION_MIN_MACOSX加載命令。 基本上我必須找到一種方法來擠壓該命令。

唯一可靠且干凈的方法是使用Xcode 7構建工具重新編譯依賴項目中的所有本機代碼。 如果依賴項是開源的,您可以自己完成。 如果不是,您將不得不懇求您的軟件供應商。

如果您需要Yosemite部署目標兼容性,您可能會冒險並在Yosemite構建框上使用Xcode 7.1 GM。 但我建議您在El Capitan構建盒上使用Xcode 7.1+重新編譯代碼,以確保您的二進制依賴性能與SIP等El Capitan之類的東西相媲美。

細節

就我而言,依賴項目是開源的,所以我能夠:

  1. 在GitHub上查找其源代碼。
  2. 叉吧。
  3. 構建項目而不對OS X版本進行任何更改,盡可能地匹配第三方開發人員最初在其構建框上使用的版本來編譯依賴項。
  4. 當(如果)失敗時查看構建日志。
  5. 進行所有必要的更改以使構建變為綠色。 您現在已經與使用的原始構建框達到了奇偶校驗。
  6. 現在將構建框OS X版本更新為Yosemite + Xcode 7.1 GM(如果必須具有Yosemite兼容性)或El Capitan + Xcode 7.1+。
  7. 重建,修復,yada yada。
  8. 當它再次變為綠色時,抓取新編譯的二進制工件。
  9. 在bundle中找到Mach-O可執行文件。
  10. 運行otool -l [path to executable]
  11. 在Mach-O標頭加載命令的大清單中,您現在應該看到LC_VERSION_MIN_MACOSX為10.10或10.11(取決於您使用的內容)。
  12. 你的二元文物應該很好用。

通過使用Travis CI的Mac構建機隊,我能夠設置多個OS X構建VM而不會生氣。

剩下的非showstopper問題

必須取消“包含用於調試的符號”以進行存檔驗證或導出。 這是因為符號化器無法處理第三方目標代碼。 我想這是因為它是為發布而構建的,因此目標代碼沒有附帶任何附帶的調試符號。

如果您無法重新編譯代碼

如果您無法重新編譯代碼,我聽說有關於可以將Mach-O加載命令加載到預先存在的二進制文件中的骯臟變通方法的傳聞。 這會遇到以下問題:

  • 這種方法非常脆弱,因為它依賴於新的加載命令在標題中留下足夠的空白位。 不出所料,我聽說修改現有加載命令的值往往比插入新命令更可靠。
  • 二進制不得已經簽約。 Gatekeeper將立即拒絕在簽名后以任何方式被篡改的二進制文件。
  • Mach-O頭重寫不是一項簡單的任務,因此它往往是在第三方工具的幫助下完成的。 如果您不習慣在二進制+十六進制編輯器級別工作,那么很難驗證這些工具的功能,因此您將非常信任它們(a)正確地執行此操作(b)沒有做任何邪惡的事。

額外的討論

我將此問題交叉發布到Apple開發人員論壇, 網址https://forums.developer.apple.com/message/175427 ,看看是否會由更專業的社區更快地得到答復。 事實並非如此,但您可以通過該鏈接找到對該問題的進一步討論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM