Bitcode

Xcode7.0开始,新建项目默认就打开了bitcode设置(Build Settings->Enable Bitcode),但到现在还是有很多第三方库不支持bitcode,从而导致编译失败,出现以下错误:

ld: '/Users/admin/Desktop/iOS_iat1166_5b065c4c/lib/iflyMSC.framework/iflyMSC(IFlyAudioSession.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

此时,要么让第三方库支持,要么关闭target的bitcode功能,对于iOS来说,bitcode是可选的(watchOS必须支持bitcode,Mac OS不支持bitcode),我都是选择关闭bitcode功能,全部不生成bitcode。但是bitcode是什么,这还是要知道一下的。

什么是bitcode?

LLVM是目前苹果采用的编译器工具链,LLVM的前端可以理解为C/C++/OC/Swift等编程语言,LLVM的后端可以理解为各个芯片平台上的汇编指令或者可执行机器指令数据,那么,bitcode就是位于这两者之间的中间码。LLVM的编译工作原理是前端负责把项目程序源代码翻译成bitcode中间码,然后再根据不同目标机器芯片平台转换为相应的汇编指令以及翻译为机器码。这样设计就可以让LLVM成为了一个编译器架构,可以轻而易举的在LLVM架构之上发明新的语言(前端),以及在LLVM架构下面支持新的CPU(后端)指令输出,虽然bitcode仅仅只是一种中间码,不能在任何平台上运行,但是它可以转化为任何被支持的CPU架构,包括现在还没被发明的CPU架构,也就是说现在打开bitcode功能提交一个App到应用商店,以后如果苹果新出了一款手机并CPU也是全新设计的,在苹果后台服务器一样可以从这个APP的bitcode开始编译转化为新CPU上的可执行程序,可供新手机用户下载运行这个App。

在App Distribution Guide – App Thinning (iOS, watchOS)一节中,找到了下面这样一个定义:

Bitcode is an intermediate representation of a compiled program. Apps you upload to iTunes Connect that contain bitcode will be compiled and linked on the App Store. Including bitcode will allow Apple to re-optimize your app binary in the future without the need to submit a new version of your app to the store.

bitcode是被编译程序的一种中间形式的代码。包含bitcode配置的程序将会在App store上被编译和链接。bitcode允许苹果在后期重新优化我们程序的二进制文件,而不需要我们重新提交一个新的版本到App store上。

继续看,在What’s New in Xcode-New Features in Xcode 7中,还有一段如下的描述

Bitcode. When you archive for submission to the App Store, Xcode will compile your app into an intermediate representation. The App Store will then compile the bitcode down into the 64 or 32 bit executables as necessary.

当我们提交程序到App store上时,Xcode会将程序编译为一个中间表现形式(bitcode)。然后App store会再将这个bitcode编译为可执行的64位或32位程序。


Bitcode_第1张图片
bitcode
支持bitcode(这个还需要考证)

在Build Options中启用bitcode,且使用Build而非Archive编译时,Xcode会自动添加编译选项-fembed-bitcode-marker,这个选项的意思大概就是说:如果bitcode开启的话,这里本来应当是放bitcode的,实际上没放。
在Build Options中启用bitcode,且使用Archive编译时,Xcode会自动添加编译选项-fembed-bitcode,此时才是真正开启了bitcode。
如果编译选项设置-fembed-bitcode-marker,编译成功后上传iTunes Connect,就会出现错误。
如果使用Build编译想强制开启-fembed-bitcode,只需在Target->Build Settings->Custom Compiler Flags->Other C Flags中加入-fembed-bitcode即可。
相关讨论可以参考How do I xcodebuild a static library with Bitcode enabled?

需要注意的是bitcode只在archive编译时生效,如果您开发的是app那么走正常的打包archive流程就好了,如果你正在开发.a静态库或者framework,请注意打包方式设置为archive,或者在打包脚本中加入-fembed-bitcode参数。

检查第三方库是否支持bitcode

使用otool工具来检查二进制文件中是否包含bitcode段。
针对于静态链接库.a文件:
otool -arch armv7 -l xxxx.a | grep __bitcode | wc -l
如果是当前库支持bitcode,会输出一个大于0的数字,不支持的话输出0。

另外更准确的方法,查看参考文章。

参考文章:
《Bitcode适配指南》
《理解Bitcode:一种中间代码》
《深入理解iOS开发中的BitCode功能》
《判断一个库是否包含 bitcode》

你可能感兴趣的:(Bitcode)