Zbuduj grubą bibliotekę statyczną (urządzenie + symulator) za pomocą Xcode i SDK 4+

283

Wydaje się, że możemy - teoretycznie - zbudować pojedynczą bibliotekę statyczną, która zawiera zarówno symulator, jak i iPhone'a i iPada.

Jednak Apple nie ma na ten temat żadnej dokumentacji, a domyślne szablony Xcode NIE są skonfigurowane do tego.

Szukam prostej, przenośnej i nadającej się do ponownego wykorzystania techniki, którą można wykonać w Xcode.

Trochę historii:

  • W 2008 r. Mogliśmy tworzyć pojedyncze biblioteki statyczne zawierające zarówno kartę SIM, jak i urządzenie. Apple wyłączył to.
  • Przez cały 2009 rok stworzyliśmy pary bibliotek statycznych - jedną dla SIM, drugą dla urządzenia. Apple też to teraz wyłączyło.

Bibliografia:

  1. To świetny pomysł, jest to doskonałe podejście, ale nie działa: http://www.drobnik.com/touch/2010/04/universal-static-libraries/

    • W jego skrypcie są pewne błędy, co oznacza, że ​​działa on tylko na jego komputerze - powinien używać BUILT_PRODUCTS_DIR i / lub BUILD_DIR zamiast ich „zgadywania”)
    • Najnowszy Xcode firmy Apple uniemożliwia robienie tego, co zrobił - po prostu nie będzie działać, ze względu na (Udokumentowaną) zmianę sposobu, w jaki Xcode przetwarza obiekty docelowe)
  2. Inny SO pytający zapytał, jak to zrobić BEZ xcode i odpowiedzi, które skupiły się na części arm6 vs arm7 - ale zignorował część i386: jak skompilować bibliotekę statyczną (tłuszcz) dla armv6, armv7 i i386

    • Od najnowszych zmian Apple'a część symulatora nie jest już taka sama jak różnica arm6 / arm7 - to inny problem, patrz wyżej)
Adam
źródło
Zastanawiam się - dlaczego tego chcesz? Czy to nie sprawia, że ​​biblioteka urządzeń jest większa i cięższa na urządzeniu?
cregox 14.01.11
3
@Cawas - „waga” biblioteki jest nieistotna w 95% rzeczywistych sytuacji - dla większości z nas biblioteki są małe, zwłaszcza w porównaniu do np. Wyświetlania tylko jednego UIImageView.
Adam
1
@Cawas - tymczasem wartość polega na tym, że UŁATWIAsz innym osobom korzystanie z biblioteki / ponowne jej używanie. Staje się jednoetapowym procesem przeciągania / upuszczania.
Adam,
4
@Cawas - wreszcie zaskakująco cenna korzyść: tak łatwo przypadkowo wysłać komuś „niewłaściwą” skompilowaną bibliotekę - XCode wykonuje zerowe kontrole i chętnie skompiluje „niewłaściwą” architekturę do pliku o nazwie, który Twoim zdaniem był „poprawny” architektura. Apple wciąż łamie Xcode w tej dziedzinie - każda nowa wersja ma zmiany, które oznaczają, że „przycisk, który nacisnąłeś wczoraj, aby poprawnie skompilować bibliotekę, dzisiaj skompiluje ją niepoprawnie”. Dopóki Apple nie przestanie nas wkurzać, musimy udoskonalić ich zły interfejs użytkownika :).
Adam
1
To byłoby naprawdę świetne! Ponieważ w tej chwili nie możemy polegać na symulatorze w przypadku czegoś bardziej złożonego.
cregox,

Odpowiedzi:

272

ALTERNATYWY:

Łatwe kopiowanie / wklejanie najnowszej wersji (ale instrukcje instalacji mogą ulec zmianie - patrz poniżej!)

Biblioteka Karla wymaga znacznie więcej wysiłku, aby skonfigurować, ale o wiele ładniejsze długoterminowe rozwiązanie (konwertuje bibliotekę do frameworka).

