¿Qué hace HABILITAR BITCODE en xcode 7?


Tengo un problema con el término bitcode incrustado.
Qué es embedded bitcode?
¿Cuándo habilitar, ENABLE_BITCODE en nuevo Xcode?
¿Qué sucede con el binario cuando está habilitado, ENABLE_BITCODE en Xcode 7 ?

Author: damithH, 2015-06-09

6 answers

Bitcode se refiere al tipo de código: "LLVM Bitcode" que se envía a iTunes Connect. Esto permite a Apple utilizar ciertos cálculos para volver a optimizar las aplicaciones (por ejemplo: posiblemente reducir el tamaño de los ejecutables). Si Apple necesita alterar su ejecutable, puede hacerlo sin cargar una nueva compilación.

Esto difiere de: Cortar que es el proceso de Apple optimizando su aplicación para el dispositivo de un usuario en función de la resolución y la arquitectura del dispositivo. Rebanar no requiere Bitcode. (Ejemplo: solo incluye @2x imágenes en un 5s)

El adelgazamiento de aplicaciones es la combinación de corte, bitcode y recursos bajo demanda

Bitcode es una representación intermedia de un programa compilado. Aplicaciones subir a iTunes Connect que contienen bitcode se compilará y vinculado en la App Store. Incluyendo bitcode permitirá a Apple a vuelva a optimizar el binario de su aplicación en el futuro sin la necesidad de enviar un nueva versión de su aplicación a la almacenar.

Documentación de Apple sobre el Adelgazamiento de aplicaciones

 282
Author: kezi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-09 05:54:07

¿Qué es bitcode incrustado?

De acuerdo con docs :

Bitcode es una representación intermedia de un programa compilado. Las aplicaciones que cargues a iTunes Connect que contengan bitcode se compilarán y vincularán en la App Store. La inclusión de bitcode permitirá a Apple volver a optimizar el binario de su aplicación en el futuro sin la necesidad de enviar una nueva versión de su aplicación a la tienda.

Actualización: Esta frase en "Nuevas Características en Xcode 7" hecho yo pensar durante mucho tiempo que Bitcode es necesario para Rebanar para reducir el tamaño de la aplicación:

Cuando archive para enviarlo a la App Store, Xcode compilará su aplicación en una representación intermedia. La Tienda de aplicaciones compilará el bitcode en los ejecutables de 64 o 32 bits según sea necesario.

Sin embargo, eso no es cierto, Bitcode y Slicing funcionan de forma independiente: Slicing se trata de reducir el tamaño de la aplicación y generar variantes de paquetes de aplicaciones, y Bitcode se trata de ciertas optimizaciones binarias. He verificado esto comprobando arquitecturas incluidas en ejecutables de aplicaciones no-bitcode y estableciendo que solo incluyen las necesarias.

Bitcode permite que otro componente App Thinning llamado Slicing genere variantes de paquetes de aplicaciones con ejecutables particulares para arquitecturas particulares, por ejemplo, la variante iPhone 5S incluirá solo ejecutable arm64, iPad Mini armv7 y así sucesivamente.

¿Cuándo habilitar ENABLE_BITCODE en el nuevo Xcode?

Para las aplicaciones iOS, bitcode es el valor predeterminado, pero opcional. Si proporciona bitcode, todas las aplicaciones y marcos en el paquete de aplicaciones deben incluir bitcode. Para las aplicaciones watchOS y tvOS, se requiere bitcoin.

¿Qué sucede con el binario cuando ENABLE_BITCODE está habilitado en el nuevo Xcode?

De Xcode 7 referencia:

La activación de esta configuración indica que el destino o el proyecto debe generar bitcode durante la compilación para plataformas y arquitecturas que lo soporten. Para las compilaciones de archivos, bitcode se generará en el binario vinculado para su envío a la tienda de aplicaciones. Para otras compilaciones, el compilador y el enlazador verificarán si el código cumple con los requisitos para la generación de bitcode, pero no generará bitcode real.

