深刻了解iOS开发中之BitCode功能

发布时间:2018-09-01  栏目:教育  评论:0 Comments

又平等次于执拗地当拘留了原作之后,不再去看它的录像版本。没什么原因,我确信有些东西,以电视剧的制造的精巧程度是心有余而力不足见的。如果有人执意要告知自己,原作与电视剧各有每的优势,那我会请他免开尊口,因为只有就自娱自乐评论我来说,我,还非需谁来点。

前言

举行iOS开发之爱侣等都了解,目前新型的Xcode7,新建项目默认就开辟了bitcode设置.而且大部分开发者都为这个突如其来的bitcode功能为坑了造成品种编译失败,而这些因为bitcode而编译失败的之型还发一个共同点,就是链接了第三着次进制的仓库或者框架,而这些框架或仓库正没有包含bitcode的物(暂且称为东西),从而造成品种编译不化功.所以每当遇到这情上大部分总人口且是直接设置Xcode关闭bitcode功能,全部休生成bitcode.也非去追究就同一开关背后藏的原理.中枪的请求点单赞.

LLVM是眼下苹果应用的编译器工具链,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.

竹内多鹤身上流的凡日本总人口之血,这是无法改变的真相。确切说,是代浪村日本人的血。从后呢不克可怜好地融入时下日本社会来拘禁,日本遗孤确实是同一丛“尴尬的有”,我同情也无可奈何。生活习惯的差别,大而化之,也是简单个民族文化和习惯的出入,仅此而已。既无必要从多鹤的“讲卫生”上观望国人的脏,也非用无聊到以多鹤说了“中国人口且是瞎说精”而背生凉气耿耿于怀。美丽之孙俪很可能演不下那种骨子里之事物——坚强、倔强、执着、勤劳,当然还有我看不惯的略微民族之窄小的志向(无关于道德,如多鹤对在的亮和实施)。

史回顾

每当iPhone出来之前,苹果要的编译器技术是用经过多少改进之GCC工具链来把Objective-C语言编写的代码编译出所指定的机处理器上原生的可执行程序.编译器产生的可执行程序叫做”Fat
Binaries”–类似于Windows下PE格式的exe和Linux下之ELF格式的二进制,不同的凡,一个”Fat
Binary”可以分包同一个次的好多本子,所以和一个可执行文件可以当不同之处理器上运行.主要就是是这个技术让苹果之硬件大爱的由PowerPC迁移至PowerPC64的微处理器,以及新兴还徙到Intel和Intel64处理器.这个方案带来的负面影响就是跟一个文书中满怀了大多卖而实行代码,除了当前机械而实施的那么无异卖之外任何还是无用的,白占空间.
这个于商海及给称呼”Universal
Binary”,在苹果于PowerPC迁移到Intel处理器的事务开始在的(一个二进制文件既涵盖一份PowerPC版本及均等卖Intel版本).慢慢的新兴而支持而富含Intel
32bit和Intel 64bit. 以一个Fat
binary中,又操作系统运行时根据处理器类型动态选择对的亚前行制版本来运行,但是应用程序要支持不同平台的处理器吧,应用程序本身若多占部分空间.当然也发出有瘦身的工具,比如lipo,可以据此来更换除fat
binary中那些当前机械中莫为支持之或者多余的可实施代码达到瘦身目的,lipo不见面改变程序执行逻辑,仅仅只是文件之大小瘦身.

太欢喜的人物是朱小环。我平坚信闫学晶只能演七私分来。因为它的东北生活,“东北老娘们儿”对其吧,绝不是个大概的存在集体。非得用一句话概括来说,那自己做不交。无法想像,没有小环的是“家”会是何许。在特别时期,没必要和我操人格。保持人的口,都颇了。所以,怎么被大家还活下来,既是异常题材,也浮现特别本事。“凑合”不是人均收入4万美元的国度之人会面考虑的从业。禽兽的日本总人口(并无迁怒于多鹤)意外流产导致力不从心生育,不得不忍受丈夫与另外一个内生育,善良而宽容地让另外一个妻一点点底进好的家庭,生生一个个儿女,一点点享了原本只是属自己之先生。她貌似强悍的撒泼耍横为亲人挡住一次次危机。因为其好其底丈夫,那个第一目看见就觉得会暨它高大偕老的先生,爱其名下持有的男女,甚至为容易在多鹤。他们内部无谁出事她还见面极其这为不过得力的吧之出头。而事实上,她就是者家的阿妈、姐、祖母、外祖母。但并未人惋惜地啊她去挡。她享有的交付到终极只是有的夺,失去自己之儿女,失去丈夫,失去养育长大的男女,孤独地及老狗为陪。