Skorzystaj z tego, a następnie popraw go, aby dodać obsługę kompilacji archiwów - patrz komentarz @ Frederika na temat zmian, których używa, aby ładnie działał w trybie archiwizacji.


OSTATNIE ZMIANY: 1. Dodano obsługę systemu iOS 10.x (przy zachowaniu obsługi starszych platform)

  1. Informacje o tym, jak używać tego skryptu z projektem osadzonym w innym projekcie (chociaż zdecydowanie nie polecam tego robić, nigdy - Apple ma kilka błędów show-stopper w Xcode, jeśli osadzasz projekty między sobą, z Xcode 3.x do Xcode 4.6.x)

  2. Dodatkowy skrypt pozwalający na automatyczne dołączanie pakietów (tj. Dołączanie plików PNG, PLIST itp. Z biblioteki!) - patrz poniżej (przewiń w dół)

  3. teraz obsługuje iPhone5 (używając obejścia Apple do błędów w lipo). UWAGA: instrukcje instalacji uległy zmianie (prawdopodobnie mogę to uprościć, zmieniając skrypt w przyszłości, ale nie chcę teraz ryzykować)

  4. Sekcja „kopiuj nagłówki” uwzględnia teraz ustawienie kompilacji dla lokalizacji nagłówków publicznych (dzięki uprzejmości Frederika Wallnera)

  5. Dodano wyraźne ustawienie SYMROOT (może trzeba też ustawić OBJROOT?), Dzięki Dougowi Dickinsonowi


SCRIPT (to jest to, co musisz skopiować / wkleić)

Aby uzyskać instrukcje użytkowania / instalacji, patrz poniżej

##########################################
#
# 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

ZAINSTALUJ INSTRUKCJE

  1. Utwórz statyczny projekt lib
  2. Wybierz cel
  3. Na karcie „Ustawienia kompilacji” ustaw „Kompiluj tylko architekturę aktywną” na „NIE” (dla wszystkich elementów)
  4. Na karcie „Fazy kompilacji” wybierz opcję „Dodaj ... Nowa faza kompilacji ... Nowa faza kompilacji skryptu uruchamiania”
  5. Skopiuj / wklej skrypt (powyżej) w polu

... wykorzystanie BONUS OPCJONALNE:

  1. OPCJONALNIE: jeśli masz nagłówki w bibliotece, dodaj je do fazy „Kopiuj nagłówki”
  2. OPCJONALNIE: ... i przeciągnij / upuść je z sekcji „Projekt” do sekcji „Publiczne”
  3. OPCJONALNIE: ... i będą one automatycznie eksportowane za każdym razem, gdy budujesz aplikację, do podkatalogu katalogu „debug-universal” (będą one w usr / local / include)
  4. OPCJONALNIE: UWAGA: jeśli spróbujesz również przeciągnąć / upuścić projekt do innego projektu Xcode, ujawnia to błąd w Xcode 4, w którym nie można utworzyć pliku .IPA, jeśli masz publiczne nagłówki w swoim projekcie przeciągania / upuszczania. Obejście: nie osadzaj projektów xcode (zbyt wiele błędów w kodzie Apple!)

Jeśli nie możesz znaleźć pliku wyjściowego, oto obejście:

  1. Dodaj następujący kod na samym końcu skryptu (dzięki uprzejmości Frederika Wallnera): otwórz „$ {CREATING_UNIVERSAL_DIR}”

  2. Apple usuwa wszystkie dane wyjściowe po 200 wierszach. Wybierz swój cel, aw fazie uruchamiania skryptu MUSISZ odznaczyć: „Pokaż zmienne środowiskowe w dzienniku kompilacji”

  3. jeśli używasz niestandardowego katalogu „build output” dla XCode4, wtedy XCode umieszcza wszystkie „nieoczekiwane” pliki w niewłaściwym miejscu.

    1. Zbuduj projekt
    2. Kliknij ostatnią ikonę po prawej stronie w lewym górnym obszarze Xcode4.
    3. Wybierz najwyższy element (jest to „najnowsza wersja”. Apple powinien wybrać go automatycznie, ale nie pomyśleli o tym)
    4. w głównym oknie przewiń w dół. Ostatni wiersz powinien brzmieć: lipo: dla bieżącej konfiguracji (debugowania) tworzenie pliku wyjściowego: /Users/blah/Library/Developer/Xcode/DerivedData/AppName-ashwnbutvodmoleijzlncudsekyf/Build/Products/Debug-universal/libTargetName.a

    ... to jest lokalizacja twojej Uniwersalnej Kompilacji.