Aquí hay un par de enlaces que ayudarán a una comprensión más profunda de Bitcode :

 78
Author: Maxim Pavlov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-29 08:43:27

En lo que respecta al código de bits y habilitar el código de bits, lo primero que se requiere para entender es la historia desde donde comenzó todo esto.

Así que, básicamente si hablo de ENABLE_BITCODE que se introduce en iOS 9, es una parte del proceso de adelgazamiento de aplicaciones.

Y es una parte del problema que responde " ¿Cómo Apple logró reducir el tamaño de almacenamiento de iOS 9 a 1 GB de 5 GB en iOS 8?"

Esto se debe a una nueva tecnología llamada ' App Adelgazamiento'

Y ¿qué es exactamente el adelgazamiento de aplicaciones ?

El adelgazamiento de aplicaciones reduce la actualización OTA de iOS 9 de 4.6 GB a 1.3 GB, una reducción de tamaño del 71%. Esto no solo ayudará con futuras actualizaciones de OTA, sino que la tecnología estará disponible para que los desarrolladores reduzcan el almacenamiento requerido por las aplicaciones de terceros.

El adelgazamiento de aplicaciones tiene básicamente tres componentes, a saber: rebanar, bitcode y recursos bajo demanda.

App Slicing: Las aplicaciones iOS están desarrolladas para ejecutarse en una variedad de dispositivos, por lo que vienen con código para admitir todos ellos, ya sea que su dispositivo en particular lo requiera o no. App Slicing permitirá que su dispositivo descargue solo los archivos requeridos por nuestro dispositivo. Ejemplo: no necesita los activos 3x iPhone 6 Plus si está ejecutando un modelo de 4 pulgadas.

On-Demand Resources (ODRs): Funciona con la idea de que una aplicación probablemente no necesita toda su biblioteca de recursos en un momento dado, por lo que partes de ella se pueden descargar o eliminar según sea necesario. Desarrollador podrá especificar qué código se necesita en qué momentos etiquetando secciones de código como ODRs. Estas partes se descargarán automáticamente de la App Store cuando se requieran y se eliminarán cuando no se vuelvan a necesitar.

Bitcode: Se refiere a una "representación intermedia" de una aplicación que los desarrolladores subirán a la Tienda de aplicaciones en lugar de un binario precompilado. Esto funciona de la mano con el Corte de aplicaciones, lo que permite que el bitcode se compile bajo demanda como 32 bits o 64 bits, dependiendo del dispositivo de descarga. Esto también permitirá que cualquier mejora del compilador realizada por Apple se implemente automáticamente, en lugar de que los desarrolladores vuelvan a enviar sus aplicaciones.

introduzca la descripción de la imagen aquí

 32
Author: Sanjay Mohnani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-15 14:07:29

Dado que la pregunta exacta es "¿qué habilita el bitcode?", me gustaría dar algunos detalles técnicos finos que he averiguado hasta ahora. La mayor parte de esto es prácticamente imposible de averiguar con 100% de certeza hasta que Apple publique el código fuente para este compilador

Primero, el bitcode de Apple no parece ser lo mismo que el bytecode LLVM. Al menos, no he sido capaz de encontrar ningún parecido entre ellos. Parece tener un encabezado propietario (siempre comienza con "¡xar!") y probablemente alguna magia de referencia de tiempo de enlace que evita duplicaciones de datos. Si escribe una cadena codificada, esta cadena solo se colocará en los datos una vez, en lugar de dos veces como se esperaría si fuera un bytecode LLVM normal.

En segundo lugar, bitcode realmente no se incluye en el archivo binario como una arquitectura separada como podría esperarse. No se envía de la misma manera que dicen x86 y ARM se ponen en un binario (archivo FAT). En su lugar, utilizan una sección especial en el binario MachO específico de arquitectura llamado "_ _ LLVM " que se envía con cada arquitectura soportada (es decir, duplicada). Asumo que este es un corto que viene con su sistema de compilador y puede ser arreglado en el futuro para evitar la duplicación.

Código C (compilado con clang -fembed-bitcode hi.c -S -emit-llvm):

