Сборка статической библиотеки для симулятора Apple Silicon mac
Моя статическая библиотека создается с помощью xcodebuild, а затем создается толстая библиотека из симулятора и результата сборки устройства. Вот моя команда xcodebuild:
xcodebuild OTHER_CFLAGS="-fembed-bitcode" -configuration "iphoneos" -target "${LIB_NAME}Common" -sdk iphoneos
xcodebuild OTHER_CFLAGS="-fembed-bitcode" -configuration "iphonesimulator" -target "${LIB_NAME}Common" -sdk iphonesimulator
липо-команда:
lipo -create "${DEVICE_DIR}/lib${LIB_NAME}Common.a" "${SIMULATOR_DIR}/lib${LIB_NAME}Common.a" -output "${INSTALL_DIR}/include/${LIB_NAME}/lib${LIB_NAME}Common.a"
Проверив архитектуры в толстой библиотеке, я получил:
$ lipo -info MyLibCommon.a
Architectures in the fat file: MyLibCommon.a are: armv7 i386 x86_64 arm64
Однако, когда я добавляю библиотеку в проект через cocoapods и запускаю проект на новом Silicon от Apple (с чипсетом arm64) на симуляторе, я получил следующую ошибку компиляции:
building for iOS Simulator, but linking in object file built for iOS, file 'MyLibCommon.a' for architecture arm64
Исключение архитектуры arm64 для Simulator не вариант, потому что на Apple Silicon Mac установлен чипсет arm64.
Есть идеи, как создать статическую библиотеку для Apple Silicon Simulator?
1 ответ
Это невозможно.
По всей вероятности, двоичные файлы вашего симулятора - это просто i386 и x86_64. Если у вас действительно есть двоичные файлы arm64 iOS и arm64 macOS,
lipo
допустил бы ошибку:
фатальная ошибка: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: test.a.ios и test.a.macos имеют одинаковую архитектуру (arm64) и не могут быть в тот же толстый выходной файл
Это происходит независимо от того, пытаетесь ли вы использовать полнофункциональные двоичные файлы, несвязанные объектные файлы или статические библиотеки. Причина в простом недостатке формата толстого файла: у вас может быть только один фрагмент на архитектуру. Вам нужны и arm64 iOS, и симулятор Apple Silicon, но это будет 2x arm64.
У вас может возникнуть соблазн попробовать создать единый тонкий двоичный файл arm64, который работает как на iOS, так и на macOS, но это тоже невозможно. Бинарные файлы заблокированы платформой:
% otool -l test.o.ios | fgrep -B1 -A5 LC_BUILD_VERSION
Load command 1
cmd LC_BUILD_VERSION
cmdsize 24
platform 2
sdk 14.2
minos 14.2
ntools 0
% otool -l test.o.macos | fgrep -B1 -A5 LC_BUILD_VERSION
Load command 1
cmd LC_BUILD_VERSION
cmdsize 24
platform 1
sdk 11.0
minos 11.0
ntools 0
Обратите внимание на
platform 2
против
platform 1
. Ядро фактически проигнорирует эту команду загрузки, но
dyld
не буду. И у вас не может быть двух таких команд загрузки в одном двоичном файле, что тоже считается недействительным.
Вы также можете вспомнить разговоры о формате файлов "Универсальный 2" из объявления Apple или что-то, где это цитируется, но они лгали. Не существует "универсального 2", это точно такой же формат файла, как десять лет назад. Когда они говорят "универсальный 2", все, что они имеют в виду, это "добавление фрагмента arm64 в ваш двоичный файл macOS".
На мой взгляд, у вас есть три варианта:
- Вы создаете отдельные библиотеки и разделяете имена.
- Вы никогда не создаете обе архитектуры одновременно.
- Вы создаете цель симулятора для x86_64 и запускаете ее под Rosetta.
Последние два широко предлагаются в Интернете: номер 2 означает "сборка только для активной архитектуры", а номер 3 - "исключить arm64". Учитывая, что ожидается, что Rosetta в конечном итоге уйдет, третий вариант кажется нежизнеспособным в долгосрочной перспективе.