¿Cómo xcodebuild una biblioteca estática con Bitcode habilitado?

88

Xcode 7 presenta Bitcode , que es una especie de binario intermedio LLVM que significa que los servidores de Apple pueden recompilar mi aplicación para diferentes arquitecturas sin mi participación.

En Lookback, distribuyo un marco de archivo estático con nuestra biblioteca. Parece que cuando compila con cualquier cosa que no sea "Build & Archive", el bitcode en realidad no se emite en mi biblioteca, y cualquiera que se vincule con mi biblioteca en su aplicación e intente hacer una Build & Archive con Bitcode habilitado obtendrá uno de dos advertencias:

  • ld: 'Lookback(Lookback.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. (si lib está construido con Xcode 6)
  • ld: warning: full bitcode bundle could not be generated because 'Lookback(Lookback.o)' was built only with bitcode marker. The library must be generated from Xcode archive build with bitcode enabled (Xcode setting ENABLE_BITCODE) (si lib está construido con Xcode 7 con un xcodebuild normal)

Tengo un script de compilación que crea un binario universal de dispositivo + simulador, por lo que no puedo usar Build & Archive, sino que lo ejecuto xcodebuilddesde la línea de comandos desde mi script. ¿Cómo puedo xcodebuildgenerar una biblioteca adecuada habilitada para códigos de bits?

nevyn
fuente
Hola @nevyn Estoy intentando que tu SDK se compile en una aplicación que usa bitcode. ¿Hay alguna manera?
Stoff81
@ Stoff81 Lo siento, estoy trabajando en ello. Primero necesito que todas mis dependencias funcionen con Bitcode, y es bastante trabajo.
nevyn

Respuestas:

137

Bitcode es una función de tiempo de compilación (no una función de tiempo de enlace) lo que significa que cada archivo .o debe contener una sección adicional llamada __bitcode cuando se construye con bitcode. Puede confirmar si su binario es compatible con el código de bits ejecutando otool -l (my .o or .a file) | grep __LLVM.

Cuando construyes normalmente, Xcode agrega la bandera de construcción -fembed-bitcode-markera cualquier invocación de clang. Esto parece ser una especie de 'aquí es donde iría el código de bits, si el código de bits estuviera habilitado', y en realidad no habilita el código de bits.

Cuando "Construye y Archiva", esta bandera es reemplazada por -fembed-bitcode, que realmente construye un binario habilitado para Bitcode.

Parece que hay dos formas de xcodebuildutilizarlo -fembed-bitcode:

  • Utilice la acción 'archivar', como en en xcodebuild -target LookbackSDK archivelugar de xcodebuild -target LookbackSDK build. Esto tiene el efecto secundario de poner binarios en su Xcode Organizer en lugar de la build/carpeta, aunque puede solucionarlo usando -exportArchive -archivePath ./build(gracias @JensAyton )
  • Forzar el uso de la bandera agregando Otras banderas C con OTHER_CFLAGS="-fembed-bitcode". Su xcodebuildinvocación se vería así xcodebuild OTHER_CFLAGS="-fembed-bitcode" -target LookbackSDK build.

Este último es el que elegí para no tener que cambiar mi sistema de compilación, pero generará advertencias para cada archivo, ya que ahora ambos -fembed-bitcode-markery -fembed-bitcodese envían a clang. Por suerte, este último gana, ¡generando una biblioteca habilitada para Bitcode!

Recursos

nevyn
fuente
9
FWIW, puede deshacerse de la advertencia sobre -fembed-bitcode-markerser ignorado agregando -Qunused-argumentstambién.
mstorsjo
¿Qué exportFormat utiliza para un xcodebuild de un marco? Parece que sólo "ipa", "pkg" y ​​"app" parecen estar definidos ( developer.apple.com/library/mac/documentation/Darwin/Reference/… ).
Fabian Köbel
@nevyn Todavía no pude construir mi aplicación principal que tiene el archivo de marco personalizado que a su vez contiene un script de construcción con la bandera mencionada anteriormente.
ravoorinandan
otool -l (mi archivo .o o .a). ¿Te refieres a otool -l (mi archivo .o o .a) | grep __bitcode?
Mike M
1
@MikeM no en realidad otool -l myfile.o | grep __LLVM, porque habrá un segmento de __bitcode incluso si solo hay un marcador de bitcode en lugar de bitcode real.
nevyn
40

Con Xcode 8, no pude ponerme OTHER_CFLAGS="-fembed-bitcode"a trabajar. Seguí encontrándome con algo parecido a was built without full bitcode. All frameworks and dylibs for bitcode must be generated from Xcode Archive or Install buildcuando intenté crear una compilación de archivo de una aplicación que contiene mi marco estático.

Lo que realmente estaba buscando era esto:

BITCODE_GENERATION_MODE=bitcode

De hecho, estoy usando un Run Script dentro de un objetivo agregado, la línea completa de xcodebuild se ve así (solo como referencia):

xcodebuild BITCODE_GENERATION_MODE=bitcode OTHER_CFLAGS="-fembed-bitcode" -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

Aaron Ash
fuente
2
+1, el BITCODE_GENERATION_MODE=bitcodemétodo parece ser el preferido, como también se sugiere en esta respuesta .
William Denniss
Esto también solucionó mi problema, mientras que la respuesta predeterminada ya no lo hace.
Kamchatka
Salvavidas! ¡Gracias!
vidalbenjoe
17

Una vez que agregue soporte de código de bits para la biblioteca estática, no será compatible con Xcode 6. La aplicación no se archivará.

Me gustaría mencionar claramente la configuración del código de bits, ya que la respuesta de @ nevyn me confundió un poco.

Vaya a Configuración de compilación, busque "indicadores de compilador personalizados". Agregar -fembed-bitcode. Esto construirá su lib con bitcode.

Gautam Jain
fuente
6

Seleccione el proyecto en la configuración de compilación -> Otros indicadores C, establezca Depurar en -fembed-bitcode-marker y Release en -fembed-bitcode

En Configuración de compilación, haga clic en el signo + en la parte superior para agregar una configuración de compilación definida por el usuario con el nombre BITCODE_GENERATION_MODE, y establezca Depurar en marcador, Liberar en código de bits

Edite el esquema como versión Luego haga clic en la biblioteca deseada. Un archivo y obtenga la ruta de construcción. Obtenga la carpeta de liberación del formulario de biblioteca.

Oshitha Wimalasuriya
fuente