编译器现状

乘活动设备移动互联网的尖锐发展,现在动设备遭遇的主次大小变换得越来越重要了,主要是以运动装备遭遇莫见面发生处理器上那坏之一个硬盘驱动器.还有即使是苹果就起原的ARM处理器迁移至自己设计的A4,A5,A5X,A6,A7,A8,A8X,A9,A9X以及持续之A10电脑,他们的指令集已经产生了变动跟原始ARM设计的有所区别,所有的这些变化还给iOS操作系统底层暨Xcode/LLVM编译工具往上层程序员一定程度的透明了,编译出来的次第会含有多尽代码版本.当面对此题材后,苹果投入大量资产迁移至LLVM编译器架构并利用bitcode的必要性进一步大.从极度开头的管OPENGL编译为一定的GPU指令到把Clang编译器(LLCM的C/OC编译前端)支持Objective-C的改良并视作Xcode的默认编译器.

LLVM提供了一个虚拟指令集机制,它可翻出指定的所支撑之电脑架构的实践代码(机器码).这个就让为iOS应用程序的编译开发一个一心基于LLVM架构的工具链成为可能.而LLVM的此虚拟的通用的指令集可以用生多种代表格式:

  • 名为IR的公文表示的汇编格式(像汇编语言);
  • 换为二进制数据表示的格式(像目标代码),这个次前行制格式就是咱所说的bitcode.

Bitcode和风土人情的可是实行令集不同,他维护的凡函数功能的花色和签约,比如,传统而实施令集中,一雨后春笋(<=8)的布尔值可以抽存储到单个字节中,但是当bitcode中他们是独家独立表示的.此外,逻辑运算操作(比如寄存器清零操作)也出于他们相应的逻辑表示法($R=0);当这些BitCode要换为特定机器平台的通令集时,他可用经过对一定机器平台优化了的汇编指令来顶替:xor eax, eax.(这个汇编指令同样是寄存器<eax>清零操作).

然而bitcode他也未是完全独立为计算机平台跟调用约定的.寄存器的深浅在指令集中是一个一定重大的特色,众所周知,64bit寄存器可以比较32bit寄存器存储更多的多寡,生成64bit平台的bitcode和32bit平台的bitcode是显眼不同之,还有,调用约定好依据函数定义或者函数调用来定义,这些可以规定函数的参数传递是传寄存器值为还是制止栈.
一些编程语言还有一部分诸如sizeof(long)这样的预处理指令,这些将于bitcode生成之前前让翻译.一般情形下,对于支撑fastcc(fast
calling convention)调用的64bit平台会转移和那同一的bitcode代码.

多鹤的片单子女,张铁、张钢,是日本全民族之严谨两当。(据说电视剧被管开中的少弟兄进行了交替,这里不多说。)张铁循规蹈矩、服从教育、参加革命、左进激情、从恶生母到死命追随并坐的也荣誉;张钢执拗、坚强、沉默、叛逆、崇尚暴力、为上目的不择手段,但为是小外毕竟比非常双胞胎哥哥强了不知多少。作为多鹤的儿女,他们带有离奇的承受另一半祖先的特质。

苹果的求

至这,让咱们考虑一下,为什么苹果默认要求watchOS和tvOS的App要达标传bitcode?
因为将bitcode上传到他协调的基本服务器后,他可为对象安装App的设备开展优化二进制,减多少安装包的下载大小,当然iOS开发者也可以上传多独版本要不是包裹到么包里,但是如此会占据更多之积存空间.
最关键的是许苹果可在后台服务器对应用程序进行签约,而非用导出任何密钥到极限开发者那.

