Как мне создать xcodebuild статическую библиотеку с включенным Bitcode?

89

Xcode 7 представляет Bitcode , который является своего рода промежуточным двоичным кодом LLVM, что означает, что серверы Apple могут перекомпилировать мое приложение для разных архитектур без моего участия.

На Lookback я распространяю статический архивный фреймворк с нашей библиотекой. Кажется, что когда вы строите что-либо, кроме «Build & Archive», битовый код фактически не передается в мою библиотеку, и любой, кто подключается к моей библиотеке в своем приложении и пытается выполнить Build & Archive с включенным Bitcode, получит один из два предупреждения:

  • 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. (если библиотека построена с 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) (если библиотека построена с Xcode 7 с обычным xcodebuild)

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

Невин
источник
Привет @nevyn Я пытаюсь скомпилировать ваш SDK в приложении, использующем битовый код. Есть способ?
Stoff81
@ Stoff81 Извините, я над этим работаю. Мне нужно сначала заставить все мои зависимости работать с Bitcode, а это довольно большая работа.
Невин

Ответы:

137

Bitcode - это функция времени компиляции (а не функция времени компоновки), что означает, что каждый файл .o должен содержать дополнительный раздел с именем __bitcode при создании с использованием битового кода. Вы можете проверить, совместим ли ваш двоичный код с битовым кодом, запустив otool -l (my .o or .a file) | grep __LLVM.

Когда вы строите нормально, Xcode добавляет флаг сборки -fembed-bitcode-markerк любому вызову clang. Похоже, что это что-то вроде того, «вот где бы пошел битовый код, если бы битовый код был включен», и фактически не включает битовый код.

Когда вы выполняете «Build & Archive», этот флаг заменяется на -fembed-bitcode, что действительно создает двоичный файл с поддержкой Bitcode.

Кажется, есть два способа xcodebuildиспользовать -fembed-bitcode:

  • Используйте действие «архивировать» xcodebuild -target LookbackSDK archiveвместо xcodebuild -target LookbackSDK build. Это имеет побочный эффект помещения двоичных файлов в ваш Xcode Organizer вместо build/папки, хотя вы можете обойти это, используя -exportArchive -archivePath ./build(спасибо @JensAyton )
  • Принудительно использовать флаг, добавив другие флаги C с OTHER_CFLAGS="-fembed-bitcode". Ваш xcodebuildпризыв будет выглядеть примерно так xcodebuild OTHER_CFLAGS="-fembed-bitcode" -target LookbackSDK build.

Последнее - это то, что я выбрал, так что мне не нужно менять мою систему сборки, но он будет генерировать предупреждения для каждого файла, так как теперь оба -fembed-bitcode-markerи -fembed-bitcodeотправляются в clang. К счастью, побеждает последний, создавая библиотеку с поддержкой Bitcode!

Ресурсы

Невин
источник
9
FWIW, вы можете избавиться от предупреждения об -fembed-bitcode-markerигнорировании, добавив -Qunused-arguments.
mstorsjo
какой exportFormat использовать для xcodebuild фреймворка? Кажется, что определены только «ipa», «pkg» и «app» ( developer.apple.com/library/mac/documentation/Darwin/Reference/… ).
Фабиан Кебель
@nevyn По-прежнему не может создать мое основное приложение, в котором есть пользовательский файл фреймворка, который, в свою очередь, содержит сценарий сборки с вышеупомянутым флагом.
ravoorinandan
otool -l (мой файл .o или .a). Вы имеете в виду otool -l (мой файл .o или .a) | grep __bitcode?
Mike M
1
@MikeM на самом деле нет otool -l myfile.o | grep __LLVM, потому что будет сегмент __bitcode, даже если там будет только маркер битового кода вместо реального битового кода.
Невин
40

С Xcode 8 я не мог приступить OTHER_CFLAGS="-fembed-bitcode"к работе. Я постоянно сталкивался с чем-то вроде того, was built without full bitcode. All frameworks and dylibs for bitcode must be generated from Xcode Archive or Install buildкогда пытался создать архивную сборку приложения, содержащего мою статическую структуру.

На самом деле я искал вот что:

BITCODE_GENERATION_MODE=bitcode

На самом деле я использую сценарий выполнения внутри совокупной цели, полная строка xcodebuild выглядит так (только для справки):

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

Аарон Эш
источник
2
+1, этот BITCODE_GENERATION_MODE=bitcodeметод кажется предпочтительным, как и предлагается в этом ответе .
Уильям Деннисс
Это также устранило мою проблему, тогда как ответа по умолчанию больше нет.
Камчатка
Спасатель жизни! Спасибо!
vidalbenjoe
17

После добавления поддержки битового кода для статической библиотеки она не будет совместима с Xcode 6. Приложение не будет архивироваться.

Я хотел бы четко упомянуть настройку битового кода, поскольку ответ @nevyn меня немного смутил.

Перейдите в настройки сборки, найдите «настраиваемые флаги компилятора». Добавить -fembed-bitcode. Это создаст вашу библиотеку с битовым кодом.

Гаутам Джайн
источник
6

Выберите проект в настройках сборки -> Другие флаги C, установите Debug на -fembed-bitcode-marker и Release на -fembed-bitcode

В настройках сборки щелкните значок + вверху, чтобы добавить пользовательский параметр сборки с именем BITCODE_GENERATION_MODE, и установите для отладки маркер, выпуск для битового кода.

Отредактируйте схему как Release Затем щелкните нужную библиотеку. Файл и получите путь сборки. Получите библиотеку формы Release folder.

Осита Вималасурия
источник