Что позволяет BITCODE делать в xcode 7?


у меня проблема со встроенным битовым кодом.
Что такое встроенный биткод?
Когда включить, ENABLE_BITCODE в новом Xcode?
Что происходит с двоичным кодом при включении,ENABLE_BITCODE в Xcode 7 ?

6 237

6 ответов:

Bitcode относится к типу кода: "LLVM Bitcode", который отправляется в iTunes Connect. Это позволяет Apple использовать определенные вычисления для дальнейшей оптимизации приложений (например, возможно уменьшение размеров исполняемых файлов). Если Apple необходимо изменить исполняемый файл, то они могут сделать это без новой сборки загружается.

Это отличается от: для нарезки что представляет собой процесс оптимизации Apple вашего приложения для устройства пользователя на основе разрешения устройства и архитектура. Нарезка не требует битового кода. (Например: только в том числе @2x изображений на 5s)

Приложение Истончение это сочетание нарезки, битового кода и ресурсов по требованию

Bitcode-это промежуточное представление скомпилированной программы. Приложения вы загружаете в iTunes Connect, которые содержат биткод будет скомпилирован и связано в магазине приложений. В том числе bitcode позволит Apple повторно оптимизируйте двоичный файл приложения в будущем без необходимости представить новая версия вашего приложения в магазине.

документация Apple по истончению приложений

Что такое встроенный биткод?

по данным docs:

Bitcode-это промежуточное представление скомпилированной программы. Приложения, которые вы загружаете в iTunes Connect, содержащие биткод, будут скомпилированы и связаны в магазине приложений. В том числе bitcode позволит Apple повторно оптимизировать ваше двоичное приложение в будущем без необходимости отправлять новую версию вашего приложения в магазин.

обновление: эта фраза в "новые возможности в Xcode 7" заставил меня долго думать, что Bitcode нужен для нарезки чтобы уменьшить размер приложения:

когда вы архивируете для отправки в магазин приложений, Xcode скомпилирует ваше приложение в промежуточное представление. Затем магазин приложений скомпилирует битовый код в 64 или 32-разрядные исполняемые файлы по мере необходимости.

однако это не так, Bitcode и для нарезки работать автономно: для нарезки заключается в уменьшении размера приложения и создании вариантов пакета приложений, а также Bitcode речь идет о некоторых бинарных оптимизациях. Я проверил это, проверив включенные архитектуры в исполняемых файлах небитовых приложений и установив, что они включают только необходимые.

Bitcode другие Приложение Истончение компонент, называемый для нарезки создать варианты пакетов приложений с конкретными исполняемыми файлами для конкретных архитектур, например, вариант iPhone 5S будет включать только исполняемый файл arm64, iPad Mini armv7 и т. д.

когда включить ENABLE_BITCODE в новом Xcode?

для iOS приложений, bitcode по умолчанию, но необязательно. Если вы предоставляете bitcode, все приложения и фреймворки в пакете приложений должны включать bitcode. Для приложений watchOS и tvOS требуется биткод.

Что происходит с двоичный, когда ENABLE_BITCODE включен в новом Xcode?

из ссылки Xcode 7:

активация этого параметра указывает на то, что цель или проект должны генерировать битовый код во время компиляции для платформ и архитектур, которые его поддерживают. Для архивных сборок битовый код будет сгенерирован в связанном двоичном файле для отправки в магазин приложений. Для других сборок компилятор и компоновщик проверят, соответствует ли код требованиям для bitcode генерация, но не будет генерировать фактический биткод.

вот пара ссылок, которые помогут в более глубоком понимании Bitcode:

Что касается битового кода и включения битового кода, первое, что требуется понять, - это история, с которой все это началось.

Итак, в основном, если я говорю о ENABLE_BITCODE который представлен в iOS 9, является частью процесса прореживания приложения.

и это часть проблемы, которая отвечает на "как Apple удалось уменьшить размер хранилища iOS 9 до 1 ГБ с 5 ГБ в iOS 8?"

Это связано с новой технология называется "приложение истончение"

и что именно приложение истончение ?

истончение приложения снижает обновление iOS 9 OTA с 4,6 ГБ до 1,3 ГБ, уменьшение размера на 71%. Это не только поможет с будущими обновлениями OTA, но и технология будет доступна для разработчиков, чтобы уменьшить объем памяти, необходимый сторонним приложениям.

приложение thinning имеет в основном три компонента, а именно-нарезка, bitcode и ресурсы по требованию.

приложения Нарезка: приложения iOS разработаны для работы на различных устройствах, поэтому они поставляются с кодом для поддержки всех их, независимо от того, требует ли это ваше конкретное устройство. Нарезка приложений позволит вашему устройству загружать только те файлы, которые требуются нашему устройству. Пример: вам не нужны активы 3x iPhone 6 Plus, если вы используете 4-дюймовую модель.

