iphone - development - xcode for windows 10




Costruisci grosse librerie statiche(dispositivo+simulatore) usando Xcode e SDK 4+ (6)

ALTERNATIVE:

Facile copia / incolla dell'ultima versione (ma le istruzioni di installazione potrebbero cambiare - vedi sotto!)

La libreria di Karl richiede molto più impegno per l'installazione, ma una soluzione a lungo termine molto più bella (converte la tua libreria in un Framework).

Usa questo, poi modificalo per aggiungere il supporto per i build di Archive - cf @ Comment di Frederik in basso sulle modifiche che sta usando per farlo funzionare bene con la modalità Archive.

RECENTI MODIFICHE: 1. Aggiunto supporto per iOS 10.x (mantenendo il supporto per piattaforme precedenti)

  1. Informazioni su come usare questo script con un progetto-embedded-in-another-project (anche se consiglio vivamente di NON farlo, sempre - Apple ha un paio di bug di show-stopper in Xcode se si incorporano progetti l'uno dentro l'altro, da Xcode 3.x fino a Xcode 4.6.x)

  2. Script bonus per permetterti di includere automaticamente i pacchetti (ad es. Includere file PNG, file PLIST ecc. Dalla tua libreria!) - vedi sotto (scorri in basso)

  3. ora supporta iPhone5 (usando la soluzione alternativa di Apple ai bug di lipo). NOTA: le istruzioni di installazione sono cambiate (probabilmente posso semplificarlo cambiando lo script in futuro, ma non voglio rischiare ora)

  4. La sezione "copia intestazioni" ora rispetta le impostazioni di compilazione per la posizione delle intestazioni pubbliche (per gentile concessione di Frederik Wallner)

  5. Aggiunta l'impostazione esplicita di SYMROOT (forse è necessario impostare anche OBJROOT?), Grazie a Doug Dickinson

SCRIPT (questo è ciò che devi copiare / incollare)

Per istruzioni sull'uso / installazione, vedi sotto

##########################################
#
# c.f. https://stackoverflow.com/questions/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

INSTALLARE LE ISTRUZIONI

  1. Creare un progetto di libica statica
  2. Seleziona il bersaglio
  3. Nella scheda "Impostazioni build", imposta "Crea solo architettura attiva" su "NO" (per tutti gli articoli)
  4. Nella scheda "Fasi di creazione", seleziona "Aggiungi ... Nuova fase di creazione ... Nuova fase di creazione script di esecuzione"
  5. Copia / incolla lo script (sopra) nella casella

... Utilizzo OPTIONAL BONUS:

  1. FACOLTATIVO: se hai intestazioni nella tua libreria, aggiungili alla fase "Copie intestazioni"
  2. OPTIONAL: ... e trascinali / rilasciandoli dalla sezione "Progetto" alla sezione "Pubblico"
  3. OPZIONALE: ... e verranno automaticamente esportati ogni volta che si costruisce l'app, in una sottodirectory della directory "debug-universal" (saranno in usr / local / include)
  4. OPZIONALE: NOTA: se si tenta di trascinare / rilasciare il progetto in un altro progetto Xcode, questo espone un bug in Xcode 4, in cui non è possibile creare un file .IPA se sono presenti intestazioni pubbliche nel progetto trascinato / rilasciato. La soluzione alternativa: non incorporare progetti xcode (troppi bug nel codice Apple!)

Se non riesci a trovare il file di output, ecco una soluzione:

  1. Aggiungi il seguente codice alla fine dello script (per gentile concessione di Frederik Wallner): apri "$ {CREATING_UNIVERSAL_DIR}"

  2. Apple cancella tutto l'output dopo 200 righe. Seleziona la tua destinazione e nella fase Script di esecuzione, DEVI deselezionare: "Mostra le variabili d'ambiente nel registro di costruzione"

  3. se stai usando una directory personalizzata "build output" per XCode4, XCode mette tutti i file "inaspettati" nel posto sbagliato.

    1. Costruisci il progetto
    2. Fare clic sull'ultima icona a destra, nell'area in alto a sinistra di Xcode4.
    3. Seleziona l'elemento in alto (questa è la tua "build più recente". Apple dovrebbe selezionarla automaticamente, ma non ci pensano)
    4. nella finestra principale, scorrere verso il basso. L'ultima riga dovrebbe contenere: lipo: per la configurazione corrente (Debug) che crea il file di output: /Users/blah/Library/Developer/Xcode/DerivedData/AppName-ashwnbutvodmoleijzlncudsekyf/Build/Products/Debug-universal/libTargetName.a

    ... questa è la posizione della tua Universal Build.

