深深通晓iOS开发中的BitCode作用,关于苹果Xcode编译器与Bitcode

前言

做iOS开发的爱侣们都知晓,近年来新型的Xcode7,新建项目默许就开辟了bitcode设置.而且一大半开发者都被这么些出人意料的bitcode成效给坑过造成项目编译战败,而那么些因为bitcode而编译失利的的连串都有一个共同点,就是链接了第三方二进制的库或者框架,而这几个框架或者库恰好没有包括bitcode的事物(暂且称为东西),从而致使品种编译不成功.所以每当遇上这些场所时候大部分人都是直接设置Xcode关闭bitcode作用,全体不生成bitcode.也不去商讨这一开关背后暗藏的原理.中枪的请点个赞.

LLVM是当下苹果选拔的编译器工具链,Bitcode是LLVM编译器的中间代码的一种编码,LLVM的前端可以知晓为C/C++/OC/斯维夫特等编程语言,LLVM的后端可以驾驭为顺序芯片平台上的汇编指令或者可实施机器指令数据,那么,BitCode就是位于那二者直接的中间码.
LLVM的编译工作原理是前者负责把品种程序源代码翻译成Bitcode中间码,然后再依照分裂对象机器芯片平台转换为对应的汇编指令以及翻译为机械码.那样设计就可以让LLVM成为了一个编译器架构,可以不难的在LLVM架构之上发明新的语言(前端),以及在LLVM架构上面支持新的CPU(后端)指令输出,即便Bitcode仅仅只是一个中间码不可能在别的平台上运行,不过它能够转账为任何被匡助的CPU架构,包涵现在还没被发明的CPU架构,也就是说现在打开Bitcode功用交由一个App到应用商店,未来只要苹果新出了一款手机并CPU也是崭新设计的,在苹果后台服务器一样可以从那一个App的Bitcode早先编译转化为新CPU上的可执行程序,可供新手机用户下载运行那么些App.

前言

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

正史回想

在One plus出来以前,苹果主要的编译器技术是用经过多少创新的GCC工具链来把Objective-C语言编写的代码编译出所指定的机械处理器上原生的可实施程序.编译器暴发的可执行程序叫做”Fat
Binaries”–类似于Windows下PE格式的exe和Linux下的ELF格式的二进制,不相同的是,一个”Fat
Binary”可以涵盖同一个顺序的许多本子,所以同一个可执行文件可以在分歧的电脑上运行.紧要就是其一技能让苹果的硬件很简单的从PowerPC迁移到PowerPC64的微处理器,以及新兴再迁移到英特尔和英特尔64处理器.这一个方案带来的负面影响就是同一个文本中存了多份可进行代码,除了当前机械可实施的那一份之外其余都是无用的,白占空间.
那一个在商海上被称呼”Universal
Binary”,在苹果从PowerPC迁移到速龙处理器的作业起先存在的(一个二进制文件既涵盖一份PowerPC版本和一份英特尔版本).渐渐的新生又协理同时含有英特尔32bit和英特尔 64bit. 在一个Fat
binary中,又操作系统运行时按照处理器类型动态选用正确的二进制版本来运行,可是应用程序要帮助不相同平台的电脑的话,应用程序本身要多占用部分空间.当然也有一部分瘦身的工具,比如lipo,可以用来移除fat
binary中这么些当前机械中不被支持的依旧多余的可进行代码达到瘦身目标,lipo不会改变程序执行逻辑,仅仅只是文件的大小瘦身.

野史回看

在One plus出来往日,苹果主要的编译器技术是用经过多少革新的GCC工具链来把Objective-C语言编写的代码编译出所指定的机械处理器上原生的可举行程序.编译器暴发的可执行程序叫做”Fat
Binaries”–类似于Windows下PE格式的exe和Linux下的ELF格式的二进制,不相同的是,一个”Fat
Binary”可以分包同一个主次的重重本子,所以同一个可执行文件可以在不相同的微机上运行.紧要就是那个技能让苹果的硬件很简单的从PowerPC迁移到PowerPC64的处理器,以及后来再迁移到AMD和AMD64处理器.那些方案带来的负面影响就是同一个文件中存了多份可实施代码,除了当前机械可实施的那一份之外其他都是行不通的,白占空间.
这几个在市面上被称之为”Universal
Binary”,在苹果从PowerPC迁移到AMD处理器的事体初始存在的(一个二进制文件既涵盖一份PowerPC版本和一份速龙版本).逐渐的新生又协理同时富含英特尔32bit和英特尔 64bit. 在一个Fat
binary中,又操作系统运行时按照处理器类型动态接纳正确的二进制版本来运行,但是应用程序要襄助不同平台的电脑的话,应用程序本身要多占用部分空间.当然也有一对瘦身的工具,比如lipo,可以用来移除fat
binary中那个当前机械中不被扶助的要么多余的可举行代码达到瘦身目标,lipo不会改变程序执行逻辑,仅仅只是文件的大小瘦身.

