Xcode 12, building for iOS Simulator, but linking in an object file built for iOS, for architecture ‘arm64’ (come risolvere)

Condividi questo articolo:


Sto cercando di compilare un grande (e funzionante su Xcode 11!) progetto in Xcode 12 (beta 5) per prepararmi per iOS 14. La codebase era precedentemente in Objective-C, ma ora contiene sia Objective-C che Swift, e usa anche pods che sono Objective-C e/o Swift.

Ho estratto la nuova beta di CocoaPods con supporto per Xcode 12 (attualmente 1.10.0.beta 2).

L’installazione dei pod ha successo. Quando faccio una build, ottengo il seguente errore su un framework pod:

costruzione per iOS Simulator, ma collegamento in file oggetto costruito per iOS, per architettura arm64

Quando vado a eseguire lipo -info sul framework, ha: armv7s armv7 i386 x86_64 arm64.

In precedenza, il progetto aveva Valid Architectures impostato su: armv7, armv7s e arm64.

In Xcode 12, questa impostazione sparisce, come da documentazione Apple. Le architetture sono impostate su $(ARCHS_STANDARD). Non ho nulla impostato in architetture escluse.

Come risolvere: Xcode 12, building for iOS Simulator, but linking in an object file built for iOS, for architecture ‘arm64’

Fondamentalmente, dovete escludere arm64 per l’architettura del simulatore, sia dal vostro progetto che dal progetto Pod,

Per farlo, vai su Build Settings del tuo progetto e aggiungi Any iOS Simulator SDK con il valore arm64 dentro Excluded Architecture.

Oppure:

Se state usando file XCConfig personalizzati, potete semplicemente aggiungere questa linea per escludere l’architettura del simulatore.

                    

EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64

Poi

Dovete fare lo stesso per il progetto Pod fino a quando tutti i venditori di pod Cocoa hanno finito di aggiungere quanto segue nei loro Podspec.

                    

s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }

Puoi aggiungere manualmente l’architettura esclusa nelle Build Settings del tuo progetto Pod, ma sarà sovrascritta quando usi pod install.

Al posto di questo, puoi aggiungere questo snippet nel tuo Podfile. Scriverà le necessarie Build Settings ogni volta che eseguirai pod install.

                    

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
  end
end

 

Approfondimento:

Imposta “Build Active Architecture Only (ONLY_ACTIVE_ARCH)” su Yes per le tue librerie/app, anche per la modalità di relase.

Mentre cercavo di identificare la causa principale del problema ho realizzato alcuni fatti anomali su Xcode 12.

Xcode 12 è in realtà il trampolino di lancio per  Apple Silicon M. Ma con quella piattaforma avremo un macOS basato su arm64 dove i simulatori gireranno anche sull’architettura arm64 a differenza dell’attuale architettura x86_64 basata su Intel.

Xcode di solito dipende dalla “Run Destination” per costruire le sue librerie/applicazioni. Così quando un simulatore è scelto come “Run Destination”, costruisce l’applicazione per le architetture del simulatore disponibili e quando un dispositivo è scelto come “Run Destination” costruisce per l’architettura che il dispositivo supporta (arm*).

xcodebuild, nel sistema di compilazione di Xcode 12+ considera arm64 come un’architettura valida per il simulatore per supportare il silicio Apple. Quindi, quando un simulatore viene scelto come destinazione di esecuzione, può potenzialmente provare a compilare/collegare le tue libs/app con simulatori basati su arm64, pure. Quindi invia a clang(++) qualche flag -target come arm64-apple-ios13.0-simulator in formato <architettura>-<os>-<sdk>-<destinazione> e clang prova a compilare/linkare contro un simulatore basato su arm64 che alla fine fallisce su un Mac basato su Intel.

Ma xcodebuild prova questo solo per le build di Release. Perché? Perché le impostazioni di compilazione “Build Active Architecture Only (ONLY_ACTIVE_ARCH)” sono solitamente impostate su “No” solo per la configurazione “Release”. E questo significa che xcodebuild proverà a costruire tutte le varianti architetturali delle tue libs/app per la destinazione di esecuzione selezionata per le build di rilascio. E per la destinazione di esecuzione del simulatore, includerà sia x86_64 che arm64 ora, poiché arm64 in Xcode 12+ è anche un’architettura supportata per i simulatori per supportare il silicio Apple.

In poche parole, Xcode non riuscirà a costruire la tua applicazione ogni volta che proverà la linea di comando, xcodebuild, (che ha come impostazione predefinita la build di rilascio, vedi la scheda generale delle impostazioni del tuo progetto) o altrimenti e cercherà di costruire tutte le varianti architetturali supportate dalla destinazione di esecuzione. Quindi un semplice workaround a questo problema è quello di impostare “Build Active Architecture Only (ONLY_ACTIVE_ARCH)” a Yes nelle tue librerie/app, anche per la modalità release.

developify

Andrea Piani Administrator
Mi chiamo Andrea Piani, sono un programmatore specializzato nello sviluppo di App iOS e Android. Appassionato di elettronica e blockchain. Divulgatore tecnologico. Creatore della web agency Immaginet Srl (Udine) e di PrestaExpert Srl (Milano), aziende specializzate in Digital Marketing ed e-commerce.
follow me

Vuoi una consulenza a pagamento? Vuoi sviluppare un software per la tua attività? Hai bisogno di informazioni? Compila il modulo per contattarmi. Ti risponderò entro 24 ore.

Fill out my online form.

Iscriviti alla newsletter. Scegli la categoria che preferisci. Solo articoli esclusivi e di alta qualità che non trovi sul blog. Niente SPAM. Promesso!


Condividi questo articolo:
LEGGI ANCHE:  xCode xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)