关于Bitcode的探索

Bitcode概述

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 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.

Xcode hides symbols generated during build time by default, so they are not readable by Apple. Only if you choose to include symbols when uploading your app to iTunes Connect would the symbols be sent to Apple. You must include symbols to receive crash reports from Apple.

上述引自Apple的文档 App Thinning (iOS, tvOS, watchOS)

其大概意思是Bitcode类似于一个中间码,被上传到applestore之后,苹果会根据下载应用的用户的手机指令集类型生成只有该指令集的二进制,进行下发。从而达到精简安装包体积的目的。

Bitcode是LLVM编译器中间代码的编码。LLVM的前端可以理解编程语言,这些程序用于编写应用。在后端LLVM能够理解如何展示用户所下载的应用的可执行版本。Bitcode就介于这两步之间。

LLVM 将一款应用的源代码转变成Bitcode,然后再将Bitvode转换成可执行应用。这样的设计让它可以轻易增加支持新语言(前端)以及新的CPU(后端)。虽然Bitcode不能在任何平台上运行,但是它可以转化成任何被支持的 CPU 架构,包括在应用提交到应用商店之前还没有推出的架构。

一点编译原理

为了更好的理解什么是bitcode,我们简短的看一下编译器编译的过程:

  • Lexer :读入源文件,并将其转化成字符流
  • Parser :将字符流转换成AST(抽象语法树
  • Semantic Analysis: 对输入的AST进行语法检查。
  • Code Generation: 代码生成,将AST转换成低层次的IR指令
  • Optimization: 分析IR指令,将其中潜在会拖慢运行速度的指令干掉。
  • AsmPrinter: 通过IR(中间码)生成特定CPU架构的汇编代码
  • Assemble: 将汇编代码转化成二进制
  • Linker: 通常程序会引用其他的二进制文件(.a或者framework),但是这些链接在程序中没有正确的地址,只是个占位符。Linker的工作就是给这些占位符正确的地址。

一般情况下,在真实的编译器构架那种,会将上述过程分成前端和后端两部分来处理:

在前后端之间传递的就是IR(中间码),而bitcode就是一种特殊形式的中间码。原本前后端的工作都是在本地LLVM中完成,虽然Apple没有给出具体的Bitcode实现,但是通过他们的文档可以猜测,是将一部分后端的工作移到了服务器进行。从Xcode上传IR到服务器,服务器来真对不同的机型进行后续操作。从而达到真对不同机型生成对应指令集的二进制,而减小报体积的目的。

打开bitcode设置

实际上在Xcode 7中,我们新建一个iOS程序时,bitcode选项默认是设置为YES的。我们可以在”Build Settings”->”Enable Bitcode”选项中看到这个设置。

不过,我们现在需要考虑的是三个平台:iOS/Mac OS/watchOS。

  • 对应iOS,bitcode是可选的。
  • 对于watchOS,bitcode是必须的。
  • Mac OS不支持bitcode。

如果我们开启了bitcode,在提交包时,下面这个界面也会有个bitcode选项:

但是如果其中包含第三方库,不支持bitcode时候。需要将”Enable BitCode”设置成NO。而且这个选项是,只要有一个第三方库不支持,就不能开的。否则连接错误。

确保打包的时候使用的是fembed-bitcode, 而不是fembed-bitcode-maker

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.

  • fembed-bitcode-maker:只是简单的标记一下在archive出来的二进制中bitcdoe所在的位置。
  • fembed-bitcode: 真的会生成bitcode指令,并且嵌入到二进制中,这个设置不止要在app中设置,同样你也必须在编译静态链接库的时候使用。而且需要主题的是该参数系统只默认在archive模式下会添加

需要注意的是bitcode只默认在archive下编译。在debug和release下并不会。

如果您开发的是app那么走正常的打包archive流程就好了。如果你正在开发.a静态库或者framework,请注意打包方式设置为archive,或者在打包脚本中加入-fembed-bitcode参数。如果需要的话,需要在Build Settings中打开 DEPLOYMENT_POSTPROCESSING=YES,设置Strip Style为debugging。

检测是否打开Bitcode

当打开bitcdoe选项之后,我们可以使用otool工具来检查二进制文件中是否包含bitcode段。

针对于静态链接库.a文件

otool -arch armv7 -l xxxx.a | grep __bitcode | wc -l

如果是当前库支持.a文件则会输出一个数字

如果不支持bitcode则不会出现该数字。

上述命令只检查了armv7架构,同时,也必须使用改指令检查其他的指令集是否包含bitcode如:arm64,armv7s等等

检查app或者framework中是否包含bitcode

由于app中二进制和framework中二进制文件与.a文件存在差异,因为需要检查的是__LLVM段,当出现该段的时候,则表示支持bitcdoe,否则不支持。

otool -l xxxx | grep __LLVM | wc -l

这里otool有个bug,当你的framework使用过lipo命令,进行拆解和合并之后,需要指定指令集进行检查才可以。

otool -arch armv7 -l xxxx | grep __LLVM | wc -l

BUT, 上述检查过了之后,也不一定是真的支持bitcode,在实际的测试中,发现上述检测命令通过之后,某个使用的第三方库,依然报错不支持bitcode。因而最终结果,还是需要以是否能够连接成功为准。重要事情说三遍,上述网上流传的检测方法只做参考,最终还是要以实际效果为准。

最终结果检查

如果您是一个APP,可以直接进行Archive打包,如果是一个库,则建议建一个Demo工程进行打包,记得要打开bitcode设置。

CheckPoint1 连接是否报错

如果有任何一个库没有打开bitcode链接,将会出现类似下方的错误。只要链接过了,那么恭喜了,基本上是OK了。

以上文章摘自:http://www.cocoachina.com/ios/20151201/14432.html  感谢

时间: 2024-10-24 07:11:33

关于Bitcode的探索的相关文章

GLSProv WebUI Framework 探索阶段成果所得(1)

作为我的处子随笔,我就凭着我所想到的记录一下这段时间探索我所做的这个Feature的历程以及所学,所感. 先说一下背景,Provisiong一直是我们COM组项目里比较重要的配置环节,诞生10来年,一直是Java Swing作为主要的GUI界面,配合后台的OMCP Server 与网元以及数据库打交道.自从COM web 化以来,Swing Gui 从纯Java 演变为了WEB Swing, 但是本质上并没有什么变化, 较差的客户体验一直让老美不爽,所以经"董事会"们开会研究,先拿规模

使用Visual Studio快速开发STM32F4-Discovery探索板入门

本本将主要介绍如何使用Visual Studio创建一个基于STM32F4-Discovery探索板的简单工程. 本文使用以下硬件和软件: ●      Microsoft Visual Studio ●      VisualGDB ●      STM32F4-Discovery探索板 我们将创建一个简单的“LED闪烁”的工程,然后进行构建,并使用调试器进行单步调试. 1.    启动Visual Studio.选择File-> New-> Project. 2.    选择VisualG

数据探索

一.查看数据 首先,我们查看iris数据集的大小和结构,其维度和名称分别使用函数dim()和names()获取. 函数str()和attributes()返回数据的结构和属性 二.单变量分析 > head(iris) Sepal.Length Sepal.Width Petal.Length Petal.Width Species1 5.1 3.5 1.4 0.2 setosa2 4.9 3.0 1.4 0.2 setosa3 4.7 3.2 1.3 0.2 setosa4 4.6 3.1 1.

地统计分析笔记——探索数据

来自:http://blog.csdn.net/kikitamoon/article/details/49925147 在执行地统计分析之前,浏览.熟悉.检查自己的数据是至关重要的.绘制和检查数据是地统计分析过程中的必要阶段,我们可以从这些工作中获得一些先验知识,指导后续的工作. Stage 1 绘制数据 通过ArcMap的图层渲染方案绘制数据,我们可以获得对数据的第一印象. 例如,使用单一符号渲染了解采样点的疏密分布,通过分类渲染了解采样点高值低值的分布,等等. Stage 2 检查数据 绘制

C++随笔:.NET CoreCLR之GC探索(2)

首先谢谢 @dudu 和 @张善友 这2位大神能订阅我,本来在写这个系列以前,我一直对写一些核心而且底层的知识持怀疑态度,我为什么持怀疑态度呢?因为一般写高层语言的人99%都不会碰底层,其实说句实话,我以前也不看这些东西,只是因为自己觉得对C++感兴趣,索性乱写点东西,如果有写得不好的地方,还请上面2位大神指出. 其实我现在虽然写的是C++,但是我打算在后面把C++和.NET的一些基础类库融合起来,我发现写CLR的文章特别少,不知道什么原因.反正,废话不多,开始今天的写作吧,今天依然是把重点集中

探索Oracle之数据库升级二 11.2.0.3升级到11.2.0.4完整步骤

探索Oracle之数据库升级二  11.2.0.3升级到11.2.0.4完整步骤 说明:         这篇文章主要是记录下单实例环境下Oracle 11.2.0.1升级到11.2.0.3的过程,当然RAC的升级是会有所不同.但是他们每个版本之间升级步骤都是差不多的,先升级Database Software,再升级Oracle Instance. Oracle 11.2.0.4的Patchset No:19852360下载需要有Oracle Support才可以.  Patchset包含有7个

[ 测试思维 ] 探索式软件测试

非常不错的关于探索式软件测试的学习资料 1.探索式测试简析 作者:微软 史亮 http://pan.baidu.com/s/1c2D4tAo 2.探索式测试白皮书 作者:淘宝 季哥 http://pan.baidu.com/s/1qYFNG3y

探索 ConcurrentHashMap 高并发性的实现机制

简介 ConcurrentHashMap 是 util.concurrent 包的重要成员.本文将结合 Java 内存模型,分析 JDK 源代码,探索 ConcurrentHashMap 高并发的具体实现机制. 由于 ConcurrentHashMap 的源代码实现依赖于 Java 内存模型,所以阅读本文需要读者了解 Java 内存模型.同时,ConcurrentHashMap 的源代码会涉及到散列算法和链表数据结构,所以,读者需要对散列算法和基于链表的数据结构有所了解. Java 内存模型 由

JVM中class文件探索与解析(一)

一直想成为一名优秀的架构师的我,转眼已经工作快两年了,对于java内核了解甚少,闲来时间,看看JVM,吧自己的一些研究写下来供大家参考,有不对的地方请指正. 废话不多说,一起来看看JVM中类文件是如何加载和运行的. (1)首先,编写简单代码,对其编译生成的class文件进行研究,其java代码如下: 1 public class test { 2 private static int count = 0; 3 public static void recursion(){ 4 count++;