Jak dołączyć do projektu pliki „bez kodu źródłowego” (PNG, PLIST, XML itp.)

  1. Zrób wszystko powyżej, sprawdź, czy działa
  2. Utwórz nową fazę Run Script, która pojawi się PO PIERWSZEJ (skopiuj / wklej poniższy kod)
  3. Utwórz nowy cel w Xcode, typu „pakiet”
  4. W swoim PROJEKCIE GŁÓWNYM w „Fazach kompilacji” dodaj nowy pakiet jako coś, od czego „zależy” (górna sekcja, naciśnij przycisk plus, przewiń w dół, znajdź plik „.bundle” w swoich produktach)
  5. W swoim NOWYM CELU GRANICZNYM w „Fazach kompilacji” dodaj sekcję „Kopiuj zasoby pakietu” i przeciągnij / upuść do niego wszystkie pliki PNG itp.

Skrypt do automatycznego kopiowania wbudowanych pakietów do tego samego folderu, co biblioteka statyczna 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}"
Adam
źródło
2
Użyłem tego w kilku projektach i wysłałem rzeczy do sklepu z aplikacjami, który wykorzystał to do zbudowania bibliotek. Wszystko działało w 100% OK, więc trzymam się tego na razie (może do Xcode 4)
Adam
2
Czy ktoś może potwierdzić, czy ta metoda działa dla XCode 4.5? Próbuję skompilować bibliotekę statyczną i użyć jej w moim głównym projekcie. Jestem w stanie uruchomić to na urządzeniu, ale nie na symulatorze. To jest błąd, który otrzymuję: brak wymaganej architektury i386 w pliku /Users/alex/Documents/iphone/production/iphone/mymedia/libMyUnrar4iOS.a (2 plastry)
Alex1987,
2
Masz pomysł, jak to zrobić w XCode 5 i ARM64? Jeśli pozostawię architekturę jako standard, spowoduje to, że biblioteka z armv7, armvs7 i i386 będzie zgodna z oczekiwaniami. Jeśli ustawię architektury na standardowe, w tym 64-bitowe, biblioteka zawiera tylko „cputype 16777223”. Używam otool -h na pliku .a, aby sprawdzić, co jest w środku
Roger Binns,
1
XCode5 sprawił, że dodanie fazy kompilacji skryptu uruchamiania jest jeszcze trudniejsze. sprawdź to: runscriptbuildphase.com
Fabio Napodano
1
Wydaje się, że działa to dobrze na Xcode 6 bez zmian (dotychczas wypróbowałem tylko kilka projektów i nie przesłałem jeszcze żadnych aktualizacji App Store, ale wszystkie działają do tej pory dobrze).
Adam
85

Spędziłem wiele godzin próbując zbudować grubą bibliotekę statyczną, która będzie działać na Armv7, Armv7s i symulatorze. Wreszcie znalazłem rozwiązanie .

Istotą jest oddzielne zbudowanie dwóch bibliotek (jednej dla urządzenia, a następnie jednej dla symulatora), zmień ich nazwy, aby się od siebie odróżnić, a następnie utwórz je lipo w jednej bibliotece.

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

Próbowałem i działa!

