Erstellen Sie mit Xcode und SDK 4+ eine fette statische Bibliothek (Gerät + Simulator)

283

Es scheint, dass wir theoretisch eine einzige statische Bibliothek erstellen können, die sowohl Simulator als auch iPhone und iPad enthält.

Apple hat jedoch keine Dokumentation dazu, die ich finden kann, und die Standardvorlagen von Xcode sind NICHT dafür konfiguriert.

Ich suche nach einer einfachen, tragbaren und wiederverwendbaren Technik, die in Xcode ausgeführt werden kann.

Einige Geschichten:

  • Im Jahr 2008 konnten wir einzelne statische Bibliotheken erstellen, die sowohl Sim als auch Gerät enthielten. Apple hat das deaktiviert.
  • Im Laufe des Jahres 2009 haben wir Paare statischer Bibliotheken erstellt - eine für Sim, eine für Geräte. Apple hat das jetzt auch deaktiviert.

Verweise:

  1. Dies ist eine großartige Idee, ein ausgezeichneter Ansatz, der jedoch nicht funktioniert: http://www.drobnik.com/touch/2010/04/universal-static-libraries/

    • Es gibt einige Fehler in seinem Skript, die bedeuten, dass es nur auf seinem Computer funktioniert - er sollte BUILT_PRODUCTS_DIR und / oder BUILD_DIR verwenden, anstatt sie zu "schätzen".
    • Apples neuester Xcode verhindert, dass Sie das tun, was er getan hat - er funktioniert einfach nicht, da sich die (dokumentierte) Änderung der Art und Weise, wie Xcode Ziele verarbeitet, geändert hat.
  2. Ein anderer SO-Fragesteller fragte, wie es OHNE xcode und mit Antworten gemacht werden soll, die sich auf den Teil arm6 vs arm7 konzentrierten - ignorierte jedoch den Teil i386: Wie kompiliere ich eine statische Bibliothek (Fett) für armv6, armv7 und i386

    • Seit den letzten Änderungen von Apple ist der Simulator-Teil nicht mehr derselbe wie der Unterschied zwischen arm6 und arm7 - es ist ein anderes Problem, siehe oben)
Adam
quelle
Ich frage mich nur - warum willst du das? Macht es die Gerätebibliothek nicht größer und schwerer auf dem Gerät?
Cregox
3
@Cawas - das "Gewicht" der Bibliothek spielt in 95% der realen Situationen keine Rolle - für die meisten von uns sind die Bibliotheken winzig, insbesondere im Vergleich zum Anzeigen nur einer einzigen UIImageView.
Adam
1
@Cawas - In der Zwischenzeit ist der Wert hier, dass Sie es anderen Menschen VIEL einfacher machen, Ihre Bibliothek zu verwenden / wiederzuverwenden. Es wird ein einstufiger Drag & Drop-Prozess.
Adam
4
@Cawas - endlich ein überraschend wertvoller Vorteil: Es ist so einfach , versehentlich jemandem die "falsche" kompilierte Bibliothek zu senden - XCode führt keine Überprüfungen durch und kompiliert gerne die "falsche" Architektur in die benannte Datei, die Sie für die "richtige" hielten. die Architektur. Apple bricht in diesem Bereich immer wieder Xcode - jede neue Version enthält Änderungen, die bedeuten, dass "die Schaltfläche, die Sie gestern gedrückt haben, um Ihre Bibliothek korrekt zu kompilieren, sie heute falsch kompiliert". Bis Apple aufhört, uns überall durcheinander zu bringen, müssen wir ihre schlechte Benutzeroberfläche idiotensicher machen :).
Adam
1
Das wäre wirklich toll! Denn im Moment können wir uns einfach nicht auf den Simulator verlassen, wenn es etwas komplexer ist.
Cregox

Antworten:

272

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)

  1. 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)

  2. 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)

  3. 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).

  4. Der Abschnitt "Header kopieren" berücksichtigt jetzt die Build-Einstellung für den Speicherort der öffentlichen Header (mit freundlicher Genehmigung von Frederik Wallner).

  5. 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

  1. Erstellen Sie ein statisches lib-Projekt
  2. Wählen Sie das Ziel aus
  3. Setzen Sie auf der Registerkarte "Build-Einstellungen" "Nur aktive Architektur erstellen" auf "NEIN" (für alle Elemente).
  4. Wählen Sie auf der Registerkarte "Build-Phasen" die Option "Hinzufügen ... Neue Build-Phase ... Neue Run-Skript-Build-Phase".
  5. Kopieren Sie das Skript (oben) und fügen Sie es in das Feld ein

... BONUS OPTIONALE Verwendung:

  1. OPTIONAL: Wenn Ihre Bibliothek Header enthält, fügen Sie diese der Phase "Header kopieren" hinzu
  2. OPTIONAL: ... und ziehen Sie sie aus dem Abschnitt "Projekt" in den Abschnitt "Öffentlich"
  3. 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).
  4. 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:

  1. Fügen Sie den folgenden Code ganz am Ende des Skripts hinzu (mit freundlicher Genehmigung von Frederik Wallner): open "$ {CREATING_UNIVERSAL_DIR}"

  2. 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.

  3. Wenn Sie ein benutzerdefiniertes "Build Output" -Verzeichnis für XCode4 verwenden, legt XCode alle Ihre "unerwarteten" Dateien am falschen Ort ab.

    1. Erstellen Sie das Projekt
    2. Klicken Sie auf das letzte Symbol rechts oben links in Xcode4.
    3. Wählen Sie das oberste Element aus (dies ist Ihr "letzter Build". Apple sollte es automatisch auswählen, aber daran haben sie nicht gedacht).
    4. 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.)

  1. Tun Sie alles oben, überprüfen Sie, ob es funktioniert
  2. Erstellen Sie eine neue Run Script-Phase, die NACH DER ERSTEN erfolgt (kopieren Sie den folgenden Code / fügen Sie ihn ein).
  3. Erstellen Sie in Xcode ein neues Ziel vom Typ "Bundle".
  4. 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).
  5. 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}"
Adam
quelle
2
Ich habe dies jetzt für einige Projekte verwendet und Dinge in den App-Store geliefert, mit denen die Bibliotheken erstellt wurden. Alles hat 100% OK funktioniert, also bleibe ich vorerst dabei (vielleicht bis Xcode 4)
Adam
2
Kann jemand bestätigen, ob diese Methode für XCode 4.5 funktioniert? Ich versuche, eine statische Bibliothek zu kompilieren und in meinem Hauptprojekt zu verwenden. Ich kann dies auf dem Gerät ausführen, aber nicht auf dem Simulator. Dies ist der Fehler, den ich erhalte: Fehlende erforderliche Architektur i386 in der Datei /Users/alex/Documents/iphone/production/iphone/mymedia/libMyUnrar4iOS.a (2 Slices)
Alex1987
2
Haben Sie eine Idee, wie dies mit XCode 5 und ARM64 funktioniert? Wenn ich Architekturen als Standard belasse, wird die Bibliothek erwartungsgemäß mit armv7, armvs7 und i386 erstellt. Wenn ich Architekturen auf Standard einschließlich 64 Bit setze, enthält die Bibliothek nur "cputype 16777223". Ich benutze otool -h in der .a-Datei, um zu überprüfen, was sich darin befindet
Roger Binns
1
XCode5 hat das Hinzufügen einer Ausführungsphase zum Ausführen von Skripten noch schwieriger gemacht. Überprüfen Sie dies: runscriptbuildphase.com
Fabio Napodano
1
Dies scheint unter Xcode 6 ohne Änderungen einwandfrei zu funktionieren (hat bisher nur einige Projekte ausprobiert und noch keine App Store-Updates eingereicht, aber alle funktionieren bisher einwandfrei).
Adam
85

Ich habe viele Stunden damit verbracht, eine fette statische Bibliothek zu erstellen, die mit armv7, armv7s und dem Simulator funktioniert. Endlich eine Lösung gefunden .