上传到服务器的bitcode给苹果带更便宜是:
以后初设计了新指令集的初CPU,可以持续由即份bitcode开始编译出新CPU上实施的可执行文件,以供应用户下载安装.
不过bitcode给开发者带来的困顿之处在便是:
没用bitcode之前,当应用程序奔溃后,开发者可以依据取得的之奔溃日志再下放上上传到苹果服务器的二进制文件之调节符号表信息方可过来程序运行过程到奔溃时后调整用栈信息,对题目进行固定排查.但是之所以了bitcode之后,用户安装的二进制不是开发者这边转移的,而是苹果服务器经过优化后变化的,其相应之调节符号信息丢失了,也尽管无法展开前说之复奔溃现场寻找原因了.

时,watchOS和tvOS应用发布得达传带bitcode版本的包.iOS应用发布针对bitcode的求是可选的,用户可以在Xcode的型设置中关闭.
相当给以编译的时候加一个标记:embed-bitcode-marker(调试构建)
embed-bitcode(打包/真机构建).这个于clang编译器的参数是-fembed-bitcode,swift编译器的参数是-embed-bitcode.

匪亮堂自己这样分析,严歌苓会不见面嗤之以鼻子,读到的人头见面无会见大加挞伐,愿意交流的,欢迎指点。

执行产生真正懂

咱们还是该实际搞两单测试代码进行实践与检察一下较好.做片不行测试,第一不善准备一定量单C语言源代码继续测试;第二蹩脚将里面一个变型也汇编语言源代码后还一个C代码和一个汇编代码一起还之前的测试步骤进行比校验差异.

  • 1 . 如下两单遍是Objective-C代码:

test.m :

#import <Foundation/Foundation.h>
void greeting(void)
{
    NSLog(@"hello world!");
}

demo.m :

#import <Foundation/Foundation.h>
void demo(void)
{
    NSLog(@"demo func");
}

就此Clang编译成 ARM64 格式且带bitcode的靶子文件test.o demo.o:

wuqiong:~ apple$ xcrun -sdk iphoneos clang -arch arm64 -fembed-bitcode -c test.m demo.m

下一场把少单目标文件包为一个静态库文件:

wuqiong:~ apple$ xcrun -sdk iphoneos ar  -r libTest.a test.o demo.o
ar: creating archive libTest.a

从而Shell命令otool查看目标文件被是不是包含bitcode段:

wuqiong:~ apple$ otool -l test.o |grep bitcode
  sectname __bitcode
  sectname __bitcode

假定看到输出了2行sectname __bitcode,就是认证这静态库中之简单单对象文件包含了bitcode.

  • 2.脚将内部一个demo.m换成汇编语言再参与编译:

因此脚的吩咐将demo.m的C代码转换为ARM64集结编语言格式demo.s:

wuqiong:~ apple$ xcrun -sdk iphoneos clang -arch arm64 -S demo.m
wuqiong:~ apple$ cat demo.s
    .section    __TEXT,__text,regular,pure_instructions
    .ios_version_min 9, 2
    .globl  _demo
    .align  2
_demo:                                  ; @demo
    .cfi_startproc
