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

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

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

EDIT: мне нужно построить не используя Xcode, а компилировать непосредственно традиционную библиотеку unix.

Ответ 1

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

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

Ответ 2

Вот хорошее решение, которое я нашел: Статические лики с поддержкой 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


Вот ссылка на сообщение: Статические лики с поддержкой iOS 5 и Arm64

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

Ответ 3

Убедитесь, что ваши настройки сборки установлены на 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 

Ответ 4

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

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

$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, но удаление архитектуры из (теперь жирного) arm 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

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