Come includere i file "non sourcecode" nel progetto (PNG, PLIST, XML, ecc.)

  1. Fai tutto sopra, controlla che funzioni
  2. Crea una nuova fase Run Script che viene DOPO IL PRIMO (copia / incolla il codice qui sotto)
  3. Crea un nuovo target in Xcode, di tipo "bundle"
  4. Nel tuo PROGETTO PRINCIPALE, in "Crea Fasi", aggiungi il nuovo pacchetto come qualcosa che "dipende da" (sezione superiore, premi il pulsante più, scorri verso il basso, trova il file ".bundle" nei tuoi Prodotti)
  5. Nel tuo NUOVO TARGET BUNDLE, in "Build Phases", aggiungi una sezione "Copy Bundle Resources" e trascina / rilascia tutti i file PNG ecc.

Script per copiare automaticamente i pacchetti compilati nella stessa cartella della libreria statica 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}"

Sembra che possiamo - teoricamente - costruire una singola libreria statica che includa sia il simulatore che l'iPhone e l'iPad.

Tuttavia, Apple non ha documentazione su questo che posso trovare, e i modelli predefiniti di Xcode NON sono configurati per farlo.

Sto cercando una tecnica semplice, portatile e riutilizzabile che possa essere eseguita all'interno di Xcode.

Qualche storia:

  • Nel 2008, eravamo abituati a creare singole librerie statiche che includevano sia la sim che il dispositivo. Apple lo ha disabilitato.
  • Nel corso del 2009, abbiamo creato una coppia di librerie statiche, una per la simulazione e una per la periferica. Apple ha ora disabilitato anche questo.

Riferimenti:

  1. Questa è una grande idea, è un approccio eccellente, ma non funziona: http://www.drobnik.com/touch/2010/04/universal-static-libraries/

    • Ci sono alcuni bug nel suo script che significa che funziona solo sulla sua macchina - dovrebbe usare BUILT_PRODUCTS_DIR e / o BUILD_DIR invece di "congestionarli")
    • L'ultimo Xcode di Apple ti impedisce di fare ciò che ha fatto, semplicemente non funzionerà, a causa del cambiamento (documentato) nel modo in cui i processi Xcode sono mirati)
  2. Un altro interrogatore SO ha chiesto come farlo SENZA xcode, e con le risposte che si sono concentrate sulla parte arm6 vs arm7, ma ha ignorato la parte i386: Come faccio a compilare una libreria statica (fat) per armv6, armv7 e i386

    • Dalle ultime modifiche di Apple, la parte Simulator non è più la stessa della differenza arm6 / arm7 - è un problema diverso, vedi sopra)

Avevo bisogno di una fat static lib per JsonKit, quindi ho creato un progetto di lib static in Xcode e poi ho eseguito questo script bash nella directory del progetto. Finché hai configurato il progetto xcode con "Crea solo configurazione attiva" disattivato, dovresti ottenere tutte le architetture in una sola lib.

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

Ho creato un modello di progetto XCode 4 che ti consente di creare un framework universale con la stessa facilità con cui esegui una normale libreria.


Ho passato molte ore a cercare di costruire una grossa libreria statica che funzioni su armv7, armv7s e il simulatore. Finalmente trovato una soluzione .

L'essenza è di costruire separatamente le due librerie (una per il dispositivo e poi una per il simulatore), rinominarle per distinguerle, e quindi renderle in una libreria.

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

Ho provato e funziona!


L'ho trasformato in un modello Xcode 4 , nella stessa vena del modello di framework statico di Karl.

Ho scoperto che la creazione di framework statici (anziché semplici librerie statiche) causava arresti anomali casuali con LLVM, a causa di un apparente bug del linker, quindi suppongo che le librerie statiche siano ancora utili!


Ottimo lavoro! Ho hackerato qualcosa di simile, ma ho dovuto eseguirlo separatamente. Averlo solo parte del processo di creazione lo rende molto più semplice.

Un elemento di nota. Ho notato che non copia su nessuno dei file include che contrassegni come pubblici. Ho adattato ciò che avevo nella mia sceneggiatura alla tua e funziona abbastanza bene. Incolla quanto segue alla fine del tuo script.

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




xcode