Xcode 14 Beta release notes已过时,这一切都要归功于一年一度的WWDC。
唉,Bitcode现在已经过时了,如果你试图启用它,你会收到一条警告消息。
我想知道,为什么会发生这种情况?使用Bitcode有什么缺点吗?对苹果来说,维护它是不是有点痛苦?现在每个iPhone型号的编译将如何运作?
Xcode 14 Beta release notes已过时,这一切都要归功于一年一度的WWDC。
唉,Bitcode现在已经过时了,如果你试图启用它,你会收到一条警告消息。
我想知道,为什么会发生这种情况?使用Bitcode有什么缺点吗?对苹果来说,维护它是不是有点痛苦?现在每个iPhone型号的编译将如何运作?
4条答案
按热度按时间mf98qq941#
Bitccode实际上只是LLVM中间语言。当您使用LLVM工具链编译源代码时,源代码会被翻译成一种名为Bitcode的中间语言。然后,此Bitcode会被分析、优化,最后翻译成所需目标CPU的CPU指令。
这样做的好处是,所有基于LLVM的前端(如clang)只需要将源代码转换为位代码,从那里开始,它的工作方式与源语言相同,因为LLVM工具链不关心位代码是从C、C++、Obj-C、Rust、Swift还是任何其他源语言生成的;一旦有了Bitcode,其余的工作流程总是相同的。
Bitcode的一个好处是,您可以在以后为另一个CPU生成指令,而不必重新编译原始源代码。例如,我可以将C代码编译为Bitcode,并让LLVM最终为x86 CPU生成一个运行二进制代码。但是,如果我保存了Bitcode,我可以在以后告诉LLVM也从该Bitcode为ARM CPU创建一个运行二进制代码。而不需要编译任何东西,也不需要访问原始的C代码。而且生成的ARM代码将和我从一开始就编译到ARM一样好。
如果没有Bitcode,我将不得不将x86代码转换为ARM代码,这样的转换会产生更差的代码,因为代码的原始意图通常会在CPU代码的最后编译步骤中丢失,这还涉及对其他CPU没有意义的CPU特定优化,而Bitcode很好地保留了原始意图,只执行所有CPU都将受益的优化。
拥有所有应用程序的位码,苹果就可以针对特定CPU重新编译位码,要么让应用程序兼容不同类型的CPU或完全不同的架构,要么只是为了更好地优化更新的编译器版本。例如,如果苹果明天推出一款使用RISC-V而不是ARM CPU的iPhone,所有带有Bitcode的应用程序都可以重新编译为RISC-V,并在本地支持新的CPU架构,尽管应用程序的作者甚至从未听说过RISC-V。
我想这就是为什么苹果希望所有的应用程序都采用Bitcode格式的原因。但这种方法一开始就有问题。一个问题是Bitcode不是一种固定的格式,LLVM会在每个版本中更新它,但它们并不保证完全的向后兼容性。位码从来都不是永久存储或存档的稳定表示。另一个问题是你不能使用汇编代码,因为没有为汇编代码发出Bitcode。你也不能使用没有Bitcode的预建的第三方库。
最后但同样重要的是:AFAIK苹果迄今为止从未使用过Bitcode的任何优势。尽管过去要求所有应用都包含Bitcode,但应用也必须包含所有支持的CPU的预构建胖二进制代码,苹果总是只发布预构建代码。例如,对于iPhone,你曾经有一个32位ARMv7和64位ARM 64版本,以及Bitcode,在应用精简期间,苹果将删除32位或64位版本,以及位码,然后运送剩下的东西。好吧,但他们也可以这样做,如果没有位码在那里。位码是不需要精简架构的胖二进制!
为了适应不同的架构,需要重新构建位码,但苹果从来没有这样做过。没有一款32位的应用程序能通过苹果重新编译位码而神奇地变成64位的。也没有一款64位的应用程序能通过苹果按需重新编译位码而神奇地适用于32位系统。作为一名开发人员,我可以向你保证,iOSAppStore总是提供你自己构建和签名的二进制代码,而从来没有任何苹果自己从Bitcode创建的代码,所以没有任何服务器端优化。没有一款macOS应用能神奇地转换为原生ARM,尽管苹果有Bitcode,所以应用商店中的所有x86应用都可以这样做。相反,苹果仍然发布了x86版本,并让它在Rosetta 2中运行。
因此,通过强制所有代码都以Bitcode的形式提供,然后不使用Bitcode给予你带来的任何好处,从而将各种不利因素强加给开发人员,这会让整个事情变得毫无意义。现在,所有平台都迁移到了ARM 64,在几年内,甚至不会再有胖二进制代码了(一旦x86对Mac的支持被放弃),继续做那些东西有什么意义呢?我猜苹果抓住机会一劳永逸地埋葬了这个想法。即使有一天他们在他们的平台上添加了RISC-V,开发人员仍然可以同时发布包含ARM 64和RISC-V代码的胖二进制代码。这个概念非常好用,简单得多,除了“更大的二进制代码”之外没有其他缺点,这是服务器端应用精简可以解决的问题,因为在下载过程中,只需要包含当前平台的代码。
ldxq2e6h2#
Apple Watch Series 3是最后一款不支持64位的设备(即i386或armv7)。
苹果现在已经停止支持Apple Watch Series 3。[1]他们本来很乐意放弃对位码的支持。
[1][https://www.xda-developers.com/watchos-9-not-coming-apple-watch-series-3](https://www.xda-developers.com/watchos-9-not-coming-apple-watch-series-3)
euoag5mw3#
xcode删除了armv7/armv 7s/i386目标支持。位代码用于构建不同的cpu目标。但是现在所有的设备可能都是arm 64。现在没有更多的开发者使用这个技术。所以弃用可能是一个明智的选择
eoxn13cs4#
位代码总是毫无意义的,因为即使你把位代码编译到另一个架构,也很有可能因为ABI不同而实际上不工作。例如,当你编译C程序时,每个架构的libc头实际上是不同的。我很高兴他们终于摆脱了它。因为它造成的问题比解决的问题多。他们最多只能为相同的架构重新优化二进制文件,或者足够相似的架构。还有位码构建中不需要的符号泄漏的问题,所以你要么重命名/混淆那些,要么被冲突击中(如果你是库/框架供应商,这是个大问题)。