iOS中動/靜態庫支援bitcode的問題

summer_liu_liu發表於2018-03-22

最近,在將工程中的幾個基礎庫打包成動態庫,減少二進位制包大小。在本機build時沒出現啥問題。但是在jenkins上打包,卻出現瞭如下錯誤:

Error Domain=IDEFoundationErrorDomain Code=1 "Failed to verify bitcode in FLAnimatedImage.framework/FLAnimatedImage:
error: Bundle only contains bitcode-marker 
複製程式碼

經搜尋,發現跟bitcode相關。因為這些庫預設是支援bitcode的,在build時,compile的引數是-fembed-bitcode-marker,它的意思只是標記二進位制檔案中有bitcode,但是實際上沒有內容,一般用於測試。

而我們在jenkins上打包時,先archive,然後再匯出ipa包,而archive的編譯引數是-fembed-bitcode,所以與本地除錯不太一樣。

那麼,這兩個引數有什麼區別呢?

[StackOverFlow上的回答](https://stackoverflow.com/questions/31233395/ios-library-to-bitcode)說的比較清楚。

• -fembed-bitcode-marker simply marks where the bitcode would be in the binary after an archive build. • -fembed-bitcode actually does the full bitcode generation and embedding, so this is what you need to use for building static libraries. • Xcode itself builds with -fembed-bitcode-marker for regular builds (like deploy to simulator) • Xcode only builds with -fembed-bitcode for archive builds / production builds (as this is only needed for Apple).

-fembed-bitcode-marker會生成一個最小bitcode的section,但是沒有任何內容,size=1。

-fembed-bitcode則會生成bitcode的相關內容。

You should be aware that a normal build with the -fembed-bitcode-marker option will produce minimal size embedded bitcode sections without any real content. This is done as a way of testing the bitcode-related aspects of your build without slowing down the build process. The actual bitcode content is included when you do an Archive build.

所以我們在打包lib的時候,需要設定引數-fembed-bitcode,這樣才會包含bitcode的內容。

因此,解決方案有兩種:

  • 禁用bitcode

  • 設定引數-fembed-bitcode

如何設定引數

由於我是基於pod package來打包,所以需要需改podspec檔案,新增xcconfig即可。

s.xcconfig = {'BITCODE_GENERATION_MODE' => 'bitcode'}
複製程式碼

這裡插一句,在用pod package打包時,如果依賴的庫是動態庫時,會有問題,我自己將原始碼改了下,會另外寫一篇文章說說。

如果你是通過xcodebuild來打包lib的話,可以在build setting的User-Define Setting中新增,這樣在build的時候也會是-fembed-bitcode

'BITCODE_GENERATION_MODE' => 'bitcode'
複製程式碼

如下圖:

iOS中動/靜態庫支援bitcode的問題

如果想讓引數是-fembed-bitcode-marker,設定為marker

'BITCODE_GENERATION_MODE' => 'marker'
複製程式碼

這張圖表達的比較清晰:

bitcode.png

另外還有一個種方式是直接在Other C flags裡設定,網上說會產生warning。不過我還沒嘗試過。推薦使用設定BITCODE_GENERATION_MODE的方式。

(When I tested using the -fembed-bitcode on the Other C flags, Xcode gave the warning clang: warning: argument unused during compilation: '-fembed-bitcode-marker')

如何檢查生成的lib是否正確

可通過以下方式檢視,打出的lib引數是-fembed-bitcode-marker還是-fembed-bitcode

在terminal中輸入

otool -arch armv7 -l xx.a/xx.framework
複製程式碼

注意:如果lib包含了模擬器架構,則需要指定相應真機的arch才能看得到。

然後,Ctrl+F,搜尋__bundle,應該會出現以下內容:

Section
 sectname __bundle
  segname __LLVM
     addr 0x0002c000
     size 0x000b0a09
   offset 180224
    align 2^0 (1)
   reloff 0
   nreloc 0
    flags 0x00000000
reserved1 0
reserved2 0
複製程式碼

如果size不為1,則說明是-fembed-bitcode

如果結果如下圖,則是-fembed-bitcode-marker,說明我們打的包不對。

bundle.png

另外,如果要檢視lib是否支援bitcode,可執行如下命令,檢視是否有__LLVM

otool -arch armv7 -l xx.a/xx.framework | grep __LLVM
複製程式碼

相關文章