Das Wesentliche ist, die beiden Bibliotheken (eine für das Gerät und eine für den Simulator) getrennt zu erstellen, sie umzubenennen, um sie voneinander zu unterscheiden, und sie dann in einer Bibliothek zu erstellen.

lipo -create libPhone.a libSimulator.a -output libUniversal.a

Ich habe es versucht und es funktioniert!

glühen
quelle
4
Ich schlage vor, Sie lesen die akzeptierte Antwort. Sie können feststellen, dass dies bereits 2 Jahre zuvor behandelt wurde ...
Adam
2
Ich habe es gelesen, das Skript verwendet, aber es hat bei armv7s nicht funktioniert.
g_low
2
Der Befehl lipo funktioniert nicht im Skript, aber manuell funktioniert er hervorragend! 10x
Dima
9
+1 Das war wirklich alles, was ich brauchte, kein riesiges "Make-a-Framework" -Skript.
LearnCocos2D
Ihre SolutionURL gibt "Fehler 404 - Nicht gefunden"
Alex
74

Ich habe eine XCode 4-Projektvorlage erstellt , mit der Sie ein universelles Framework genauso einfach erstellen können wie mit einer regulären Bibliothek.

Karl
quelle
Konnte es nicht mit iOS 4.3 Ziel erstellen. Erhalten Sie den folgenden Fehler: ungültiges Bereitstellungsziel für -stdlib = libc ++ (erfordert iOS 5.0 oder höher)
Alex1987
Ich wünschte, ich könnte mehr Reputationspunkte für diese Antwort vergeben ... viel einfacher als mit CMake eine statische Bibliothek zu erstellen. Vielen Dank dafür!
Ich wurde am
Es funktioniert auch mit iOS 6 für mich. Aber vielleicht liegt es daran, dass meine Bibliothek ganz einfach und ohne Abhängigkeiten und Ressourcen ist
Paulius Vindzigelskis
Es gibt ein großes Problem mit dieser Lösung: Andere, die das von dieser Lösung erstellte Framework verwenden möchten (diese Lösung schlägt vor, die fremework-Vorlage auf xcode zu installieren), MÜSSEN diese Vorlage auf IHREM xcode installieren !!!
Evya
Sie müssen die Vorlage nur für echte Frameworks installieren. Gefälschte Frameworks funktionieren in unverändertem Xcode einwandfrei.
Karl
30

Es gibt ein Befehlszeilenprogramm, xcodebuildund Sie können den Shell-Befehl in xcode ausführen. Wenn es Ihnen nichts ausmacht, ein benutzerdefiniertes Skript zu verwenden, kann Ihnen dieses Skript helfen.

#Configurations.
#This script designed for Mac OS X command-line, so does not use Xcode build variables.
#But you can use it freely if you want.

TARGET=sns
ACTION="clean build"
FILE_NAME=libsns.a

DEVICE=iphoneos3.2
SIMULATOR=iphonesimulator3.2






#Build for all platforms/configurations.

xcodebuild -configuration Debug -target ${TARGET} -sdk ${DEVICE} ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO
xcodebuild -configuration Debug -target ${TARGET} -sdk ${SIMULATOR} ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO
xcodebuild -configuration Release -target ${TARGET} -sdk ${DEVICE} ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO
xcodebuild -configuration Release -target ${TARGET} -sdk ${SIMULATOR} ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO







#Merge all platform binaries as a fat binary for each configurations.

DEBUG_DEVICE_DIR=${SYMROOT}/Debug-iphoneos
DEBUG_SIMULATOR_DIR=${SYMROOT}/Debug-iphonesimulator
DEBUG_UNIVERSAL_DIR=${SYMROOT}/Debug-universal

RELEASE_DEVICE_DIR=${SYMROOT}/Release-iphoneos
RELEASE_SIMULATOR_DIR=${SYMROOT}/Release-iphonesimulator
RELEASE_UNIVERSAL_DIR=${SYMROOT}/Release-universal