; BB#0:
    stp x29, x30, [sp, #-16]!
    mov  x29, sp
Ltmp0:
    .cfi_def_cfa w29, 16
Ltmp1:
    .cfi_offset w30, -8
Ltmp2:
    .cfi_offset w29, -16
    adrp    x0, L__unnamed_cfstring_@PAGE
    add x0, x0, L__unnamed_cfstring_@PAGEOFF
    bl  _NSLog
    ldp x29, x30, [sp], #16
    ret
    .cfi_endproc

    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ; @.str
    .asciz  "demo func"

    .section    __DATA,__cfstring
    .align  4                       ; @_unnamed_cfstring_
L__unnamed_cfstring_:
    .quad   ___CFConstantStringClassReference
    .long   1992                    ; 0x7c8
    .space  4
    .quad   L_.str
    .quad   9                       ; 0x9

    .section    __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
    .long   0
    .long   0


.subsections_via_symbol

接下来去demo.m这个C源代码,仅留下test.mdemo.s:

wuqiong:~ apple$ rm demo.m

兹,我们来管test.m斯C源代码和dmeo.s是集编源代码来并带在-fembed-bitcode参数来深成靶子代码并打包为一个静态库:

wuqiong:~ apple$ xcrun -sdk iphoneos clang -arch arm64 -fembed-bitcode -c test.m demo.s
wuqiong:~ apple$ xcrun -sdk iphoneos ar -r libTest.a test.o demo.o

接下来我们重运行otool工具来检查是新的静态库中带有的2单目标文件是否都带有bitcode段:

wuqiong:~ apple$ ar -t libTest.a
__.SYMDEF SORTED
test.o
demo.o
wuqiong:~ apple$ otool -l libTest.a | grep bitcode
  sectname __bitcode

雅奇怪,这同样次于,只生一行sectname __bitcode出口,这便说明及时点儿个目标文件,有一个勿带有bitcode段,哪怕我们于编译的时刻指定了参数-fembed-bitcode也无用.至于具体是啦一个无带bitcode段,我们必然懂得就是大起ARM64聚编语言编译过来的对象文件不带.

这就是说就是得出一个结论,bitcode的浮动,是由于汇编语言以上之上层语言编译而来,和极前面所说之那样,他是上层语言及汇编语言(机器语言)之间的一个中码.

脚下咱们一般的iOS应用开发被,一般不会见要为此到汇编层面去优化的代码.所以我们第一关心第三着(开源)C代码,尤其是音视频编码解码这些计算密集型项目代码,关键计算的代码针对特定平台还来指向许平台的汇编版本实现,当然也生C的兑现,但是默认编译一般还是为此之汇编版本,这样即使会导致我们于编译这个开源代码的时便你带来了-fembed-bitcode参数为仅仅只是让色面临的有C代码的靶子文件带了bitcode段,而那小数的汇编代码的目标文件一律不带bitcode段,这样编译出此库房交给上层开发者使用的时段,就会油然而生在包上传或者真机调试之时节以Xcode默认开了bitcode功能一旦链接失败,导致未克真机调试要无克上传应用及AppStore.

此文之初衷

近年来于辅导自己戴维营战友等开手机音视频直播的App,调试之时节手机采集音视频,视频用h264编码,音频采用aac编码,通过RTMP协议于斗鱼直播频道发布媒体流,项目用为此FFMPEGlibx264少单开源项目,在编译为iOS框架库提供于学生因此之早晚,他们遇到了bitcode的题材,虽然好应用直接关闭bitcode来避免不当,但是战友的求知欲要满足,格物致知,必须吃那知其究竟.

libx264是VideoLan基金会保管的一个视频编解码的开源项目,其大气施用了逐条平台的多媒体汇编指令进行了优化,在编译为无带bitcode的库房的下,完全按官方autotools编译方法是没外问题之;编译全带bitcode的库房的时刻我们只能关门汇编优化,在实施./configure级可以长--disable-asm参数来受用汇编.但是,这个选项在configure剧本中之落实机制发生题目.导致其还调用了汇编的函数,但是汇编的代码却尚未编译进去,从而会招致品种也确实机构建及打包的链接阶段会暴露找不至号的错,这样便无可知成就少全都其美.出于轻微程度的强迫症影响,故将前面的FFMPEGlibx264种之编译脚本进行了改良和打补丁.时一度得以好一键编译出带全部bitcode的FFMPEG和libx264底框架了.

FFmpeg内需负libx264.

自动编译脚本项目位置在github:
https://github.com/Diveinedu-CN/FFmpeg-iOS-build-script.git

由于时间和字数由,关于其他还多详细的音就是无细道来了.

戴维营教育Slogan: Dive in education!

重新多iOS开发精品文章:戴维营技术博客

留下评论