2010-08-18 8 views
8

J'écris un cadre (appelé Lighthouse.framework) qui, à son tour, utilise le code d'un autre cadre (RegexKit.framework, pour être précis). Je l'ai copié RegexKit.framework dans mon propre cadre, de sorte qu'il a une structure comme ce qui suit:Puis-je inclure un cadre dans un autre cadre?

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

Cependant, lorsque je tente d'exécuter une application qui utilise Lighthouse.framework (mon cadre), je reçois le erreur suivante:

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

De toute évidence, le chargeur ne trouve pas RegexKit.

Here're les chemins du chargeur pour charger, attend avec la permission 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) 

Puis-je inclure un cadre dans un autre cadre? Est-ce la bonne façon de le faire? Comment puis-je résoudre mon erreur?

+0

Voici comment vous pouvez inclure un cadre dans un autre cadre. http://stackoverflow.com/a/27638841/1582217 C'est ce qu'on appelle le cadre parapluie. –

+0

double possible de [Comment créer un cadre parapluie dans iOS sdk?] (Http://stackoverflow.com/questions/27484997/how-to-create-an-umbrella-framework-in-ios-sdk) –

Répondre

1

j'ai découvert un correctif pour ce problème. J'ai incorporé quelques idées de la réponse de booth, mais la solution était plus simple. J'ai exécuté ce 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}" 

en tant que phase de génération de script de génération.

Notez que, pour le cas général, vous devez changer @executable_path/../ à @loader_path/, et tout va bien.

+0

Où avez-vous défini ce script de construction? Au produit cadre ou au produit agrégé? –

1

Oui, vous pouvez.

Cependant, vous avez besoin du cadre inclus pour « savoir » ce que son emplacement d'installation sera au moment où il est construit; Sinon, dyld ne sera pas en mesure de le trouver au moment de l'exécution, comme vous l'avez vu.

Les paramètres pertinents dans XCode, si je me souviens bien, sont « Répertoire d'installation » et « Cadre d'installation Nom ». Ce dernier ne sera probablement pas important pour votre usage, mais vous aurez besoin de quelque chose comme: @executable_path/../Frameworks/Lighthouse.framework/Versions/A/Frameworks/RegexKit.framework/Versions/A/

+0

Do I définir le répertoire d'installation lors de la construction de Lighthouse.framework (pour Lighthouse.framework)? J'ai essayé, mais cela n'a pas fonctionné (même si j'ai peut-être fait quelque chose de mal). – mipadi

+0

@mipadi: Si vous ne construisez pas 'RegExKit.framework', vous ne pourrez pas le faire. Pourquoi voulez-vous que RegExKit soit contenu dans l'autre cadre? Ce que vous faites fonctionnera très bien sans cela. –

+0

Ce serait bien si les utilisateurs de mon framework devaient seulement inclure mon framework, et pas aussi les dépendances de mon framework. – mipadi

8

La façon la plus simple est d'utiliser @rpath. Votre configuration devrait ressembler à:

  1. Set répertoire d'installation de RegExKit.framework à @rpath
  2. Set répertoire d'installation de Lighthouse.frameworks à @rpath
  3. Set RUNPATH de Lighthouse.framework chemins de recherche à @ loader_path/cadres
  4. Assurez-vous que RegExKit.framework est copié dans le sous-dossier cadre de Lighthouse.framework (utiliser une phase de construction personnalisée pour cette)

Enfin, toute application linkin g à Lighthouse.framework doit définir RUNPATH chemins de recherche pour @loader_path /../ Cadres et

+0

Je ne construis pas RegexKit.framework (j'utilise un binaire pré-compilé). Puis-je toujours définir le répertoire d'installation pour cela (je n'ai pas vu un moyen de le faire)? – mipadi

+1

Vous pouvez utiliser install_name_tool pour cela - quelque chose comme install_name_tool -change @executable_path /../ Frameworks @ rpath/Frameworks – sbooth