Как мне скомпилировать статическую библиотеку (толстую) для armv6, armv7 и i386

Я знаю, что этот вопрос задавался несколько раз, но моя цель немного отличается от того, что я нашел при поиске в Интернете. В частности, я уже в состоянии собрать статическую библиотеку для iPhone, но окончательный толстый файл, который я могу создать, содержит только архитектуры arm и i386 (и я не уверен, что относится к arm: v6 или v7?). Я не могу скомпилировать специально для armv6 и armv7, и они объединяют обе архитектуры, используя lipo. Инструмент lipo жалуется, что в библиотеках armv6 и armv7 присутствует одна и та же архитектура (arm, а не armv6 или armv7).

Может кто-нибудь объяснить, как именно собрать для armv6 и armv7, и объединить эти библиотеки в толстый файл, используя lipo?

РЕДАКТИРОВАТЬ: мне нужно собрать не используя XCode, а компилировать непосредственно традиционную библиотеку Unix.

4 ответа

Решение

Просто используйте libtool, чтобы связать две версии arm6 и arm7 вместе - это то, что делает XCode. Однако у вас будут проблемы, если вы попытаетесь объединить эти статические библиотеки в новую супер-библиотеку. Если вам нужно сделать это, то прочитайте это.

Если вы уже делаете это, именно поэтому lipo жалуется, что ваша библиотека armv6 содержит и armv6, и armv7. В моем посте есть исправление, которое, вероятно, будет проще для вас, поскольку вы не используете XCode, но в основном вы используете lipo -extract, чтобы убедиться, что у вас есть тонкая библиотека armv6 и тонкая библиотека armv7, прежде чем идти дальше.

Вот хорошее решение, которое я нашел: Static Libs с поддержкой iOS 5 и Arm64

Отредактировано:

Решение состоит в том, чтобы создать разные архитектуры, а затем связать их, используя lipo, используя командную строку (или Rakefile).

Сначала соберите бинарный файл с помощью команды xcodebuild:

xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphoneos7.0' clean build ARCHS='armv7 armv7s' IPHONEOS_DEPLOYMENT_TARGET='5.0' TARGET_BUILD_DIR='./build-arm' BUILT_PRODUCTS_DIR='./build-arm'

Обратите внимание, что вы должны установить IPHONEOS_DEPLOYMENT_TARGET='5.0' и ARCHS='armv7 armv7s', рекомендуется установить каталоги сборки и продукта, чтобы сделать вещи более понятными, взгляните на Справочник настроек сборки для более подробной информации о том, что означает этот флаг.

Следующая сборка для arm64:

xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphoneos7.0' clean build ARCHS='arm64' IPHONEOS_DEPLOYMENT_TARGET='7.0' TARGET_BUILD_DIR='./build-arm64' BUILT_PRODUCTS_DIR='./build-arm64'

Обратите внимание на разницу в ARCHS и IPHONEOS_DEPLOYMENT_TARGET. Нам также нужно собрать симулятор, в этом случае нам нужно изменить sdk на iphonesimulator7.0 и собрать сначала два шага для i386:

xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphonesimulator7.0' clean build ARCHS='i386' IPHONEOS_DEPLOYMENT_TARGET='5.0' TARGET_BUILD_DIR='./build-i386' BUILT_PRODUCTS_DIR='./build-i386'

Теперь сложная часть! Если вы просто измените ARCHS на x86_86 в зависимости от настроек XCode, вы получите сообщение об ошибке типа "x86_64 не является допустимой аркой". Чтобы избежать этого, просто добавьте VALID_ARCHS='x86_64':

xcodebuild -project 'StaticLibDemo.xcodeproj' -configuration 'Release' -sdk 'iphonesimulator7.0' clean build ARCHS='x86_64' VALID_ARCHS='x86_64' IPHONEOS_DEPLOYMENT_TARGET='7.0' TARGET_BUILD_DIR='./build-x86_64' BUILT_PRODUCTS_DIR='./build-x86_64'

Наконец, нам просто нужно создать толстый двоичный файл со всеми 5 архитектурами:

lipo -create './build-arm/libStaticLibDemo.a' './build-arm64/libStaticLibDemo.a' './build-i386/libStaticLibDemo.a' './build-x86_64/libStaticLibDemo.a' -output 'libStaticLibDemo.a'

Автор создал рабочий пример этого, вы можете получить его: https://github.com/diogot/StaticLibDemo


Ссылка на пост: Static Libs с поддержкой iOS 5 и Arm64

Все кредиты идут к Диогу Тридапалли.

Похоже, больше нет необходимости извлекать из библиотеки жира перед тем, как снова присоединиться (как описано в ответе Джейми). Я использую последний 4.0 SDK от apple, который по умолчанию создает библиотеки fat armv6/armv7.

Ранее я указывал архитектуру для входной библиотеки следующим образом:

$DEVROOT/usr/bin/lipo -arch arm $PROJECT_DIR/buildlib/Release-iphoneos/lib.a -arch i386 $PROJECT_DIR/buildlib/Release-iphonesimulator/lib.a -create -output $PROJECT_DIR/buildlib/lib.a

Это терпит неудачу на более поздних SDK, но удаление архитектуры из (теперь толстой) библиотеки lib работает нормально:

$DEVROOT/usr/bin/lipo $PROJECT_DIR/buildlib/Release-iphoneos/lib.a -arch i386 $PROJECT_DIR/buildlib/Release-iphonesimulator/lib.a -create -output $PROJECT_DIR/buildlib/lib.a

Теперь Липо должен уметь обнаруживать архитектуры в толстых библиотеках.

Убедитесь, что ваши настройки сборки установлены на Valid Architectures: armv6 armv7 а также Architectures: Optimized (armv6 armv7), Это должно привести к бинарной оптимизации, оптимизированной как для v6, так и для v7. Если вы не уверены, что это сработало, просто установите Architectures: Standard (armv6) и сравните размеры файлов. Оптимизированный должен давать вдвое больший размер (когда я правильно помню).

Вы также всегда можете использовать lipo -info на вашем двоичном файле, чтобы увидеть все включенные архитектуры.

Запуск его в сборке дистрибутива моего приложения дает мне:

ullrich ~/Code/.../build/Distribution-iphoneos/My.app (streaming)$ lipo -info My
Architectures in the fat file: My are: armv6 armv7 
Другие вопросы по тегам