关于Bitcode的探索
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Bitcode的探索相关的知识,希望对你有一定的参考价值。
上述引自Apple的文档 App Thinning (iOS, tvOS, watchOS)。
其大概意思是Bitcode类似于一个中间码,被上传到applestore之后,苹果会根据下载应用的用户的手机指令集类型生成只有该指令集的二进制,进行下发。从而达到精简安装包体积的目的。
一点编译原理
为了更好的理解什么是bitcode,我们简短的看一下编译器编译的过程:
- Lexer :读入源文件,并将其转化成字符流
- Parser :将字符流转换成AST(抽象语法树
- Semantic Analysis: 对输入的AST进行语法检查。
- Code Generation: 代码生成,将AST转换成低层次的IR指令
- Optimization: 分析IR指令,将其中潜在会拖慢运行速度的指令干掉。
- AsmPrinter: 通过IR(中间码)生成特定CPU架构的汇编代码
- Assemble: 将汇编代码转化成二进制
- Linker: 通常程序会引用其他的二进制文件(.a或者framework),但是这些链接在程序中没有正确的地址,只是个占位符。Linker的工作就是给这些占位符正确的地址。
打开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的探索的主要内容,如果未能解决你的问题,请参考以下文章