ALTERNATIVEN:
Einfaches Kopieren / Einfügen der neuesten Version (die Installationsanweisungen können sich jedoch ändern - siehe unten!)
Die Einrichtung von Karls Bibliothek erfordert viel mehr Aufwand, aber eine viel schönere langfristige Lösung (sie konvertiert Ihre Bibliothek in ein Framework).
Verwenden Sie diese Option und optimieren Sie sie, um Unterstützung für Archiv-Builds hinzuzufügen. Siehe @ Frederiks Kommentar unten zu den Änderungen, die er verwendet, damit dies im Archivierungsmodus gut funktioniert.
JÜNGSTE ÄNDERUNGEN: 1. Unterstützung für iOS 10.x hinzugefügt (während die Unterstützung für ältere Plattformen beibehalten wird)
Informationen zur Verwendung dieses Skripts mit einem Projekt, das in ein anderes Projekt eingebettet ist (obwohl ich dringend empfehle, dies niemals zu tun - Apple hat ein paar Show-Stopper-Fehler in Xcode, wenn Sie Projekte von Xcode ineinander einbetten 3.x bis Xcode 4.6.x)
Bonusskript, mit dem Sie Bundles automatisch einschließen können (dh PNG-Dateien, PLIST-Dateien usw. aus Ihrer Bibliothek einschließen!) - siehe unten (nach unten scrollen)
unterstützt jetzt das iPhone5 (mit Apples Problemumgehung für die Fehler in Lipo). HINWEIS: Die Installationsanweisungen haben sich geändert (ich kann dies wahrscheinlich vereinfachen, indem ich das Skript in Zukunft ändere, möchte es aber jetzt nicht riskieren).
Der Abschnitt "Header kopieren" berücksichtigt jetzt die Build-Einstellung für den Speicherort der öffentlichen Header (mit freundlicher Genehmigung von Frederik Wallner).
Dank Doug Dickinson wurde die explizite Einstellung von SYMROOT hinzugefügt (muss möglicherweise auch OBJROOT eingestellt werden?)
SCRIPT (das müssen Sie kopieren / einfügen)
Anweisungen zur Verwendung / Installation finden Sie unten
##########################################
#
# 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
INSTALLATIONSANWEISUNGEN
- Erstellen Sie ein statisches lib-Projekt
- Wählen Sie das Ziel aus
- Setzen Sie auf der Registerkarte "Build-Einstellungen" "Nur aktive Architektur erstellen" auf "NEIN" (für alle Elemente).
- Wählen Sie auf der Registerkarte "Build-Phasen" die Option "Hinzufügen ... Neue Build-Phase ... Neue Run-Skript-Build-Phase".
- Kopieren Sie das Skript (oben) und fügen Sie es in das Feld ein
... BONUS OPTIONALE Verwendung:
- OPTIONAL: Wenn Ihre Bibliothek Header enthält, fügen Sie diese der Phase "Header kopieren" hinzu
- OPTIONAL: ... und ziehen Sie sie aus dem Abschnitt "Projekt" in den Abschnitt "Öffentlich"
- OPTIONAL: ... und sie werden jedes Mal, wenn Sie die App erstellen, AUTOMATISCH in ein Unterverzeichnis des Verzeichnisses "debug-universal" exportiert (sie befinden sich in usr / local / include).
- OPTIONAL: HINWEIS: Wenn Sie auch versuchen, Ihr Projekt in ein anderes Xcode-Projekt zu ziehen, wird ein Fehler in Xcode 4 angezeigt, bei dem keine IPA-Datei erstellt werden kann, wenn Ihr Drag / Drop-Projekt öffentliche Header enthält. Die Problemumgehung: Betten Sie keine Xcode-Projekte ein (zu viele Fehler in Apples Code!)
Wenn Sie die Ausgabedatei nicht finden können, finden Sie hier eine Problemumgehung:
Fügen Sie den folgenden Code ganz am Ende des Skripts hinzu (mit freundlicher Genehmigung von Frederik Wallner): open "$ {CREATING_UNIVERSAL_DIR}"
Apple löscht alle Ausgaben nach 200 Zeilen. Wählen Sie Ihr Ziel aus und in der Phase "Skript ausführen" MÜSSEN Sie das Kontrollkästchen "Umgebungsvariablen im Erstellungsprotokoll anzeigen" deaktivieren.
Wenn Sie ein benutzerdefiniertes "Build Output" -Verzeichnis für XCode4 verwenden, legt XCode alle Ihre "unerwarteten" Dateien am falschen Ort ab.
- Erstellen Sie das Projekt
- Klicken Sie auf das letzte Symbol rechts oben links in Xcode4.
- Wählen Sie das oberste Element aus (dies ist Ihr "letzter Build". Apple sollte es automatisch auswählen, aber daran haben sie nicht gedacht).
- Scrollen Sie im Hauptfenster nach unten. Die allerletzte Zeile sollte lauten: lipo: Für die aktuelle Konfiguration (Debug) wird eine Ausgabedatei erstellt: /Users/blah/Library/Developer/Xcode/DerivedData/AppName-ashwnbutvodmoleijzlncudsekyf/Build/Products/Debug-universal/libTargetName.a
... das ist der Ort Ihres Universal Builds.
So fügen Sie "Nicht-Quellcode" -Dateien in Ihr Projekt ein (PNG, PLIST, XML usw.)
- Tun Sie alles oben, überprüfen Sie, ob es funktioniert
- Erstellen Sie eine neue Run Script-Phase, die NACH DER ERSTEN erfolgt (kopieren Sie den folgenden Code / fügen Sie ihn ein).
- Erstellen Sie in Xcode ein neues Ziel vom Typ "Bundle".
- Fügen Sie in Ihrem MAIN PROJECT unter "Build Phases" das neue Bundle als etwas hinzu, von dem es "abhängt" (oberer Abschnitt, drücken Sie die Plus-Taste, scrollen Sie nach unten, suchen Sie die ".bundle" -Datei in Ihren Produkten).
- Fügen Sie in Ihrem NEUEN BUNDLE-ZIEL unter "Phasen erstellen" einen Abschnitt "Bundle-Ressourcen kopieren" hinzu und ziehen Sie alle PNG-Dateien usw. per Drag & Drop hinein
Skript zum automatischen Kopieren der erstellten Bundles in denselben Ordner wie Ihre statische FAT-Bibliothek:
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}"