#include <stdio.h>

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

Salida LLVM IR:

; 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!\00", align 1
@llvm.embedded.module = appending constant [1600 x i8] c"\DE\C0\17\0B\00\00\00\00\14\00\00\00$\06\00\00\07\00\00\01BC\C0\DE!\0C\00\00\86\01\00\00\0B\82 \00\02\00\00\00\12\00\00\00\07\81#\91A\C8\04I\06\1029\92\01\84\0C%\05\08\19\1E\04\8Bb\80\10E\02B\92\0BB\84\102\148\08\18I\0A2D$H\0A\90!#\C4R\80\0C\19!r$\07\C8\08\11b\A8\A0\A8@\C6\F0\01\00\00\00Q\18\00\00\C7\00\00\00\1Bp$\F8\FF\FF\FF\FF\01\90\00\0D\08\03\82\1D\CAa\1E\E6\A1\0D\E0A\1E\CAa\1C\D2a\1E\CA\A1\0D\CC\01\1E\DA!\1C\C8\010\87p`\87y(\07\80p\87wh\03s\90\87ph\87rh\03xx\87tp\07z(\07yh\83r`\87th\07\80\1E\E4\A1\1E\CA\01\18\DC\E1\1D\DA\C0\1C\E4!\1C\DA\A1\1C\DA\00\1E\DE!\1D\DC\81\1E\CAA\1E\DA\A0\1C\D8!\1D\DA\A1\0D\DC\E1\1D\DC\A1\0D\D8\A1\1C\C2\C1\1C\00\C2\1D\DE\A1\0D\D2\C1\1D\CCa\1E\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\08wx\876p\87pp\87yh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \E6\81\1E\C2a\1C\D6\A1\0D\E0A\1E\DE\81\1E\CAa\1C\E8\E1\1D\E4\A1\0D\C4\A1\1E\CC\C1\1C\CAA\1E\DA`\1E\D2A\1F\CA\01\C0\03\80\A0\87p\90\87s(\07zh\83q\80\87z\00\C6\E1\1D\E4\A1\1C\E4\00 \E8!\1C\E4\E1\1C\CA\81\1E\DA\C0\1C\CA!\1C\E8\A1\1E\E4\A1\1C\E6\01X\83y\98\87y(\879`\835\18\07|\88\03;`\835\98\87y(\076X\83y\98\87r\90\036X\83y\98\87r\98\03\80\A8\07w\98\87p0\87rh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \EAa\1E\CA\A1\0D\E6\E1\1D\CC\81\1E\DA\C0\1C\D8\E1\1D\C2\81\1E\00s\08\07v\98\87r\006\C8\88\F0\FF\FF\FF\FF\03\C1\0E\E50\0F\F3\D0\06\F0 \0F\E50\0E\E90\0F\E5\D0\06\E6\00\0F\ED\10\0E\E4\00\98C8\B0\C3<\94\03@\B8\C3;\B4\819\C8C8\B4C9\B4\01<\BCC:\B8\03=\94\83<\B4A9\B0C:\B4\03@\0F\F2P\0F\E5\00\0C\EE\F0\0Em`\0E\F2\10\0E\EDP\0Em\00\0F\EF\90\0E\EE@\0F\E5 \0FmP\0E\EC\90\0E\ED\D0\06\EE\F0\0E\EE\D0\06\ECP\0E\E1`\0E\00\E1\0E\EF\D0\06\E9\E0\0E\E60\0Fm`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\84;\BCC\1B\B8C8\B8\C3<\B4\819\C0C\1B\B4C8\D0\03:\00\E6\10\0E\EC0\0F\E5\00\10\F3@\0F\E10\0E\EB\D0\06\F0 \0F\EF@\0F\E50\0E\F4\F0\0E\F2\D0\06\E2P\0F\E6`\0E\E5 \0Fm0\0F\E9\A0\0F\E5\00\E0\01@\D0C8\C8\C39\94\03=\B4\C18\C0C=\00\E3\F0\0E\F2P\0Er\00\10\F4\10\0E\F2p\0E\E5@\0Fm`\0E\E5\10\0E\F4P\0F\F2P\0E\F3\00\AC\C1<\CC\C3<\94\C3\1C\B0\C1\1A\8C\03>\C4\81\1D\B0\C1\1A\CC\C3<\94\03\1B\AC\C1<\CCC9\C8\01\1B\AC\C1<\CCC9\CC\01@\D4\83;\CCC8\98C9\B4\819\C0C\1B\B4C8\D0\03:\00\E6\10\0E\EC0\0F\E5\00\10\F50\0F\E5\D0\06\F3\F0\0E\E6@\0Fm`\0E\EC\F0\0E\E1@\0F\809\84\03;\CCC9\00\00I\18\00\00\02\00\00\00\13\82`B \00\00\00\89 \00\00\0D\00\00\002\22\08\09 d\85\04\13\22\A4\84\04\13\22\E3\84\A1\90\14\12L\88\8C\0B\84\84L\100s\04H*\00\C5\1C\01\18\94`\88\08\AA0F7\10@3\02\00\134|\C0\03;\F8\05;\A0\836\08\07x\80\07v(\876h\87p\18\87w\98\07|\88\038p\838\80\037\80\83\0DeP\0Em\D0\0Ez\F0\0Em\90\0Ev@\07z`\07t\D0\06\E6\80\07p\A0\07q \07x\D0\06\EE\80\07z\10\07v\A0\07s \07z`\07t\D0\06\B3\10\07r\80\07:\0FDH #EB\80\1D\8C\10\18I\00\00@\00\00\C0\10\A7\00\00 \00\00\00\00\00\00\00\868\08\10\00\02\00\00\00\00\00\00\90\05\02\00\00\08\00\00\002\1E\98\0C\19\11L\90\8C\09&G\C6\04C\9A\22(\01\0AM\D0i\10\1D]\96\97C\00\00\00y\18\00\00\1C\00\00\00\1A\03L\90F\02\134A\18\08&PIC Level\13\84a\D80\04\C2\C05\08\82\83c+\03ab\B2j\02\B1+\93\9BK{s\03\B9q\81q\81\01A\19c\0Bs;k\B9\81\81q\81q\A9\99q\99I\D9\10\14\8D\D8\D8\EC\DA\5C\DA\DE\C8\EA\D8\CA\5C\CC\D8\C2\CE\E6\A6\04C\1566\BB6\974\B227\BA)A\01\00y\18\00\002\00\00\003\08\80\1C\C4\E1\1Cf\14\01=\88C8\84\C3\8CB\80\07yx\07s\98q\0C\E6\00\0F\ED\10\0E\F4\80\0E3\0CB\1E\C2\C1\1D\CE\A1\1Cf0\05=\88C8\84\83\1B\CC\03=\C8C=\8C\03=\CCx\8Ctp\07{\08\07yH\87pp\07zp\03vx\87p \87\19\CC\11\0E\EC\90\0E\E10\0Fn0\0F\E3\F0\0E\F0P\0E3\10\C4\1D\DE!\1C\D8!\1D\C2a\1Ef0\89;\BC\83;\D0C9\B4\03<\BC\83<\84\03;\CC\F0\14v`\07{h\077h\87rh\077\80\87p\90\87p`\07v(\07v\F8\05vx\87w\80\87_\08\87q\18\87r\98\87y\98\81,\EE\F0\0E\EE\E0\0E\F5\C0\0E\EC\00q \00\00\05\00\00\00&`<\11\D2L\85\05\10\0C\804\06@\F8\D2\14\01\00\00a \00\00\0B\00\00\00\13\04A,\10\00\00\00\03\00\00\004#\00dC\19\020\18\83\01\003\11\CA@\0C\83\11\C1\00\00#\06\04\00\1CB\12\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", section "__LLVM,__bitcode"
@llvm.cmdline = appending constant [67 x i8] c"-triple\00x86_64-apple-macosx10.10.0\00-emit-llvm\00-disable-llvm-optzns\00", 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)"}

