ios ENABLE_BITCODE 在 xcode 7 中有什么作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30722606/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does ENABLE_BITCODE do in xcode 7?
提问by damithH
I have a problem with the embedded bitcode term.
What is embedded bitcode?
When to enable, ENABLE_BITCODE
in new Xcode?
What happens to the binary when enabled, ENABLE_BITCODE
in Xcode 7?
我对嵌入式位码术语有疑问。
什么是嵌入式位码?
何时启用,ENABLE_BITCODE
在新的 Xcode 中?在 Xcode 7 中
启用二进制文件会发生什么ENABLE_BITCODE
?
回答by keji
Bitcoderefers to to the type of code: "LLVM Bitcode" that is sent to iTunes Connect. This allows Apple to use certain calculations to re-optimize apps further (e.g: possibly downsize executable sizes). If Apple needs to alter your executable then they can do this without a new build being uploaded.
Bitcode指的是发送到 iTunes Connect 的代码类型:“LLVM Bitcode”。这允许 Apple 使用某些计算来进一步重新优化应用程序(例如:可能缩小可执行文件的大小)。如果 Apple 需要更改您的可执行文件,那么他们可以在不上传新版本的情况下执行此操作。
This differs from: Slicingwhich is the process of Apple optimizing your app for a user's device based on the device's resolution and architecture. Slicing does not require Bitcode. (Ex: only including @2x images on a 5s)
这不同于: 切片是 Apple 根据设备的分辨率和架构为用户的设备优化您的应用程序的过程。切片不需要位码。(例如:仅在 5s 上包含 @2x 图像)
App Thinningis the combination of slicing, bitcode, and on-demand resources
AppThinning 是切片、位码和按需资源的组合
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.
位码是已编译程序的中间表示。您上传到 iTunes Connect 的包含 bitcode 的应用程序将在 App Store 上编译和链接。包含 bitcode 将允许 Apple 将来重新优化您的应用程序二进制文件,而无需向商店提交新版本的应用程序。
回答by Maxim Pavlov
What is embedded bitcode?
什么是嵌入式位码?
According to docs:
根据文档:
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.
位码是已编译程序的中间表示。您上传到 iTunes Connect 的包含 bitcode 的应用程序将在 App Store 上编译和链接。包含 bitcode 将允许 Apple 将来重新优化您的应用程序二进制文件,而无需向商店提交新版本的应用程序。
Update:This phrase in "New Features in Xcode 7"made me to think for a long time that Bitcodeis needed for Slicingto reduce app size:
更新:“Xcode 7 中的新功能”中的这句话让我想了很长时间,Slicing需要使用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 会将您的应用程序编译为中间表示。然后,App Store 会根据需要将位代码编译为 64 位或 32 位可执行文件。
However that's not true, Bitcodeand Slicingwork independently: Slicingis about reducing app size and generating app bundle variants, and Bitcodeis about certain binary optimizations. I've verified this by checking included architectures in executables of non-bitcode apps and founding that they only include necessary ones.
然而事实并非如此,Bitcode和Slicing独立工作:Slicing是关于减少应用程序大小和生成应用程序包变体,而Bitcode是关于某些二进制优化。我已经通过检查非位代码应用程序的可执行文件中包含的架构并发现它们只包含必要的架构来验证这一点。
Bitcodeallows other App Thinningcomponent called Slicingto generate app bundle variants with particular executables for particular architectures, e.g. iPhone 5S variant will include only arm64 executable, iPad Mini armv7 and so on.
Bitcode允许其他称为Slicing 的App Thinning组件生成具有特定架构的特定可执行文件的应用程序包变体,例如 iPhone 5S 变体将仅包含 arm64 可执行文件、iPad Mini armv7 等。
When to enable ENABLE_BITCODE in new Xcode?
何时在新 Xcode 中启用 ENABLE_BITCODE?
For iOS apps, bitcode is the default, but optional. If you provide bitcode, all apps and frameworks in the app bundle need to include bitcode. For watchOS and tvOS apps, bitcode is required.
对于 iOS 应用程序,位码是默认的,但可选的。如果您提供 bitcode,则应用程序包中的所有应用程序和框架都需要包含 bitcode。对于 watchOS 和 tvOS 应用程序,位码是必需的。
What happens to the binary when ENABLE_BITCODE is enabled in the new Xcode?
在新 Xcode 中启用 ENABLE_BITCODE 时,二进制文件会发生什么变化?
From Xcode 7 reference:
从 Xcode 7 参考:
Activating this setting indicates that the target or project should generate bitcode during compilation for platforms and architectures which support it. For Archive builds, bitcode will be generated in the linked binary for submission to the app store. For other builds, the compiler and linker will check whether the code complies with the requirements for bitcode generation, but will not generate actual bitcode.
激活此设置表示目标或项目应在编译期间为支持它的平台和体系结构生成位代码。对于存档构建,将在链接的二进制文件中生成位代码以提交到应用商店。对于其他构建,编译器和链接器将检查代码是否符合位码生成的要求,但不会生成实际的位码。
Here's a couple of links that will help in deeper understanding of Bitcode:
这里有几个链接将有助于更深入地理解Bitcode:
回答by Earlz
Since the exact question is "what does enable bitcode do", I'd like to give a few thin technical details I've figured out thus far. Most of this is practically impossible to figure out with 100% certainty until Apple releases the source code for this compiler
由于确切的问题是“启用位码有什么作用”,我想提供一些迄今为止我已经弄清楚的技术细节。在 Apple 发布此编译器的源代码之前,几乎不可能 100% 确定地弄清楚其中的大部分内容
First, Apple's bitcode does not appearto be the same thing as LLVM bytecode. At least, I've not been able to figure out any resemblance between them. It appears to have a proprietary header (always starts with "xar!") and probably some link-time reference magic that prevents data duplications. If you write out a hardcoded string, this string will only be put into the data once, rather than twice as would be expected if it was normal LLVM bytecode.
首先,苹果的位码不显示是同样的事情LLVM字节码。至少,我一直无法弄清楚它们之间有任何相似之处。它似乎有一个专有的标头(总是以“xar!”开头),可能还有一些防止数据重复的链接时引用魔法。如果你写出一个硬编码的字符串,这个字符串只会被放入数据一次,而不是如果它是正常的 LLVM 字节码所预期的两倍。
Second, bitcode is not really shipped in the binary archive as a separate architecture as might be expected. It is not shipped in the same way as say x86 and ARM are put into one binary (FAT archive). Instead, they use a special section in the architecture specific MachO binary named "__LLVM" which is shipped with every architecture supported (ie, duplicated). I assume this is a short coming with their compiler system and may be fixed in the future to avoid the duplication.
其次,bitcode 并没有像预期的那样作为单独的体系结构在二进制存档中真正提供。它的交付方式与将 x86 和 ARM 放入一个二进制文件(FAT 存档)的方式不同。相反,他们在特定于体系结构的 MachO 二进制文件中使用了一个名为“__LLVM”的特殊部分,该部分随支持的每个体系结构(即重复的)一起提供。我认为这是他们的编译器系统的一个缺点,将来可能会修复以避免重复。
C code (compiled with clang -fembed-bitcode hi.c -S -emit-llvm
):
C 代码(用 编译clang -fembed-bitcode hi.c -S -emit-llvm
):
#include <stdio.h>
int main() {
printf("hi there!");
return 0;
}
LLVM IR output:
LLVM 红外输出:
; ModuleID = '/var/folders/rd/sv6v2_f50nzbrn4f64gnd4gh0000gq/T/hi-a8c16c.bc'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.10.0"
@.str = private unnamed_addr constant [10 x i8] c"hi there!; ModuleID = '1'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.10.0"
@.str = private unnamed_addr constant [10 x i8] c"hi there!##代码##", align 1
; Function Attrs: nounwind ssp uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
store i32 0, i32* %1
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i32 0, i32 0))
ret i32 0
}
declare i32 @printf(i8*, ...) #1
attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="core2" "target-features"="+ssse3,+cx16,+sse,+sse2,+sse3" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="core2" "target-features"="+ssse3,+cx16,+sse,+sse2,+sse3" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"PIC Level", i32 2}
!1 = !{!"Apple LLVM version 7.0.0 (clang-700.1.76)"}
", align 1
@llvm.embedded.module = appending constant [1600 x i8] c"\DE\C0##代码##B##代码####代码####代码####代码####代码####代码####代码##$##代码####代码####代码####代码##BC\C0\DE!##代码##C##代码####代码####代码####代码####代码##B ##代码####代码####代码####代码####代码####代码####代码###A\C8I29##代码##C%EBbEB##代码##BB28I##代码##A2D$H##代码##A!#\C4R##代码##C!r$\C8b\A8\A0\A8@\C6\F0##代码####代码####代码##Q##代码####代码##\C7##代码####代码####代码##Bp$\F8\FF\FF\FF\FF##代码####代码##DD\CAaE\E6\A1##代码##D\E0AE\CAaC\D2aE\CA\A1##代码##D\CCE\DA!C\C80p`y(pwhsphrhxxtpz(yhr`thE\E4\A1E\CA\DC\E1D\DA\C0C\E4!C\DA\A1C\DA##代码##E\DE!D\DCE\CAAE\DA\A0C\D8!D\DA\A1##代码##D\DC\E1D\DC\A1##代码##D\D8\A1C\C2\C1C##代码##\C2D\DE\A1##代码##D\D2\C1D\CCaE\DA\C0C\E0\A1##代码##D\DA!C\E8D##代码##svr##代码##wx6pppyhs6hp\A0t##代码##\CC!C\D8aE\CA \E6E\C2aC\D6\A1##代码##D\E0AE\DEE\CAaC\E8\E1D\E4\A1##代码##D\C4\A1E\CC\C1C\CAAE\DA`E\D2AF\CA\C0\A0ps(zhqz##代码##\C6\E1D\E4\A1C\E4##代码## \E8!C\E4\E1C\CAE\DA\C0C\CA!C\E8\A1E\E4\A1C\E6Xyy(9`5|;`5y(6Xyr6Xyr\A8wp0rhs6hp\A0t##代码##\CC!C\D8aE\CA \EAaE\CA\A1##代码##D\E6\E1D\CCE\DA\C0C\D8\E1D\C2E##代码##svr##代码##6\C8\F0\FF\FF\FF\FF\C1##代码##E\E50##代码##F\F3\D0\F0 ##代码##F\E50##代码##E\E90##代码##F\E5\D0\E6##代码####代码##F\ED##代码##E\E4##代码##C8\B0\C3<@\B8\C3;\B49\C8C8\B4C9\B4<\BCC:\B8=<\B4A9\B0C:\B4@##代码##F\F2P##代码##F\E5##代码####代码##C\EE\F0##代码##Em`##代码##E\F2##代码##E\EDP##代码##Em##代码####代码##F\EF##代码##E\EE@##代码##F\E5 ##代码##FmP##代码##E\EC##代码##E\ED\D0\EE\F0##代码##E\EE\D0\ECP##代码##E\E1`##代码##E##代码##\E1##代码##E\EF\D0\E9\E0##代码##E\E60##代码##Fm`##代码##E\F0\D0\ED##代码##E\F4##代码##E9;\CCC9##代码##;\BCCB\B8C8\B8\C3<\B49\C0CB\B4C8\D0:##代码##\E6##代码##E\EC0##代码##F\E5##代码##\F3@##代码##F\E10##代码##E\EB\D0\F0 ##代码##F\EF@##代码##F\E50##代码##E\F4\F0##代码##E\F2\D0\E2P##代码##F\E6`##代码##E\E5 ##代码##Fm0##代码##F\E9\A0##代码##F\E5##代码##\E0@\D0C8\C8\C39=\B4\C18\C0C=##代码##\E3\F0##代码##E\F2P##代码##Er##代码##\F4##代码##E\F2p##代码##E\E5@##代码##Fm`##代码##E\E5##代码##E\F4P##代码##F\F2P##代码##E\F3##代码##\AC\C1<\CC\C3<\C3C\B0\C1AC>\C4D\B0\C1A\CC\C3<B\AC\C1<\CCC9\C8B\AC\C1<\CCC9\CC@\D4;\CCC8C9\B49\C0CB\B4C8\D0:##代码##\E6##代码##E\EC0##代码##F\E5##代码##\F50##代码##F\E5\D0\F3\F0##代码##E\E6@##代码##Fm`##代码##E\EC\F0##代码##E\E1@##代码##F9;\CCC9##代码####代码##I##代码####代码####代码####代码####代码##`B ##代码####代码####代码## ##代码####代码####代码##D##代码####代码####代码##2 d\A4\E3\A1LC##代码##BL0sH*##代码##\C5C`\AA0F7@3##代码##4|\C0;\F8;\A06xv(6hpw|8p87##代码##DeP##代码##Em\D0##代码##Ez\F0##代码##Em##代码##Ev@z`t\D0\E6p\A0q x\D0\EEzv\A0s z`t\D0\B3r:##代码##FDH #EBDCI##代码####代码##@##代码####代码##\C0\A7##代码####代码## ##代码####代码####代码####代码####代码####代码####代码##8##代码####代码####代码####代码####代码####代码####代码####代码####代码####代码####代码####代码##2E##代码##CLC&G\C6CA(##代码##AM\D0iD]C##代码####代码####代码##y##代码####代码##C##代码####代码####代码##ALF4A&PIC Levela\D80\C2\C05c+ab\B2j\B1+BK{s\B9qqAc##代码##Bs;k\B9qq\A9qI\D9D\D8\D8\EC\DAC\DA\DE\C8\EA\D8\CAC\CC\D8\C2\CE\E6\A6C66\BB64\B227\BA)A##代码##y##代码####代码##2##代码####代码####代码##3C\C4\E1Cf=C8\C3CByxsq##代码##C\E6##代码####代码##F\ED##代码##E\F4##代码##E3##代码##CBE\C2\C1D\CE\A1Cf0=C8B\CC=\C8C=C=\CCxCtp{yHppzpvxp \CC##代码##E\EC##代码##E\E10##代码##Fn0##代码##F\E3\F0##代码##E\F0P##代码##E3\C4D\DE!C\D8!D\C2aEf0;\BC;\D0C9\B4<\BC<;\CC\F0v`{h7hrh7pp`v(v\F8vxw_qry,\EE\F0##代码##E\EE\E0##代码##E\F5\C0##代码##E\EC##代码##q ##代码####代码####代码####代码####代码##&`<\D2L##代码##C4@\F8\D2##代码####代码##a ##代码####代码####代码##B##代码####代码####代码##A,##代码####代码####代码####代码####代码####代码##4###代码##dC0##代码##3\CA@##代码##C\C1##代码####代码#####代码##CB##代码####代码####代码####代码####代码####代码####代码####代码####代码####代码####代码####代码####代码####代码####代码##", section "__LLVM,__bitcode"
@llvm.cmdline = appending constant [67 x i8] c"-triple##代码##x86_64-apple-macosx10.10.0##代码##-emit-llvm##代码##-disable-llvm-optzns##代码##", section "__LLVM,__cmdline"
; Function Attrs: nounwind ssp uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
store i32 0, i32* %1
%2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0))
ret i32 0
}
declare i32 @printf(i8*, ...) #1
attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="core2" "target-features"="+ssse3,+cx16,+sse,+sse2,+sse3" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="core2" "target-features"="+ssse3,+cx16,+sse,+sse2,+sse3" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"PIC Level", i32 2}
!1 = !{!"Apple LLVM version 7.0.0 (clang-700.0.53.3)"}
The data array that is in the IR also changes depending on the optimization and other code generation settings of clang. It's completely unknown to me what format or anything that this is in.
IR 中的数据数组也会根据 clang 的优化和其他代码生成设置而变化。我完全不知道这是什么格式或任何东西。
EDIT:
编辑:
Following the hint on Twitter, I decided to revisit this and to confirm it. I followed this blog postand used his bitcode extractor tool to get the Apple Archive binary out of the MachO executable. And after extracting the Apple Archive with the xar utility, I got this (converted to text with llvm-dis of course)
按照 Twitter 上的提示,我决定重新审视并确认它。我关注了这篇博客文章,并使用他的位码提取器工具从 MachO 可执行文件中获取了 Apple Archive 二进制文件。在使用 xar 实用程序提取 Apple Archive 后,我得到了这个(当然是用 llvm-dis 转换为文本)
##代码##The only notable difference really between the non-bitcode IR and the bitcode IR is that filenames have been stripped to just 1, 2, etc for each architecture.
非位码 IR 和位码 IR 之间唯一显着的区别是每个架构的文件名都被剥离为 1、2 等。
I also confirmed that the bitcode embedded in a binary is generated after optimizations. If you compile with -O3 and extract out the bitcode, it'll be different than if you compile with -O0.
我还确认嵌入在二进制文件中的位码是在优化后生成的。如果你用 -O3 编译并提取出位码,它会与你用 -O0 编译不同。
And just to get extra credit, I also confirmed that Apple does not ship bitcode to devices when you download an iOS 9 app. They include a number of other strange sections that I don't recognized like __LINKEDIT, but they do not include __LLVM.__bundle, and thus do not appear to include bitcode in the final binary that runs on a device. Oddly enough, Apple still ships fat binaries with separate 32/64bit code to iOS 8 devices though.
为了获得额外的荣誉,我还确认当您下载 iOS 9 应用程序时,Apple 不会向设备发送位代码。它们包括许多其他我不认识的奇怪部分,例如 __LINKEDIT,但它们不包括 __LLVM.__bundle,因此在设备上运行的最终二进制文件中似乎不包括位码。奇怪的是,Apple 仍然向 iOS 8 设备提供带有单独 32/64 位代码的胖二进制文件。
回答by Inder Kumar Rathore
Bitcode (iOS, watchOS)
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.
位码(iOS、watchOS)
位码是已编译程序的中间表示。您上传到 iTunes Connect 的包含 bitcode 的应用程序将在 App Store 上编译和链接。包含 bitcode 将允许 Apple 将来重新优化您的应用程序二进制文件,而无需向商店提交新版本的应用程序。
Basically this concept is somewhat similar to java where byte code is run on different JVM's and in this case the bitcode is placed on iTune store and instead of giving the intermediate code to different platforms(devices) it provides the compiled code which don't need any virtual machine to run.
基本上这个概念有点类似于 java,其中字节码在不同的 JVM 上运行,在这种情况下,位码放在 iTune 存储中,而不是将中间代码提供给不同的平台(设备),它提供不需要的编译代码要运行的任何虚拟机。
Thus we need to create the bitcode once and it will be available for existing or coming devices. It's the Apple's headache to compile an make it compatible with each platform they have.
因此,我们需要创建一次位码,它将可用于现有或即将推出的设备。编译并使其与他们拥有的每个平台兼容是 Apple 的头疼事。
Devs don't have to make changes and submit the app again to support new platforms.
开发人员不必进行更改并再次提交应用程序以支持新平台。
Let's take the exampleof iPhone 5s when apple introduced x64
chip in it. Although x86
apps were totally compatible with x64
architecture but to fully utilise the x64
platform the developer has to change the architecture or some code. Once s/he's done the app is submitted to the app store for the review.
我们以苹果引入x64
芯片的iPhone 5s为例。尽管x86
应用程序与x64
架构完全兼容,但要充分利用x64
平台,开发人员必须更改架构或一些代码。她/她完成后,应用程序将提交到应用程序商店进行审核。
If this bitcode concept was launched earlier then we the developers doesn't have to make any changes to support the x64
bit architecture.
如果这个 bitcode 概念更早推出,那么我们开发人员就不必进行任何更改来支持x64
bit 架构。
回答by Ben Flynn
Update
更新
Apple has clarifiedthat slicing occurs independent of enabling bitcode. I've observed this in practice as well where a non-bitcode enabled app will only be downloaded as the architecture appropriate for the target device.
Apple 已经澄清,切片的发生与启用位码无关。我在实践中也观察到了这一点,其中不支持位码的应用程序只会作为适合目标设备的架构下载。
Original
原来的
Bitcode. Archive your app for submission to the App Store in an intermediate representation, which is compiled into 64- or 32-bit executables for the target devices when delivered.
Slicing. Artwork incorporated into the Asset Catalog and tagged for a platform allows the App Store to deliver only what is needed for installation.
位码。归档您的应用程序,以中间表示形式提交到 App Store,在交付时将其编译为目标设备的 64 位或 32 位可执行文件。
切片。纳入资产目录并标记为平台的艺术品允许 App Store 仅提供安装所需的内容。
The way I read this, if you support bitcode, downloaders of your app will only get the compiled architecture needed for their own device.
我读这个的方式,如果你支持位码,你的应用程序的下载者只会得到他们自己设备所需的编译架构。