2010-08-18 15 views
8

Estoy escribiendo un framework (llamado Lighthouse.framework) que, a su vez, usa código de otro framework (RegexKit.framework, para ser precisos). He copiado RegexKit.framework en mi propio marco, de manera que tiene una estructura como la siguiente:¿Puedo incluir un marco en otro marco?

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

Sin embargo, cuando trato de ejecutar una aplicación que utiliza Lighthouse.framework (mi marco), consigo el el siguiente error:

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

Obviamente, el cargador no encuentra RegexKit.

Acá los caminos del cargador de espera para cargar, cortesía 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) 

¿Puedo incluir un marco en otro contexto? ¿Es esta la manera correcta de hacerlo? ¿Cómo puedo resolver mi error?

+0

Así es como puede incluir un marco en otro marco. http://stackoverflow.com/a/27638841/1582217 Se llama marco paraguas. –

+0

posible duplicado de [¿Cómo crear un marco Umbrella en iOS sdk?] (Http://stackoverflow.com/questions/27484997/how-to-create-an-umbrella-framework-in-ios-sdk) –

Respuesta

1

Descubrí una solución para este problema. Incorporé algunas ideas de la respuesta de sbooth, pero la solución fue más simple. Ejecuté este 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}" 

como fase Ejecutar script de compilación.

Tenga en cuenta que, para el caso general, debe cambiar @executable_path/../ a @loader_path/, y todo está bien.

+0

¿Dónde configuró este Build Script? ¿En el producto marco o en el producto agregado? –

1

Sí, puedes.

Sin embargo, necesita el marco incluido para "saber" cuál será su ubicación instalada en el momento en que está construida; de lo contrario, dyld no podrá encontrarlo en tiempo de ejecución, como pudo ver.

Las configuraciones relevantes en XCode, si no recuerdo mal, son "Directorio de instalación" y "Nombre de instalación del marco". Lo último probablemente no importará para su uso, pero necesitará que el primero sea algo similar a: @executable_path/../Frameworks/Lighthouse.framework/Versions/A/Frameworks/RegexKit.framework/Versions/A/

+0

Do I establecer el directorio de instalación cuando se construye Lighthouse.framework (para Lighthouse.framework)? Lo intenté, pero no funcionó (aunque tal vez hice algo mal). – mipadi

+0

@mipadi: si no está compilando 'RegExKit.framework', no podrá hacer esto. ¿Por qué quieres que RegExKit esté contenido en el otro marco? Lo que estás haciendo funcionará bien sin eso. –

+0

Sería bueno si los consumidores de mi framework solo tuvieran que incluir mi framework, y tampoco incluir las dependencias de mi framework. – mipadi

8

La manera más fácil es usar @rpath. Su configuración debe ser similar:

  1. Directorio de instalación del conjunto RegExKit.framework a @rpath directorio de instalación
  2. Set Lighthouse.frameworks a @rpath
  3. de
  4. Conjunto Lighthouse.framework RUNPATH rutas de búsqueda a @ loader_path/marcos
  5. Asegúrese de que RegExKit.framework se copia en la subcarpeta marco de Lighthouse.framework (usar una fase de generación personalizada para este)

Finalmente, cualquier Linkin aplicaciones g a Lighthouse.framework debe establecer Path Paths de búsqueda en @loader_path /../ Frameworks

+0

No estoy compilando RegexKit.framework (estoy usando un binario precompilado). ¿Todavía puedo configurar el directorio de instalación para él (no vi una forma de hacerlo)? – mipadi

+1

Puede usar install_name_tool para esto, algo así como install_name_tool -change @executable_path /../ Frameworks @ rpath/Frameworks – sbooth