Bitcode是什么,vscode如何配置置

posts - 89,&
comments - 2,&
trackbacks - 0
深究Xcode的bitcode设置
转发至:/p/f42a33f5eb61
做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不会改变程序执行逻辑,仅仅只是文件的大小瘦身.
编译器现状
随着移动设备移动互联网的深入发展,现在移动设备中的程序大小变得越来越重要了,主要是因为移动设备中不会有电脑上那么大的一个硬盘驱动器.还有就是苹果早就从原始的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代码:
#import &Foundation/Foundation.h&
void greeting(void)
NSLog(@"hello world!");
#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
__TEXT,__text,regular,pure_instructions
.ios_version_min 9, 2
.cfi_startproc
然后删除demo.m这个C源代码,仅留下test.m和demo.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
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协议往斗鱼直播频道发布媒体流,项目需要用FFMPEG和libx264两个开源项目,在编译为iOS框架库提供给学生用的时候,他们遇到了bitcode的问题,虽然可以采取直接关闭bitcode来避免错误,但是战友的求知欲必须满足,格物致知,必须让其知其究竟.
libx264是VideoLan基金会管理的一个视频编解码的开源项目,其大量使用了各个平台的多媒体汇编指令进行了优化,在编译为不带bitcode的库的时候,完全按官方autotools编译方法是没有任何问题的;编译全带bitcode的库的时候我们不得不关闭汇编优化,在执行./configure阶段可以加上--disable-asm参数来禁用汇编.但是,这个选项在configure脚本中的实现机制有问题.导致其仍然调用了汇编的函数,但是汇编的代码却没有编译进去,从而会导致项目为真机构建和打包的链接阶段会爆出找不到符号的错误,这样就不能做到两全其美.出于轻微程度的强迫症影响,故把之前的FFMPEG和libx264项目的编译脚本进行了改进和打补丁.目前已经可以做到一键编译出带全部bitcode的FFMPEG和libx264的框架了.
FFmpeg需要依赖libx264.
自动编译脚本项目位置放在github:
阅读(...) 评论()理解Bitcode:一种中间代码
招聘信息:
今天试着用Xcode 7 beta 3在真机(iOS 8.3)上运行一下我们的工程,结果发现工程编译不过。看了下问题,报的是以下错误:ld:&‘/Users/**/Framework/SDKs/PolymerPay/Library/mobStat/lib**SDK.a(**ForSDK.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&arm64得到的信息是我们引入的一个第三方库不包含bitcode。嗯,不知道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 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上。嗯,看着挺高级的啊。继续看,在中,还有一段如下的描述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会再将这个botcode编译为可执行的64位或32位程序。再看看这两段描述都是放在App Thinning(App瘦身)一节中,可以看出其与包的优化有关了。喵大(@onevcat)在其博客中也描述了iOS 9中苹果在App瘦身中所做的一些改进,大家可以转场到那去研读一下。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 arm64要么让第三方库支持,要么关闭target的bitcode选项。实际上在Xcode 7中,我们新建一个iOS程序时,bitcode选项默认是设置为YES的。我们可以在”Build Settings”->”Enable Bitcode”选项中看到这个设置。不过,我们现在需要考虑的是三个平台:iOS,Mac OS,watchOS。对应iOS,bitcode是可选的。对于watchOS,bitcode是必须的。Mac OS不支持bitcode。如果我们开启了bitcode,在提交包时,下面这个界面也会有个bitcode选项:盗图,我的应用没办法在这个界面显示bitcode,因为依赖于第三方的库,而这个库不支持bitcode,暂时只能设置ENABLE_BITCODE为NO。所以,如果我们的工程需要支持bitcode,则必要要求所有的引入的第三方库都支持bitcode。我就只能等着公司那些大哥大姐们啥时候提供一个新包给我们了。题外话如上面所说,bitcode是一种中间代码。LLVM官方文档有介绍这种文件的格式,有兴趣的可以移步。参考
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
点击量10887点击量9070点击量6832点击量6807点击量6167点击量6133点击量5809点击量5585点击量5315
&2015 Chukong Technologies,Inc.
京公网安备89必读!结合实际问题的 Bitcode 适配指南
招聘信息:
随着XCode7的发布,Apple提供了一项新的技术来支持App瘦身功能,那就是Bitcode。本文章将会结合自己在支持bitcode过程中遇到的问题,来阐述支持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的文档 。其大概意思是Bitcode类似于一个中间码,被上传到applestore之后,苹果会根据下载应用的用户的手机指令集类型生成只有该指令集的二进制,进行下发。从而达到精简安装包体积的目的。一点编译原理为了更好的理解什么是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-makerYou 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 -lBUT, 上述检查过了之后,也不一定是真的支持bitcode,在实际的测试中,发现上述检测命令通过之后,某个使用的第三方库,依然报错不支持bitcode。因而最终结果,还是需要以是否能够连接成功为准。重要事情说三遍,上述网上流传的检测方法只做参考,最终还是要以实际效果为准。最终结果检查如果您是一个APP,可以直接进行Archive打包,如果是一个库,则建议建一个Demo工程进行打包,记得要打开bitcode设置。CheckPoint1 连接是否报错如果有任何一个库没有打开bitcode链接,将会出现类似下方的错误。只要链接过了,那么恭喜了,基本上是OK了。&CheckPoint2 检查最终效果使用开发模式导出ipa选择出包的方式这里建议使用第二种,生成针对具体机型的包出现了,Compiling Bitcode,这个过程!!!!!最终结果在最后输出的文件中,你能够看到一个App Thinning的结果,里面有针对各个机型的ipa包。在App Thinning Size Report中能够明显看到,由于使用了bitcode等技术之后,所带来的收益:App Thinning Size Report for All Variants of BlackVariant: Black-iPad (4th generation)-etc.ipaSupported devices: iPad (3rd generation) and iPad (4th generation)App + On Demand Resources size: 368 KB compressed, 737 KB uncompressedApp size: 368 KB compressed, 737 KB uncompressedOn Demand Resources size: Zero KB compressed, Zero KB uncompressed....欢迎关注iOS开发公共账号iOS_Tips:扫描下方二维码关注
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量8744点击量7635点击量7426点击量7331点击量6810点击量6312点击量6125点击量5756点击量5670
关注微信 每日推荐
扫一扫 浏览移动版
&2015 Chukong Technologies,Inc.
京公网安备89理解什么是Bitcode - 简书
理解什么是Bitcode
用Xcode 7 beta 3在真机(iOS 8.3)上运行一下工程,结果发现工程编译不过。看了下问题,报的是以下错误:ld: ‘/Users/**/Framework/SDKs/PolymerPay/Library/mobStat/lib**SDK.a(**ForSDK.o)’does not contain bitcode. You must rebuild it with bitcode enabled (Xcodesetting ENABLE_BITCODE), obtain an updated library from the vendor, or disablebitcode for this target. for architecture arm64得到的信息是引入的一个第三方库不包含bitcode。Bitcode是个什么鬼?查阅了一下官方文档,在AppDistribution Guide–App Thinning (iOS, watchOS)一节中,找到了下面这样一个定义:Bitcode is an intermediate representationof a compiled program. Apps you upload to iTunes Connect that contain bitcodewill be compiled and linked on the App Store. Including bitcode will allowApple to re-optimize your app binary in the future without the need to submit anew 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 tothe 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 bitexecutables as necessary.当提交程序到App store上时,Xcode会将程序编译为一个中间表现形式(bitcode)。然后App store会再将这个bitcode编译为可执行的64位或32位程序。再看看这两段描述,都是放在App Thinning(App瘦身)一节中,可以看出其与包的优化有关了。Bitcode配置在上面的错误提示中,提到了如何处理我们遇到的问题:You must rebuild it with bitcode enabled(Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, ordisable bitcode for this target. for architecture arm64要么让第三方库支持,要么关闭target的bitcode选项。实际上,在Xcode 7中,我们新建一个iOS程序时,bitcode选项默认是设置为YES的。我们可以在”Build Settings”-&”Enable Bitcode”选项中看到这个设置。不过,我们现在需要考虑的是三个平台:iOS,Mac OS,watchOS。对于iOS,bitcode是可选的;对于watchOS,bitcode是必须的;而Mac OS是不支持bitcode。如果我们开启了bitcode,在提交包时,下面这个界面也会有个bitcode选项:
所以,如果我们的工程需要支持bitcode,则必要要求所有引入的第三方库都支持bitcode。

我要回帖

更多关于 vscode c 配置 的文章

 

随机推荐