Ресурсы По Требованию (ODR): Он работает на идее, что приложение, вероятно, не нужно всю свою библиотеку ресурсов в любом случае учитывая время, поэтому его части могут быть загружены или удалены по мере необходимости. Разработчики смогут указать, какой код необходим в какое время, пометив разделы кода как oDR. Эти части будут автоматически загружены из магазина приложений, когда они необходимы, и удалены, когда они больше не понадобятся.

Bitcode: это относится к" промежуточному представлению " приложения, которое разработчики будут загружать в магазин приложений, а не к предварительно скомпилированному двоичному файлу. Эта работа рука об руку с приложением нарезки, что позволяет битовый код будет скомпилирован по требованию как 32-разрядный или 64-разрядный, в зависимости от устройства загрузки. Это также позволит автоматически реализовать любые улучшения компилятора, сделанные Apple, вместо того, чтобы разработчики повторно отправляли свои приложения.

enter image description here

поскольку точный вопрос:" что позволяет bitcode делать", я хотел бы дать несколько тонких технических деталей, которые я выяснил до сих пор. Большую часть этого практически невозможно понять со 100% уверенностью, пока Apple не выпустит исходный код для этого компилятора

во-первых, биткод Apple не появляется быть то же самое, что и байт-код LLVM. По крайней мере, я не смог найти между ними никакого сходства. Похоже, у него есть собственный заголовок (всегда начинается с "xar!") и, вероятно, какая-то ссылка на ссылку времени, которая предотвращает дублирование данных. Если вы выпишете жестко закодированную строку, эта строка будет помещена в данные только один раз, а не дважды, как ожидалось бы, если бы это был обычный байт-код LLVM.

во-вторых, bitcode на самом деле не поставляется в двоичном архиве как отдельная архитектура, как можно было бы ожидать. Он не поставляется так же, как говорят x86 и ARM помещаются в один двоичный файл (архив FAT). Вместо этого они используют специальный раздел в архитектуре конкретного двоичного мачо с именем "_ _ LLVM", который поставляется с каждой поддерживаемой архитектурой (т. е. дублируется). Я предполагаю, что это недостаток с их системой компилятора и может быть исправлено в будущем, чтобы избежать дублирования.

C код (компилируется с clang -fembed-bitcode hi.c -S -emit-llvm):

#include <stdio.h>

int main() {
    printf("hi there!");
    return 0;
}

выход ИК 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!", align 1
@llvm.embedded.module = appending constant [1600 x i8] c"\DE\C0B$BC\C0\DE!CB #A\C8I29C%EBbEBBB28IA2D$HA!#\C4RC!r$\C8b\A8\A0\A8@\C6\F0Q\C7Bp$\F8\FF\FF\FF\FFDD\CAaE\E6\A1D\E0AE\CAaC\D2aE\CA\A1D\CCE\DA!C\C80p`y(pwhsphrhxxtpz(yhr`thE\E4\A1E\CA\DC\E1D\DA\C0C\E4!C\DA\A1C\DAE\DE!D\DCE\CAAE\DA\A0C\D8!D\DA\A1D\DC\E1D\DC\A1D\D8\A1C\C2\C1C\C2D\DE\A1D\D2\C1D\CCaE\DA\C0C\E0\A1D\DA!C\E8Dsvrwx6pppyhs6hp\A0t\CC!C\D8aE\CA \E6E\C2aC\D6\A1D\E0AE\DEE\CAaC\E8\E1D\E4\A1D\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\A1D\E6\E1D\CCE\DA\C0C\D8\E1D\C2Esvr6\C8\F0\FF\FF\FF\FF\C1E\E50F\F3\D0\F0 F\E50E\E90F\E5\D0\E6F\EDE\E4C8\B0\C3<@\B8\C3;\B49\C8C8\B4C9\B4<\BCC:\B8=<\B4A9\B0C:\B4@F\F2PF\E5C\EE\F0Em`E\F2E\EDPEmF\EFE\EE@F\E5 FmPE\ECE\ED\D0\EE\F0E\EE\D0\ECPE\E1`E\E1E\EF\D0\E9\E0E\E60Fm`E\F0\D0\EDE\F4E9;\CCC9;\BCCB\B8C8\B8\C3<\B49\C0CB\B4C8\D0:\E6E\EC0F\E5\F3@F\E10E\EB\D0\F0 F\EF@F\E50E\F4\F0E\F2\D0\E2PF\E6`E\E5 Fm0F\E9\A0F\E5\E0@\D0C8\C8\C39=\B4\C18\C0C=\E3\F0E\F2PEr\F4E\F2pE\E5@Fm`E\E5E\F4PF\F2PE\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:\E6E\EC0F\E5\F50F\E5\D0\F3\F0E\E6@Fm`E\EC\F0E\E1@F9;\CCC9I`B  D2 d\A4\E3\A1LCBL0sH*\C5C`\AA0F7@34|\C0;\F8;\A06xv(6hpw|8p87DePEm\D0Ez\F0EmEv@z`t\D0\E6p\A0q x\D0\EEzv\A0s z`t\D0\B3r:FDH #EBDCI@\C0\A7 82ECLC&G\C6CA(AM\D0iD]CyCALF4A&PIC Levela\D80\C2\C05c+ab\B2j\B1+BK{s\B9qqAcBs;k\B9qq\A9qI\D9D\D8\D8\EC\DAC\DA\DE\C8\EA\D8\CAC\CC\D8\C2\CE\E6\A6C66\BB64\B227\BA)Ay23C\C4\E1Cf=C8\C3CByxsqC\E6F\EDE\F4E3CBE\C2\C1D\CE\A1Cf0=C8B\CC=\C8C=C=\CCxCtp{yHppzpvxp \CCE\ECE\E10Fn0F\E3\F0E\F0PE3\C4D\DE!C\D8!D\C2aEf0;\BC;\D0C9\B4<\BC<;\CC\F0v`{h7hrh7pp`v(v\F8vxw_qry,\EE\F0E\EE\E0E\F5\C0E\ECq &`<\D2LC4@\F8\D2a BA,4#dC03\CA@C\C1#CB", section "__LLVM,__bitcode"
@llvm.cmdline = appending constant [67 x i8] c"-triplex86_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)"}