poświata
źródło
4
Sugeruję przeczytanie zaakceptowanej odpowiedzi. Może się okazać, że zostało to uwzględnione już 2 lata wcześniej ...
Adam
2
Przeczytałem go, użyłem skryptu, ale nie działało to dla armv7s.
g_low
2
polecenie lipo nie działa na skrypcie, ale ręcznie działa świetnie! 10x
Dima,
9
+1 To było naprawdę wszystko, czego potrzebowałem, a nie ogromny skrypt „make-a-framework”.
LearnCocos2D,
Twoje rozwiązanieURL zwraca „Błąd 404 - Nie znaleziono”
Alex
74

Stworzyłem szablon projektu XCode 4, który pozwala tworzyć uniwersalne ramy tak łatwo, jak tworzenie zwykłej biblioteki.

Karl
źródło
Nie można zbudować go z celem iOS 4.3. Uzyskaj następujący błąd: nieprawidłowy cel wdrażania dla -stdlib = libc ++ (wymaga systemu iOS 5.0 lub nowszego)
Alex1987,
Chciałbym dać więcej punktów reputacji za tę odpowiedź ... o wiele łatwiej niż przy użyciu CMake do stworzenia biblioteki statycznej. Dziękuję bardzo za zrobienie tego!
iwasrobbed
Działa również z iOS 6 dla mnie. Ale może dlatego, że moja lib jest dość prosta i bez żadnych zależności i zasobów
Paulius Vindzigelskis
Istnieje duży problem z tym rozwiązaniem: inni, którzy chcą korzystać z frameworka utworzonego przez to rozwiązanie (to rozwiązanie sugeruje zainstalowanie szablonu fremework na xcode) MUSZĄ zainstalować ten szablon na ICH xcode !!!
evya
Musisz tylko zainstalować szablon dla prawdziwych frameworków. Fałszywe frameworki będą działać poprawnie w niezmodyfikowanym Xcode.
Karl
30

Istnieje narzędzie wiersza polecenia xcodebuildi możesz uruchamiać polecenie powłoki w xcode. Jeśli więc nie masz nic przeciwko użyciu skryptu niestandardowego, ten skrypt może ci pomóc.

#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}"

Może wygląda nieefektywnie (nie jestem dobry w skryptach powłoki), ale łatwo go zrozumieć. Skonfigurowałem nowy cel, w którym działa tylko ten skrypt. Skrypt jest przeznaczony dla wiersza poleceń, ale nie został przetestowany w :)

Podstawową koncepcją jest xcodebuildi lipo.

Próbowałem wielu konfiguracji w interfejsie Xcode, ale nic nie działało. Ponieważ jest to rodzaj przetwarzania wsadowego, więc bardziej odpowiedni jest projekt wiersza polecenia, dlatego Apple stopniowo usuwał funkcję kompilacji wsadowej z Xcode. Więc nie oczekuję, że w przyszłości będą oferować funkcję kompilacji wsadowej opartą na interfejsie użytkownika.

Eonil
źródło
Dzięki, to naprawdę interesujące, że podstawowe proste polecenia wydają się nadal działać - po prostu Apple spektakularnie złamało GUI. Wygląda na to, że mógłbym stworzyć w pełni niestandardowy szablon projektu, który „nie będzie do bani” i naprawi to, co zepsuł się Apple, przygotowując wstępnie wszystkie cele i łącząc ten skrypt za pomocą różnych wersji xcode. Wypróbuję to w moim następnym projekcie :)
Adam
1
Użyłem skryptu podobnego do tego i umieściłem go pod nowym celem zawierającym tylko skrypt powłoki. Powyższy skrypt kompilacji rekurencyjnej jest bardzo sprytny, ale niepotrzebnie mylący.
benzado
1
Wolę skrypty powłoki dla takich rzeczy, oto moja wersja gist.github.com/3178578
slf
@benzado Tak, celowo uniknąłem złożoności, ponieważ uważam, że skrypt powłoki musi być łatwy do odczytania w celu modyfikacji.
Eonil
lipo: nie można otworzyć pliku wejściowego: / Debug-iphoneos /
Dima
11