编译器现状

趁着活动装备移动网络的时刻思念发展,现在移动装备中的程序大小变得愈加主要了,首要是因为移动设备中不会有总结机上那么大的一个硬盘驱动器.还有就是苹果已经从原有的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代码.

编译器现状

随着移动装备移动互连网的中肯发展,现在移动设备中的程序大小变得进一步首要了,重如若因为运动装备中不会有处理器上那么大的一个硬盘驱动器.还有就是苹果已经从原始的ARM处理器迁移到本人设计的A4,A5,A5X,A6,A7,A8,A8X,A9,A9X以及一而再的A10统计机,他们的指令集已经爆发了变更和原始ARM设计的有所不同,所有的这几个生塞尔维亚Bell格莱德被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.

苹果的渴求

到此,让大家想想一下,为何苹果默许需求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应用开发中,一般不会须求用到汇编层面去优化的代码.所以大家任重(英文名:rèn zhòng)而道远关怀第三方(开源)C代码,越发是音视频编码解码这么些计算密集型项目代码,关键计算的代码针对一定平台都有对应平台的汇编版本完毕,当然也有C的兑现,但是默许编译一般都是用的汇编版本,那样就会促成大家在编译这些开源代码的时候就是你带了-fembed-bitcode参数也仅仅只是让项目中的部分C代码的目的文件带了bitcode段,而那小数的汇编代码的靶子文件一律不带bitcode段,那样编译出这么些库交给上层开发者使用的时候,就会现出在卷入上传或者真机调试的时候因为Xcode默认开了bitcode功效而链接失败,导致不可以真机调试或者无法上传应用到AppStore.

实践出真知

俺们依然应该实际弄八个测试代码举办实践和考查一下相比较好.做一遍测试,首回准备三个C语言源代码继续测试;第二次把里面一个转移为汇编语言源代码后再一个C代码和一个汇编代码一起重复以前的测试步骤进行相比较校验差距.

此文之初衷

近些年在指引自己戴维营战友们做手机音视频直播的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

由于时间和字数原因,关于任何愈来愈多详细的讯息就不苗条道来了.

ca88官方会员登录,大卫营教育Slogan: Dive in education!

越来越多iOS开发精品小说:大卫营技术博客

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:

$ xcrun -sdk iphoneos clang -arch arm64 -fembed-bitcode -c test.m demo.m

然后把五个对象文件打包为一个静态库文件:

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

用Shell命令otool查看目的文件中是或不是包蕴bitcode段:

$ otool -l test.o |grep bitcode
# Prints:
#   sectname __bitcode
#   sectname __bitcode

如果看到输出了2行sectname
__bitcode,就是认证那静态库中的三个对象文件包罗了bitcode.

2.下边把其中一个demo.m换成汇编语言再加入编译:

用上面的命令把demo.m的C代码转换为ARM64汇编语言格式demo.s:

$ xcrun -sdk iphoneos clang -arch arm64 -S demo.m
$ cat demo.s
# Prints:
    .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.m和demo.s:

$ rm demo.m

现行,我们来把test.m那几个C源代码和dmeo.s那些汇编源代码来一起带着-fembed-bitcode参数来生成靶子代码并封装为一个静态库:

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

下一场大家再运行otool工具来检查那么些新的静态库中包涵的2个目的文件是还是不是都带有bitcode段:

$ ar -t libTest.a
# Prints:
# __.SYMDEF SORTED
# test.o
# demo.o
$ otool -l libTest.a | grep bitcode
# Prints:
#  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商事往斗鱼直播频道揭橥媒体流,项目需要用FFMPEG和libx264三个开源项目,在编译为iOS框架库提需要学员用的时候,他们遭遇了bitcode的标题,即便可以应用间接关闭bitcode来幸免不当,可是战友的求知欲必须满意,格物致知,必须让其知其究竟.

libx264是VideoLan基金会管理的一个视频编解码的开源项目,其大气行使了种种平台的多媒体汇编指令展开了优化,在编译为不带bitcode的库的时候,完全按官方autotools编译方法是没有任何难题的;编译全带bitcode的库的时候我们只可以关闭汇编优化,在执行./configure阶段可以添加–disable-asm参数来禁用汇编.不过,那个选项在configure脚本中的已毕机制有题目.导致其依旧调用了汇编的函数,但是汇编的代码却从不编译进去,从而会促成项目为真机营造和打包的链接阶段会揭示找不到符号的错误,那样就无法不辱义务一语双关.出于轻微程度的网瘾影响,故把往日的FFMPEG和libx264品类的编译脚本举行了鼎新和打补丁.方今一度得以做到一键编译出带全体bitcode的FFMPEG和libx264的框架了.

FFmpeg须求重视libx264.

电动编译脚本项目地方放在github:
https://github.com/Diveinedu-CN/FFmpeg-iOS-build-script.git

鉴于岁月和字数原因,关于其他更多详细的音信就不苗条道来了.

相关文章

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图