2011-10-30 4 views
7

Ho un progetto con una dipendenza da una libreria statica di terze parti e dalle tre20 librerie. In XCode 3.X, per ottenere la compilazione del mio progetto, ho dovuto usare il flag -force_load nell'impostazione di build "Altri linker" e specificare ognuna delle tre 20 librerie che volevo includere.Perché il carico -force_load non è più necessario per le mie dipendenze da tre20 in XCode 4.2?

Durante il tentativo di creare un archivio in XCode 4.2, ricevevo un errore di "simbolo duplicato". Ho risolto questo problema rimuovendo i sette flag separati -force_load che si riferivano a ciascuna delle tre 20 librerie su cui avevo una dipendenza.

Il mio progetto ora funziona correttamente.

Mi chiedo se qualcuno può spiegare al mio perché questo cambiamento ha funzionato? C'è stato un bug che XCode 4.2 ha risolto, o è una modifica comportamentale? This post suggests c'era un bug in XCode 3.2, ma sarebbe bello se qualcuno potesse gettare ulteriore luce su questo argomento per me quindi posso essere sicuro di non aver fatto qualcosa di sbagliato rimuovendo questi flag -force_load.

Grazie!

risposta

19

Quando si crea una libreria statica (come richiesto per iOS), uno dei problemi che si incontrano è come includere i simboli dalle categorie in quella libreria in modo che siano utilizzabili da un'applicazione. Il flag del linker -ObjC dovrebbe inserire informazioni sufficienti per includere le categorie in questi framework, come Dave Dribin descrive nel suo articolo here.

Tuttavia, tra iPhone OS 2.0 e 3.0, questo ha smesso di funzionare correttamente. Come accennato in this answer, abbiamo riscontrato questo problema nel framework Core Plot e abbiamo scoperto che era necessario aggiungere il flag del linker -all_load per far funzionare correttamente il framework. Apple ha pubblicato stessi Technical Q&A QA1490 che cita questo problema:

a 64 bit e le applicazioni iPhone OS, c'è un bug linker che impedisce -ObjC caricamento di oggetti file da librerie statiche che contengono solo le categorie e classi. La soluzione alternativa consiste nell'utilizzare i flag -all_load o -force_load.

-all_load forza il linker a caricare tutti i file oggetto da ogni archivio che vede, anche quelli senza codice Objective-C. -force_load è disponibile in Xcode 3.2 e versioni successive. Consente un controllo più fine del caricamento dell'archivio . Ogni opzione -force_load deve essere seguita da un percorso per un archivio e ogni file oggetto in quell'archivio verrà caricato.

Purtroppo, l'effetto collaterale di questo è che i simboli duplicati collegati in dalle librerie multiple possono causare errori come quelli che hai incontrato.

Ho archiviato un bug report su questo (nel 2009), e sembra che l'ultima versione di LLVM ora usata in Xcode non soffra più di questo bug del linker. Ho provato a usare solo -ObjC con il target della libreria statica di Core Plot per iOS e ora funziona perfettamente. Questa è una buona notizia.

+0

Cool, quindi è stato sicuramente un bug, ed empiricamente sembra che sia stato corretto (anche se Apple non ha annunciato nulla ...) Grazie! – esilver

+0

Penso che tu abbia ancora bisogno di -ObjC per caricare le categorie, e questo ti darà comunque un errore "simbolo duplicato" se lo fai, intatto hai simboli duplicati, giusto? – hooleyhoop

+1

@hooleyhoop - Giusto, come premetto sopra hai ancora bisogno di -ObjC per le categorie, ma nella mia esperienza rimuovendo il flag linker -all_load' si elimina quasi tutti gli errori dei simboli duplicati che vedi. Se ricordo bene, molti di quei simboli provenivano da framework a cui erano collegati in più di una libreria statica, quindi entrambe le librerie statiche erano utilizzate nella stessa applicazione. Naturalmente, '-ObjC' non ti proteggerà dal caso in cui diverse categorie definiscono entrambi lo stesso nome di metodo di un'estensione della stessa classe, ma le convenzioni di denominazione appropriate dovrebbero impedirlo. –

Problemi correlati