La matriz de datos que está en el IR también cambia dependiendo de la optimización y otras configuraciones de generación de código de clang. Es completamente desconocido para mí qué formato o cualquier cosa en la que esté esto.

EDITAR:

Siguiendo la pista en Twitter, decidí revisar esto y confirmarlo. Seguí esta entrada de blog y utilicé su herramienta extractor de bitcode para obtener el archivo binario de Apple del ejecutable MachO. Y después de extraer el archivo de Apple con la utilidad xar, obtuve esto (convertido a texto con llvm-dis, por supuesto)

; 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!\00", 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)"}

La única diferencia notable realmente entre el IR no bitcode y el IR bitcode es que los nombres de archivo se han reducido a solo 1, 2, etc. para cada arquitectura.

También confirmé que el bitcode incrustado en un binario se genera después de optimizaciones. Si compilas con -O3 y extraes el bitcode, será diferente que si compilas con-O0.

Y solo para obtener crédito adicional, también confirmé que Apple no envía bitcode a los dispositivos cuando descarga una aplicación iOS 9. Incluyen una serie de otras secciones extrañas que no reconozco como _ _ LINKEDIT, pero lo hacen no incluye _ _ LLVM.__bundle, y por lo tanto no parecen incluir bitcode en el binario final que se ejecuta en un dispositivo. Por extraño que parezca, Apple todavía envía binarios fat con código separado de 32 / 64bit para dispositivos iOS 8.

 18
