2010-08-18 7 views
8

Sto scrivendo un framework (chiamato Lighthouse.framework) che, a sua volta, utilizza il codice da un altro framework (RegexKit.framework, per essere precisi). Ho copiato RegexKit.framework nel mio quadro, in modo che abbia una struttura simile alla seguente:Posso includere un framework in un altro framework?

Lighthouse.framework/ 
    Versions/ 
    A/ 
     Frameworks/ 
     RegexKit.framework 
     Lighthouse 

Tuttavia, quando si tenta di eseguire un'applicazione che utilizza Lighthouse.framework (il mio quadro), ottengo il errore seguente:

dyld: Library not loaded: @executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit

Referenced from: /Users/mdippery/Developer/Projects/Current/lighthouse/build/Debug/Lighthouse.framework/Versions/A/Lighthouse

Reason: image not found

Ovviamente, il caricatore non trova RegexKit.

Here're i sentieri del caricatore prevede di caricare, cortesia otool:

build/Debug/Lighthouse.framework/Versions/A/Lighthouse: 
    /Users/mdippery/Library/Frameworks/Lighthouse.framework/Versions/A/Lighthouse (compatibility version 1.0.0, current version 1.0.0) 
    /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 12.0.0) 
    @executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit (compatibility version 0.4.0, current version 0.6.0) 
    /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4) 
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0) 
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 476.19.0) 
    /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 677.26.0) 

Posso comprendere un quadro in un altro quadro? È questo il modo giusto per farlo? Come posso risolvere il mio errore?

+0

Ecco come è possibile includere un framework in un altro framework. http://stackoverflow.com/a/27638841/1582217 Si chiama framework ombrello. –

+0

possibile duplicato di [Come creare un framework Umbrella in sdk iOS?] (Http://stackoverflow.com/questions/27484997/how-to-create-an-umbrella-framework-in-ios-sdk) –

risposta

1

Ho scoperto una soluzione per questo problema. Ho incorporato alcune idee dalla risposta di sbooth, ma la soluzione era più semplice. Ho eseguito questo script:

install_name_tool -change @executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit @loader_path/Frameworks/RegexKit.framework/Versions/A/RegexKit "${TARGET_BUILD_DIR}/${PRODUCT_NAME}.framework/Versions/A/${PRODUCT_NAME}" 

come fase Esegui script.

Si noti che, nel caso generale, è necessario modificare @executable_path/../ a @loader_path/ e tutto va bene.

+0

Dove hai impostato questo Build Script? Al prodotto quadro o al prodotto aggregato? –

1

Sì, è possibile.

Tuttavia, è necessario il framework incluso per "sapere" quale sarà il suo percorso installato nel momento in cui è stato creato; altrimenti, dyld non sarà in grado di trovarlo in fase di esecuzione, come hai visto.

Le impostazioni pertinenti in XCode, se ricordo correttamente, sono "Directory di installazione" e "Nome di installazione del framework". Quest'ultimo probabilmente non avrà importanza per il tuo utilizzo, ma avrai bisogno che il primo sia qualcosa sulla falsariga di: @executable_path/../Frameworks/Lighthouse.framework/Versions/A/Frameworks/RegexKit.framework/Versions/A/

+0

Do I imposta la directory di installazione durante la costruzione di Lighthouse.framework (per Lighthouse.framework)? Ho provato, ma non ha funzionato (anche se forse ho fatto qualcosa di sbagliato). – mipadi

+0

@mipadi: se non stai costruendo 'RegExKit.framework', non sarai in grado di farlo. Perché vuoi che RegExKit sia contenuto nell'altro framework? Quello che stai facendo funzionerà bene senza quello. –

+0

Sarebbe bello se gli utenti del mio framework dovessero solo includere il mio framework e non includere anche le dipendenze del mio framework. – mipadi

8

Il modo più semplice è usare @rpath. La configurazione dovrebbe essere simile:

  1. di Set RegExKit.framework Directory di installazione per @rpath directory di installazione di
  2. Set Lighthouse.frameworks a @rpath
  3. di
  4. Set Lighthouse.framework RunPath percorsi di ricerca a @ loader_path/quadri
  5. Assicurarsi che RegExKit.framework viene copiato in sottocartella quadro di Lighthouse.framework (utilizzare una fase di generazione personalizzata per questo)

Infine, qualsiasi applicazioni linkin g to Lighthouse.framework dovrebbe impostare i percorsi di ricerca del percorso di corsa in @loader_path /../ Frameworks

+0

Non sto creando RegexKit.framework (sto usando un binario precompilato). Posso ancora impostare la directory di installazione per questo (non ho visto un modo per farlo)? – mipadi

+1

Puoi usare install_name_tool per questo, qualcosa come install_name_tool -change @executable_path /../ Frameworks @ rpath/Frameworks – sbooth

Problemi correlati