rm -rf "${DEBUG_UNIVERSAL_DIR}"
rm -rf "${RELEASE_UNIVERSAL_DIR}"
mkdir "${DEBUG_UNIVERSAL_DIR}"
mkdir "${RELEASE_UNIVERSAL_DIR}"

lipo -create -output "${DEBUG_UNIVERSAL_DIR}/${FILE_NAME}" "${DEBUG_DEVICE_DIR}/${FILE_NAME}" "${DEBUG_SIMULATOR_DIR}/${FILE_NAME}"
lipo -create -output "${RELEASE_UNIVERSAL_DIR}/${FILE_NAME}" "${RELEASE_DEVICE_DIR}/${FILE_NAME}" "${RELEASE_SIMULATOR_DIR}/${FILE_NAME}"

Sieht vielleicht ineffizient aus (ich bin nicht gut im Shell-Skript), aber leicht zu verstehen. Ich habe ein neues Ziel konfiguriert, auf dem nur dieses Skript ausgeführt wird. Das Skript ist für die Befehlszeile konzipiert, aber nicht in :) getestet

Das Kernkonzept ist xcodebuildundlipo .

Ich habe viele Konfigurationen innerhalb der Xcode-Benutzeroberfläche ausprobiert, aber nichts hat funktioniert. Da dies eine Art Stapelverarbeitung ist, ist das Befehlszeilendesign besser geeignet, sodass Apple die Stapelerstellungsfunktion schrittweise aus Xcode entfernt hat. Ich erwarte daher nicht, dass sie in Zukunft UI-basierte Batch-Build-Funktionen anbieten.

Eonil
quelle
Vielen Dank, es ist wirklich interessant, dass die zugrunde liegenden einfachen Befehle immer noch zu funktionieren scheinen - es ist nur so, dass Apple seine GUI spektakulär gebrochen hat. Es sieht so aus, als könnte ich eine vollständig benutzerdefinierte Projektvorlage erstellen, die "nicht saugt" und die Probleme behebt, die Apple gebrochen hat, indem ich alle Ziele vorab erstellt und dieses Skript mit xcode build vars verkabelt habe. Ich werde es bei meinem nächsten Projekt ausprobieren :)
Adam
1
Ich habe ein ähnliches Skript verwendet und es unter ein neues Ziel gestellt, das nur das Shell-Skript enthält. Das obige rekursive Build-Skript ist sehr clever, aber unnötig verwirrend.
Benzado
1
Ich bevorzuge Shell-Skripte für solche
slf
@benzado Ja, ich habe Komplexität absichtlich vermieden, weil ich denke, dass Shell-Skripte zum Ändern leicht zu lesen sein müssen.
Eonil
lipo: Eingabedatei kann nicht geöffnet werden: / Debug-iphoneos /
Dima
11

Ich brauchte eine fette statische Bibliothek für JsonKit, also erstellte ich ein statisches lib-Projekt in Xcode und führte dann dieses Bash-Skript im Projektverzeichnis aus. Solange Sie das xcode-Projekt mit deaktivierter Option "Nur aktive Konfiguration erstellen" konfiguriert haben, sollten Sie alle Architekturen in einer Bibliothek erhalten.

#!/bin/bash
xcodebuild -sdk iphoneos
xcodebuild -sdk iphonesimulator
lipo -create -output libJsonKit.a build/Release-iphoneos/libJsonKit.a build/Release-iphonesimulator/libJsonKit.a
Brad Robinson
quelle
7

IOS 10 Update:

Ich hatte ein Problem beim Erstellen der Fatlib mit iphoneos10.0, da der reguläre Ausdruck im Skript nur 9.x und niedriger erwartet und 0.0 für ios 10.0 zurückgibt

Um dies zu beheben, ersetzen Sie es einfach

SDK_VERSION=$(echo ${SDK_NAME} | grep -o '.\{3\}$')

mit