Author: Earlz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-06 15:23:52

Bitcode (iOS, watchOS)

Bitcode es una representación intermedia de un programa compilado. Las aplicaciones que cargues a iTunes Connect que contengan bitcode se compilarán y vincularán en la App Store. La inclusión de bitcode permitirá a Apple volver a optimizar el binario de su aplicación en el futuro sin la necesidad de enviar una nueva versión de su aplicación a la tienda.


Básicamente este concepto es algo similar a Java, donde el código de bytes se ejecuta en diferentes JVM y en este caso el bitcode se coloca en la tienda iTune y en lugar de dar el código intermedio a diferentes plataformas(dispositivos) proporciona el código compilado que no necesita ninguna máquina virtual para ejecutarse.

Por lo tanto, necesitamos crear el bitcode una vez y estará disponible para dispositivos existentes o futuros. Es el dolor de cabeza de Apple para compilar y hacerlo compatible con cada plataforma que tienen.

Los desarrolladores no tienen que hacer cambios y volver a enviar la aplicación para admitir nuevos plataforma.

Tomemos el ejemplo del iPhone 5s cuando Apple introdujo el chip x64 en él. Aunque x86 las aplicaciones eran totalmente compatibles con la arquitectura x64, pero para utilizar completamente la plataforma x64 el desarrollador tiene que cambiar la arquitectura o algún código. Una vez que haya terminado, la aplicación se envía a la tienda de aplicaciones para su revisión.

Si este concepto de bitcode se lanzó antes, entonces nosotros, los desarrolladores, no tenemos que hacer ningún cambio para soportar el bit x64 arquitectura.

 11
Author: Inder Kumar Rathore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-11 09:39:38

Update

Apple ha aclarado que el corte se produce independientemente de habilitar bitcode. He observado esto en la práctica también donde una aplicación no habilitada para bitcode solo se descargará como la arquitectura apropiada para el dispositivo objetivo.

Original

Más específicamente:

Bitcode. Archive su aplicación para enviarla a la Tienda de aplicaciones en un representación intermedia, que se compila en 64 o 32 bits ejecutables para los dispositivos de destino cuando se entregan.

Rebanado. Arte incorporado en el Catálogo de activos y etiquetado para una la plataforma permite que la App Store entregue solo lo que se necesita instalación.

La forma en que he leído esto, si es compatible con bitcode, los descargadores de su aplicación solo obtendrán la arquitectura compilada necesaria para su propio dispositivo.

 4
Author: Ben Flynn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-11 18:23:39