массив данных, который находится в ИК, также изменяется в зависимости от оптимизации и генерации кода другие параметры лязг. Это мне совершенно неизвестно, в каком формате или что это.

EDIT:

следуя подсказке в Twitter, Я решил вернуться к этому и подтвердить его. Я последовал этот блог и использовал свой инструмент извлечения битового кода, чтобы получить двоичный файл архива Apple из исполняемого файла MachO. И после извлечения архива Apple с помощью утилиты xar я получил это (преобразовано в текст с помощью llvm-dis, конечно)

; 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)"}

единственный заметный разница на самом деле между ИК-битовым кодом и ИК-битовым кодом заключается в том, что имена файлов были разделены только на 1, 2 и т. д. Для каждой архитектуры.

Я также подтвердил, что битовый код, встроенный в двоичный файл, генерируется после оптимизации. Если вы компилируете с-O3 и извлекаете битовый код, он будет отличаться от компиляции с-O0.

и просто чтобы получить дополнительный кредит, я также подтвердил, что Apple не отправляет bitcode на устройства при загрузке приложения iOS 9. Они включите ряд других странных разделов, которые я не распознал как __LINKEDIT, но они не включают __LLVM.__bundle, и, таким образом, не включают bitcode в окончательный двоичный файл, который работает на устройстве. Как ни странно, Apple по-прежнему поставляет жирные двоичные файлы с отдельным 32/64-битным кодом на устройства iOS 8.

Bitcode (iOS, watchOS)

Bitcode-это промежуточное представление скомпилированной программы. Приложения, которые вы загружаете в iTunes Connect, содержащие биткод, будут скомпилированы и связаны в магазине приложений. В том числе bitcode позволит Apple повторно оптимизировать ваше двоичное приложение в будущем без необходимости отправлять новую версию вашего приложения в магазин.


в основном эта концепция несколько похожа на java, где байтовый код запускается на разных JVM, и в этом случае биткод помещается в хранилище iTune, и вместо того, чтобы давать промежуточный код различным платформам(устройствам), он предоставляет скомпилированный код, который не нуждается в какой-либо виртуальной машине для запуска.

таким образом, нам нужно создать биткод один раз, и он будет доступен для существующих или будущих устройств. Это головная боль Apple, чтобы скомпилировать сделать его совместимым с каждой платформой, которую они имеют.

разработчики не должны делать изменения и отправить приложение снова для поддержки новых платформ.

давайте возьмем пример iPhone 5s, когда apple представила x64 чип в нем. Хотя x86 приложения полностью совместимые с x64 архитектура, но чтобы полностью использовать разработчик должен изменить архитектуру или какой-то код. После того, как он/она сделал приложение отправляется в магазин приложений для обзора.

если эта концепция битового кода была запущена ранее, то мы, разработчики, не должны вносить никаких изменений в поддержку x64 битной архитектурой.

обновление

компания Apple уточнила, что нарезка происходит независимо от включения битового кода. Я наблюдал это на практике, а также там, где приложение с поддержкой небитового кода будет загружено только как архитектура, подходящая для целевого устройства.

Оригинал

более конкретно:

Bitcode. Архивируйте приложение для отправки в магазин приложений в виде промежуточный представление, которое компилируется в 64-или 32-разрядное программы для целевых устройств при доставке.

нарезки. Произведение искусства, включенное в каталог активов и помеченное для a платформа позволяет App Store доставлять только то, что необходимо для установка.

Как я читал, если вы поддерживаете bitcode, загрузчики вашего приложения получат только скомпилированную архитектуру, необходимую для их собственного устройства.