Как мне создать xcodebuild статическую библиотеку с включенным битовым кодом?
Xcode 7 представляет биткод, который является своего рода промежуточным двоичным кодом LLVM, что означает, что серверы Apple могут перекомпилировать мое приложение для разных архитектур без моего участия.
В Lookback я распространяю статическую структуру архива с нашей библиотекой. Похоже, что когда вы строите что-либо, кроме "Build and Archive", биткод фактически не выдается в мою библиотеку, и любой, кто связывается с моей библиотекой в своем приложении и пытается сделать сборку и архив с включенным битовым кодом, получит один из два предупреждения:
-
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.
(если lib построен с 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)
(если lib построен с Xcode 7 с нормальной xcodebuild)
У меня есть сборка script, которая строит универсальный двоичный файл device + simulator, поэтому я не могу использовать Build и Archive, но вместо этого я запускаю xcodebuild
из командной строки из моего script. Как я могу сделать xcodebuild
создать надлежащую библиотеку с поддержкой битового кода?
Ответы
Ответ 1
Биткод - это функция времени компиляции (а не функция времени соединения), что означает, что каждый файл .o должен содержать дополнительный раздел, называемый __bitcode, когда он построен с помощью битового кода. Вы можете подтвердить, совместим ли ваш бинард с совместимостью с битами, запустив otool -l (my .o or .a file) | grep __LLVM
.
Когда вы строите нормально, Xcode добавляет флаг сборки -fembed-bitcode-marker
к любому вызову clang. Кажется, что это какой-то "это то, где биткод будет идти, если биткод был включен", и на самом деле не разрешает биткод.
Когда вы создаете и архивируете, этот флаг заменяется на -fembed-bitcode
, который действительно создает двоичный код с поддержкой Bitcode.
Кажется, есть два способа сделать xcodebuild
использование -fembed-bitcode
:
- Используйте действие "archive", как в
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. Luckilly последний выигрывает, создавая библиотеку с поддержкой Bitcode!
Ресурсы
Ответ 2
После добавления поддержки bitcode для статического lib он не будет совместим с Xcode 6. Приложение не будет архивироваться.
Я хотел бы четко указать настройку для битового кода, так как ответ @nevyn немного смутил меня.
Перейдите к настройкам сборки, найдите "настраиваемые флаги компилятора". Добавьте -fembed-bitcode
. Это создаст ваш lib с помощью битового кода.
Ответ 3
С 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
Я использую Run Script внутри агрегатной цели, полная строка 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