АЛЬТЕРНАТИВИ:
Проста копія / вставка останньої версії (але інструкції з установки можуть змінитися - див. Нижче!)
Бібліотека Карла потребує набагато більше зусиль для налаштування, але набагато приємнішого довгострокового рішення (це перетворює вашу бібліотеку в Framework).
Використовуйте це, а потім налаштуйте його, щоб додати підтримку збірок архівів - див. Коментар @ Frederik нижче щодо змін, які він використовує, щоб зробити цю роботу добре в режимі Archive.
ПОСЛІДНІ ЗМІНИ: 1. Додана підтримка iOS 10.x (зберігаючи підтримку для старих платформ)
Інформація про те, як використовувати цей скрипт із проектом, вбудованим в інший проект (хоча я настійно рекомендую НЕ робити цього ніколи - Apple має пару помилок стоп-шоу у Xcode, якщо ви вставляєте проекти один з одного, з Xcode Від 3x до Xcode 4.6.x)
Бонусний скрипт, який дозволяє автоматично включати в себе пакети (тобто включати файли PNG, файли PLIST тощо з вашої бібліотеки!) - див. Нижче (прокрутіть донизу)
тепер підтримує iPhone5 (використовуючи вирішення Apple для помилок в lipo). ПРИМІТКА: інструкції з установки змінилися (я, ймовірно, можу спростити це, змінивши сценарій у майбутньому, але не хочу ризикувати зараз)
Розділ "копіювати заголовки" тепер поважає налаштування збирання для загальнодоступних заголовків (люб’язно надано Фредеріком Уолнером)
Додано чітке налаштування SYMROOT (можливо, потрібно також встановити OBJROOT?), Завдяки Дугу Дікінсону
SCRIPT (це те, що вам потрібно копіювати / вставляти)
Інструкції щодо використання / встановлення див. Нижче
##########################################
#
# c.f. /programming/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4
#
# Version 2.82
#
# Latest Change:
# - MORE tweaks to get the iOS 10+ and 9- working
# - Support iOS 10+
# - Corrected typo for iOS 1-10+ (thanks @stuikomma)
#
# Purpose:
# Automatically create a Universal static library for iPhone + iPad + iPhone Simulator from within XCode
#
# Author: Adam Martin - http://twitter.com/redglassesapps
# Based on: original script from Eonil (main changes: Eonil's script WILL NOT WORK in Xcode GUI - it WILL CRASH YOUR COMPUTER)
#
set -e
set -o pipefail
#################[ Tests: helps workaround any future bugs in Xcode ]########
#
DEBUG_THIS_SCRIPT="false"
if [ $DEBUG_THIS_SCRIPT = "true" ]
then
echo "########### TESTS #############"
echo "Use the following variables when debugging this script; note that they may change on recursions"
echo "BUILD_DIR = $BUILD_DIR"
echo "BUILD_ROOT = $BUILD_ROOT"
echo "CONFIGURATION_BUILD_DIR = $CONFIGURATION_BUILD_DIR"
echo "BUILT_PRODUCTS_DIR = $BUILT_PRODUCTS_DIR"
echo "CONFIGURATION_TEMP_DIR = $CONFIGURATION_TEMP_DIR"
echo "TARGET_BUILD_DIR = $TARGET_BUILD_DIR"
fi
#####################[ part 1 ]##################
# First, work out the BASESDK version number (NB: Apple ought to report this, but they hide it)
# (incidental: searching for substrings in sh is a nightmare! Sob)
SDK_VERSION=$(echo ${SDK_NAME} | grep -o '\d\{1,2\}\.\d\{1,2\}$')
# Next, work out if we're in SIM or DEVICE
if [ ${PLATFORM_NAME} = "iphonesimulator" ]
then
OTHER_SDK_TO_BUILD=iphoneos${SDK_VERSION}
else
OTHER_SDK_TO_BUILD=iphonesimulator${SDK_VERSION}
fi
echo "XCode has selected SDK: ${PLATFORM_NAME} with version: ${SDK_VERSION} (although back-targetting: ${IPHONEOS_DEPLOYMENT_TARGET})"
echo "...therefore, OTHER_SDK_TO_BUILD = ${OTHER_SDK_TO_BUILD}"
#
#####################[ end of part 1 ]##################
#####################[ part 2 ]##################
#
# IF this is the original invocation, invoke WHATEVER other builds are required
#
# Xcode is already building ONE target...
#
# ...but this is a LIBRARY, so Apple is wrong to set it to build just one.
# ...we need to build ALL targets
# ...we MUST NOT re-build the target that is ALREADY being built: Xcode WILL CRASH YOUR COMPUTER if you try this (infinite recursion!)
#
#
# So: build ONLY the missing platforms/configurations.
if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: I am NOT the root invocation, so I'm NOT going to recurse"
else
# CRITICAL:
# Prevent infinite recursion (Xcode sucks)
export ALREADYINVOKED="true"
echo "RECURSION: I am the root ... recursing all missing build targets NOW..."
echo "RECURSION: ...about to invoke: xcodebuild -configuration \"${CONFIGURATION}\" -project \"${PROJECT_NAME}.xcodeproj\" -target \"${TARGET_NAME}\" -sdk \"${OTHER_SDK_TO_BUILD}\" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO" BUILD_DIR=\"${BUILD_DIR}\" BUILD_ROOT=\"${BUILD_ROOT}\" SYMROOT=\"${SYMROOT}\"
xcodebuild -configuration "${CONFIGURATION}" -project "${PROJECT_NAME}.xcodeproj" -target "${TARGET_NAME}" -sdk "${OTHER_SDK_TO_BUILD}" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" SYMROOT="${SYMROOT}"
ACTION="build"
#Merge all platform binaries as a fat binary for each configurations.
# Calculate where the (multiple) built files are coming from:
CURRENTCONFIG_DEVICE_DIR=${SYMROOT}/${CONFIGURATION}-iphoneos
CURRENTCONFIG_SIMULATOR_DIR=${SYMROOT}/${CONFIGURATION}-iphonesimulator
echo "Taking device build from: ${CURRENTCONFIG_DEVICE_DIR}"
echo "Taking simulator build from: ${CURRENTCONFIG_SIMULATOR_DIR}"
CREATING_UNIVERSAL_DIR=${SYMROOT}/${CONFIGURATION}-universal
echo "...I will output a universal build to: ${CREATING_UNIVERSAL_DIR}"
# ... remove the products of previous runs of this script
# NB: this directory is ONLY created by this script - it should be safe to delete!
rm -rf "${CREATING_UNIVERSAL_DIR}"
mkdir "${CREATING_UNIVERSAL_DIR}"
#
echo "lipo: for current configuration (${CONFIGURATION}) creating output file: ${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}"
xcrun -sdk iphoneos lipo -create -output "${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}" "${CURRENTCONFIG_DEVICE_DIR}/${EXECUTABLE_NAME}" "${CURRENTCONFIG_SIMULATOR_DIR}/${EXECUTABLE_NAME}"
#########
#
# Added: StackOverflow suggestion to also copy "include" files
# (untested, but should work OK)
#
echo "Fetching headers from ${PUBLIC_HEADERS_FOLDER_PATH}"
echo " (if you embed your library project in another project, you will need to add"
echo " a "User Search Headers" build setting of: (NB INCLUDE THE DOUBLE QUOTES BELOW!)"
echo ' "$(TARGET_BUILD_DIR)/usr/local/include/"'
if [ -d "${CURRENTCONFIG_DEVICE_DIR}${PUBLIC_HEADERS_FOLDER_PATH}" ]
then
mkdir -p "${CREATING_UNIVERSAL_DIR}${PUBLIC_HEADERS_FOLDER_PATH}"
# * needs to be outside the double quotes?
cp -r "${CURRENTCONFIG_DEVICE_DIR}${PUBLIC_HEADERS_FOLDER_PATH}"* "${CREATING_UNIVERSAL_DIR}${PUBLIC_HEADERS_FOLDER_PATH}"
fi
fi
ВСТАНОВИТИ ІНСТРУКЦІЇ
- Створіть статичний проект ліб
- Виберіть ціль
- На вкладці "Налаштування побудови" встановіть "Тільки для активної архітектури" на "НІ" (для всіх елементів)
- На вкладці "Фази побудови" виберіть "Додати ... Нова фаза збірки ... Нова фаза збірки сценарію"
- Скопіюйте / вставте сценарій (вище) у поле
... БОНУСОВЕ ОПЦІЙНЕ використання:
- ВІДКЛЮЧНО: якщо у вашій бібліотеці є заголовки, додайте їх до фази "Копіювати заголовки"
- ОПЦІЙНО: ... та перетягніть їх із розділу "Проект" до розділу "Загальнодоступне"
- ОПЦІОНАЛЬНО: ... і вони будуть АВТОМАТИЧНО експортуватися кожного разу, коли ви створюєте додаток, у підкаталог каталогу "універсальний налагодження" (вони будуть в usr / local / include)
- ОПЦІЯЛЬНО: ПРИМІТКА. Якщо ви також намагаєтесь перетягнути / перенести проект у інший проект Xcode, це виявить помилку в Xcode 4, де він не може створити файл .IPA, якщо у вашому проекті перетягування / випадання є загальнодоступні заголовки. Вирішення проблеми: не вставляйте проекти xcode (занадто багато помилок у коді Apple!)
Якщо ви не можете знайти вихідний файл, ось такий спосіб вирішення:
Додайте наступний код у самому кінці сценарію (люб’язно Фредерік Валнер): відкрийте "$ {CREATING_UNIVERSAL_DIR}"
Apple видаляє весь вихід після 200 рядків. Виберіть ціль, і у фазі запустити сценарій ОБОВ'ЯЗКОВО зняти: "Показати змінні середовища у журналі складання"
якщо ви використовуєте користувальницький каталог "збірка результатів" для XCode4, то XCode розміщує всі ваші "несподівані" файли в неправильному місці.
- Побудуйте проект
- Клацніть на останньому значку праворуч у верхній лівій частині Xcode4.
- Виберіть верхню позицію (це ваша "остання збірка". Apple повинна автоматично вибрати її, але вони не думали про це)
- у головному вікні прокрутіть донизу. Останній рядок повинен читати: lipo: для поточної конфігурації (налагодження) створення вихідного файлу: /Users/blah/Library/Developer/Xcode/DerivedData/AppName-ashwnbutvodmoleijzlncudsekyf/Build/Products/Debug-universal/libTargetName.a
... це місце вашої Universal Build.
Як включити у проект "файли без вихідного коду" (PNG, PLIST, XML тощо)
- Зробіть усе вище, перевірте, чи працює
- Створіть нову фазу запуску сценарію, яка настає ПЕРШИЙ (скопіюйте / вставте код нижче)
- Створіть нову ціль у Xcode типу "пакет"
- У свій ОСНОВНИЙ ПРОЕКТ у розділі "Фази збірки" додайте новий пакет як щось, від чого "залежить" (верхній розділ, натисніть кнопку плюс, прокрутіть донизу, знайдіть файл ".bundle" у своїх продуктах)
- У вашій НОВІЙ ЦІЛІ БУНДУ в розділі "Фази збірки" додайте розділ "Копіювати ресурси ресурсу" та перетягніть у нього всі файли PNG тощо.
Сценарій для автоматичного копіювання вбудованих пакетів у ту саму папку, що і статична бібліотека FAT:
echo "RunScript2:"
echo "Autocopying any bundles into the 'universal' output folder created by RunScript1"
CREATING_UNIVERSAL_DIR=${SYMROOT}/${CONFIGURATION}-universal
cp -r "${BUILT_PRODUCTS_DIR}/"*.bundle "${CREATING_UNIVERSAL_DIR}"