SDK_VERSION=$(echo ${SDK_NAME} | grep -o '[\\.0-9]\{3,4\}$')
ben
quelle
Vielen Dank. Ich habe heute Morgen eine ähnliche Änderung vorgenommen, aber \ d verwendet. Ich denke, das ist das, was wir wollen (ist es besser oder schlechter als deins?) ... grep -o '\ d \ {1,2 \} \. \ D \ {2 \} $'
Adam
Ich denke, meine ist zuverlässiger, da sie nur Zahlen berücksichtigt
ben
1
Nein, Ihre entspricht einer bestimmten Schreibweise für Ziffern. Angesichts der historischen Unterstützung (und Verwendung) von hübschen Zeichen und Texten durch Apple (z. B. in Dateinamen) würde ich erwarten, dass Ihre proprietäre Auswahl einiger Ziffern weniger zuverlässig ist.
Adam
1
Okay, vielleicht hast du recht. Zumindest hat mein Projekt auch funktioniert und wir sind sicher für die nächsten 89 iOS-Versionen
Ben
@ben Lösung funktioniert für mich, Adams Regex '[\\. 0-9] \ {3,4 \} $' gibt Fehlercode 2
Zee
4

Ich habe daraus eine Xcode 4-Vorlage gemacht , genau wie Karls statische Framework-Vorlage.

Ich fand heraus, dass das Erstellen statischer Frameworks (anstelle von einfachen statischen Bibliotheken) aufgrund eines offensichtlichen Linker-Fehlers zufällige Abstürze mit LLVM verursachte - ich denke also, statische Bibliotheken sind immer noch nützlich!

Michael Tyson
quelle
Hallo Michael, ich habe deine statische Bibliotheksvorlage ausprobiert, aber ich kann sie für den Simulator kompilieren, aber nicht für das Gerät. Hier ist der Fehler: ** BUILD FAILED ** Die folgenden Build-Befehle sind fehlgeschlagen: ProcessPCH / var / folders / qy / ncy6fkpn6677qt876ljrc54m0000gn / C / com .apple.Xcode.501 / SharedPrecompiledHeaders / MenuBarUniversal-Prefix-gwxxzpanxyudmfgryorafazokagi / MenuBarUniversal-Prefix.pch.pth MenuBarUniversal / MenuBarUniversal-Prefix.pch normal arm.v. ) Nur die ersten 200 Benachrichtigungen anzeigen Befehl / bin / sh schlug mit Exit-Code 65 fehl
Kappe
2

Gut gemacht! Ich habe etwas Ähnliches zusammen gehackt, musste es aber separat ausführen. Wenn es nur Teil des Erstellungsprozesses ist, wird es so viel einfacher.

Ein Hinweis. Mir ist aufgefallen, dass keine der Include-Dateien kopiert wird, die Sie als öffentlich markieren. Ich habe das, was ich in meinem Skript hatte, an Ihr Skript angepasst und es funktioniert ziemlich gut. Fügen Sie Folgendes am Ende Ihres Skripts ein.

if [ -d "${CURRENTCONFIG_DEVICE_DIR}/usr/local/include" ]
then
  mkdir -p "${CURRENTCONFIG_UNIVERSAL_DIR}/usr/local/include"
  cp "${CURRENTCONFIG_DEVICE_DIR}"/usr/local/include/* "${CURRENTCONFIG_UNIVERSAL_DIR}/usr/local/include"
fi
user503821
quelle
1
OK, das habe ich der obigen Antwort hinzugefügt. (hatte noch keine Gelegenheit, es zu testen, sieht aber für mich richtig aus)
Adam
1

Ich habe gerade mein eigenes Skript geschrieben für diesen Zweck geschrieben. Es wird kein Xcode verwendet. (Es basiert auf einem ähnlichen Skript im Gambit-Schema-Projekt.)

Grundsätzlich wird ./configure ausgeführt und dreimal erstellt (für i386, armv7 und armv7s) und jede der resultierenden Bibliotheken zu einer fetten Bibliothek kombiniert.

whooops
quelle