Potrzebowałem grubej biblioteki statycznej dla JsonKit, więc stworzyłem projekt biblioteki statycznej w Xcode, a następnie uruchomiłem ten skrypt bash w katalogu projektu. Tak długo, jak skonfigurowałeś projekt xcode z wyłączoną opcją „Buduj aktywną konfigurację”, powinieneś otrzymać wszystkie architektury w jednym pliku lib.

#!/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
źródło
7

Aktualizacja IOS 10:

Miałem problem z budowaniem fatlib z iPhoneos 10.0, ponieważ wyrażenie regularne w skrypcie oczekuje tylko 9.x i niższych i zwraca 0.0 dla iOS 10.0

aby to naprawić, po prostu wymień

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

z

SDK_VERSION=$(echo ${SDK_NAME} | grep -o '[\\.0-9]\{3,4\}$')
ben
źródło
Dzięki. Dokonałem podobnej zmiany dziś rano, ale użyłem \ d. Myślę, że właśnie tego chcemy (czy jest lepszy czy gorszy od twojego?) ... grep -o '\ d \ {1,2 \} \. \ D \ {2 \} $'
Adam
Myślę, że mój jest bardziej niezawodny, ponieważ bierze pod uwagę tylko liczby
ben
1
Nie, twój odpowiada 1 konkretnemu sposobowi pisania cyfr. Biorąc pod uwagę historyczne wsparcie Apple dla (i użycie) wstępnie zapisanych znaków i tekstu (np. W nazwach plików) oczekiwałbym, że twój zastrzeżony wybór kilku cyfr będzie mniej wiarygodny.
Adam
1
dobrze, może masz rację. przynajmniej mój sprawił, że mój projekt również działa i jesteśmy bezpieczni dla następnych 89 wersji iOS
ben
Rozwiązanie @ben działa dla mnie, wyrażenie regularne Adama „[\\. 0-9] \ {3,4 \} $ 'podaje kod błędu 2
Zee
4

Zrobiłem to w szablon Xcode 4 , w tym samym stylu co szablon statyczny Karla.

Odkryłem, że budowanie statycznych ram (zamiast zwykłych bibliotek statycznych) powodowało przypadkowe awarie LLVM z powodu widocznego błędu linkera - więc sądzę, że biblioteki statyczne są nadal przydatne!

Michael Tyson
źródło
Cześć Michael, próbowałem twojego szablonu biblioteki statycznej, ale mogę skompilować dla symulatora, ale nie dla urządzenia, tutaj błąd: ** BUILD FAILED ** Następujące polecenia kompilacji nie powiodły się: ProcessPCH / var / folder / qy / ncy6fkpn6677qt876ljrc54m0000gn / C / com .apple.Xcode.501 / SharedPrecompiledHeaders / MenuBarUniversal-Prefix-gwxxzpanxyudmfgryorafazokagi / MenuBarUniversal-Prefix.pch.pth MenuBarUniversal / MenuBarUniversal-Prefix.pch normal armv7 object-c com.apple.compiler.llm ) Wyświetlanie tylko pierwszych 200 powiadomień Komenda / bin / sh nie powiodła się z kodem wyjścia 65
Kappe
2

Dobra robota! Zhakowałem razem coś podobnego, ale musiałem to uruchomić osobno. Udział w procesie kompilacji sprawia, że ​​jest to o wiele prostsze.

Jedna uwaga. Zauważyłem, że nie kopiuje żadnego z plików dołączanych, które oznaczysz jako publiczne. Dostosowałem to, co miałem w moim skrypcie, do twojego i działa całkiem dobrze. Wklej następujące elementy na końcu skryptu.

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
użytkownik503821
źródło
1
OK, dodałem to do powyższej odpowiedzi. (nie miałem jeszcze okazji go przetestować, ale wydaje mi się poprawny)
Adam
1

Właśnie napisałem własny skrypt do tego celu. Nie używa Xcode. (Opiera się na podobnym skrypcie w projekcie Gambit Scheme).

Zasadniczo uruchamia ./configure i tworzy trzy razy (dla i386, armv7 i armv7s) i łączy każdą z wynikowych bibliotek w grubą bibliotekę lib.

ups
źródło