Xcode 4 no puede ubicar los archivos de encabezado público de la dependencia de la biblioteca estática

Títulos alternativos para ayudar a la búsqueda

  • Xcode no puede encontrar el encabezado
  • Falta .h en Xcode
  • Archivo Xcode .h no encontrado
  • archivo léxico o de preprocesador no encontrado

Estoy trabajando en un proyecto de aplicación iOS que vino de Xcode 3. Ahora me he mudado a Xcode 4. Mi proyecto construye varias bibliotecas estáticas.

Esas bibliotecas estáticas también declaran encabezados públicos y esos encabezados son utilizados por el código de la aplicación. En Xcode 3.x los encabezados se copiaron (como una fase de comstackción) en el public headers directory , luego en el proyecto de la aplicación el public headers directory se agregó a la headers search list .

En Xcode 4, el directorio de comstackción se mueve a ~/Library/Developer/Xcode/DerivedData/my-project .

El problema es ¿cómo hago referencia a esta nueva ubicación en la configuración de búsqueda de encabezados? Parece que:

  • public headers directory es relativo al directorio DerivedData , pero
  • directorio de headers search es relativo a otra cosa (posiblemente la ubicación del proyecto)

¿Cómo debo configurar un objective de biblioteca estática para el desarrollo de iOS en Xcode 4 que garantizará que los archivos de cabecera estén disponibles para los clientes que usan la biblioteca estática al intentar comstackr como una dependencia?

Cada una de las soluciones que he visto para este problema parece ser poco elegante (copiar encabezados en el proyecto de la aplicación) o simplificar demasiado hasta el punto de que solo funcionan en situaciones triviales.

La respuesta corta

Agregue la siguiente ruta a sus rutas de búsqueda de encabezado de usuario

“$ (BUILD_ROOT) /../ IntermediateBuildFilesPath / UninstalledProducts”

¿Por qué funciona esto?

Primero, necesitamos entender el problema. En circunstancias normales, es decir, cuando ejecuta, prueba, perfila o analiza, Xcode crea su proyecto y lo coloca en el directorio de comstackción / productos / configuración / productos, que está disponible a través de la macro $ BUILT_PRODUCTS_DIR .

La mayoría de las guías sobre bibliotecas estáticas recomiendan establecer la ruta de la carpeta de encabezados públicos a $ TARGET_NAME , lo que significa que su archivo lib se convierte en $ BUILT_PRODUCTS_DIR /libTargetName.a y sus encabezados se ponen en $ BUILT_PRODUCTS_DIR / TargetName. Siempre que su aplicación incluya $ BUILT_PRODUCTS_DIR en sus rutas de búsqueda, las importaciones funcionarán en las 4 situaciones indicadas anteriormente. Sin embargo, esto no funcionará cuando intentes archivar.

Archivar funciona de forma un poco diferente

Cuando archiva un proyecto, Xcode usa una carpeta diferente llamada ArchiveIntermediates. Dentro de esa carpeta encontrará / YourAppName / BuildProductsPath / Release-iphoneos /. Esta es la carpeta a la que apunta $ BUILT_PRODUCTS_DIR cuando haces un archivo. Si miras allí, verás que hay un enlace simbólico a tu archivo de biblioteca estática pero falta la carpeta con los encabezados.

Para encontrar los encabezados (y el archivo lib), debe ir a IntermediateBuildFilesPath / UninstalledProducts /. ¿Recuerdas cuando te dijeron que configuraras Skip Install en YES para bibliotecas estáticas? Bueno, este es el efecto que tiene esa configuración cuando haces un archivo.

Nota al margen: si no lo configura para que omita la instalación, sus encabezados se colocarán en otra ubicación y el archivo lib se copiará en su archivo, lo que le impedirá exportar un archivo .ipa que puede enviar al App Store. .

Después de mucha búsqueda, no pude encontrar ninguna macro que corresponda a la carpeta UninstalledProducts exactamente, de ahí la necesidad de construir la ruta con “$ (BUILD_ROOT) /../ IntermediateBuildFilesPath / UninstalledProducts”

Resumen

Para su biblioteca estática, asegúrese de omitir la instalación y que sus encabezados públicos se coloquen en $ TARGET_NAME.

Para su aplicación, establezca las rutas de búsqueda de encabezado de usuario a “$ (BUILT_PRODUCTS_DIR)”, que funciona bien para comstackciones regulares, y “$ (BUILD_ROOT) /../ IntermediateBuildFilesPath / UninstalledProducts”, que funciona para comstackciones de archivos.

Me encontré con este mismo problema cuando desarrollé mi propia biblioteca estática y, aunque la respuesta de Colin fue muy útil, tuve que modificarla un poco para que funcionara de manera consistente y sencilla cuando ejecutaba y archivaba proyectos bajo Xcode 4 usando un área de trabajo.

Lo que es diferente acerca de mi método es que puedes usar una ruta de encabezado de un solo usuario para todas tus configuraciones de comstackción.

Mi método es el siguiente:

Crear un espacio de trabajo

  1. En Xcode 4, ve a Archivo, Nuevo, Espacio de trabajo.
  2. Desde Finder, puede arrastrar en los proyectos .xcodeproj tanto para la biblioteca estática que desea usar como para la nueva aplicación que está creando y que utiliza la biblioteca. Consulte Apple Docs para obtener más información sobre la configuración de Espacios de trabajo: https://developer.apple.com/library/content/featuredarticles/XcodeConcepts/Concept-Workspace.html

Configuración del proyecto de biblioteca estática

  1. Asegúrese de que todos los encabezados de la biblioteca estática estén configurados para copiar a “Público”. Esto se hace bajo la configuración para el objective de biblioteca estática> Fases de comstackción. En la fase “Copiar encabezados”, asegúrese de que todos los encabezados estén dentro de la sección “Público”.
  2. Luego vaya a Configuración de comstackción, encuentre “Ruta de carpeta de encabezados públicos” y escriba una ruta para su biblioteca. Elijo usar esto:

include / LibraryName

Lo adopté del uso con RestKit y encontré que funciona mejor con todas mis bibliotecas estáticas. Lo que hace esto es decirle a Xcode que copie todos los encabezados que movimos a la sección de encabezados “Públicos” en el paso 1 a la carpeta que especifiquemos aquí que se encuentra dentro de la carpeta de Datos Derivados al comstackr. Al igual que con RestKit, me gusta usar una única carpeta “incluir” para contener cada biblioteca estática que estoy usando en un proyecto.

Tampoco me gusta usar macros aquí porque nos permitirá usar una ruta de búsqueda de encabezado de un solo usuario más tarde cuando configuramos el proyecto usando la biblioteca estática.

  1. Encuentra “Omitir instalación” y asegúrate de que esté establecido en SÍ.

Configuraciones para el proyecto usando la biblioteca estática

  1. Agregue la biblioteca estática como un marco bajo Crear Fases> Enlace Binario con Bibliotecas y agregue el archivo libLibraryName.a para cualquier biblioteca estática que desee usar.
  2. A continuación, asegúrese de que el proyecto esté configurado para buscar Rutas de búsqueda de usuario. Esto se realiza en Configuraciones de comstackción> Buscar siempre en las rutas de usuario y asegúrese de que esté configurado en SÍ.
  3. En la misma área, busque Rutas de búsqueda de encabezado de usuario y agregue:

    “$ (PROJECT_TEMP_DIR) /../ UninstalledProducts / include”

Esto le dice a Xcode que busque bibliotecas estáticas dentro de la carpeta de comstackción intermedia que Xcode crea durante el proceso de comstackción. Aquí, tenemos la carpeta “incluir” que estamos usando para nuestras ubicaciones de biblioteca estática que configuramos en el paso 2 para la configuración del proyecto de biblioteca estática. Este es el paso más importante para que Xcode encuentre correctamente sus bibliotecas estáticas.

Configurar el espacio de trabajo

Aquí queremos configurar el espacio de trabajo para que construya la biblioteca estática cuando construyamos nuestra aplicación. Esto se hace editando el esquema utilizado para nuestra aplicación.

  1. Asegúrese de tener el esquema seleccionado que creará su aplicación.
  2. Desde el menú desplegable de esquema, elija Editar esquema.
  3. Seleccione Build en la parte superior de la lista a la izquierda. Agregue un nuevo objective presionando + en el panel central.
  4. Debería ver aparecer la biblioteca estática de la biblioteca que intenta vincular. Elija la biblioteca estática de iOS.
  5. Haga clic en Ejecutar y archivar. Esto le dice al esquema que compile las bibliotecas para la biblioteca estática cada vez que crea su aplicación.
  6. Arrastre la biblioteca estática sobre su objective de aplicación. Esto hace que las bibliotecas estáticas se compilen antes de su objective de aplicación.

Comience a usar la biblioteca

Ahora, debería poder importar su biblioteca estática usando

 import  

Este método evita la molestia de tener que tener diferentes rutas de encabezado de usuario para diferentes configuraciones, por lo que no debería tener problemas para comstackr archivos.

¿Por qué funciona esto?

Todo depende de esta ruta:

 "$(PROJECT_TEMP_DIR)/../UninstalledProducts/include" 

Debido a que configuramos nuestra biblioteca estática para usar “Omitir instalación”, los archivos comstackdos se mueven a la carpeta “UninstalledProjects” dentro del directorio de comstackción temporal. Nuestra ruta aquí también se resuelve en la carpeta “incluir” que configuramos para nuestra biblioteca estática y usamos para nuestra ruta de búsqueda de encabezado de usuario. Los dos trabajando juntos le permiten a Xcode saber dónde encontrar nuestra biblioteca durante el proceso de comstackción. Dado que este directorio de comstackción temporal existe para las configuraciones de Depuración y Liberación, solo necesita una ruta única para que Xcode busque bibliotecas estáticas.

El proyecto Xcode 4 no puede comstackr una biblioteca estática

Pregunta relacionada: “archivo de problema léxico o de preprocesador no encontrado” en Xcode 4

Los errores pueden incluir; falta de archivos de encabezado, “problema léxico o preprocesador”

Soluciones:

  1. Compruebe que las “rutas de encabezado del usuario” son correctas
  2. Establezca “Buscar siempre rutas de usuario” en SÍ
  3. Cree una llamada de grupo “Encabezados de indización” en su proyecto y arrastre los encabezados a este grupo. NO lo agregue a ningún objective cuando se le solicite.

Este fue un hilo muy útil. Al investigar mi propia situación, descubrí que Apple tiene un documento de 12 páginas con fecha de septiembre de 2012 titulado “Uso de bibliotecas estáticas en iOS”. Aquí está el enlace pdf: http://developer.apple.com/library/ios/technotes/iOSStaticLibraries/iOSStaticLibraries.pdf

Es mucho más simple que la mayoría de las discusiones en Internet, y con algunas modificaciones pequeñas para explicar cómo están configuradas las bibliotecas externas que estoy usando, me funciona bien. La parte más importante es probablemente:

Si el objective de su biblioteca tiene una fase de comstackción “Copiar cabeceras”, debe eliminarlo; las fases de comstackción de los encabezados de copia no funcionan correctamente con los objectives de la biblioteca estática cuando se realiza la acción “Archivar” en Xcode.

Los nuevos destinos de biblioteca estática creados con Xcode 4.4 o posterior vendrán con una fase de Copiar archivos configurada apropiadamente para los encabezados, por lo que debe verificar si ya tiene uno antes de crear uno. Si no lo hace, presione “Agregar fase de comstackción” en la parte inferior del editor de destino y elija “Agregar archivos de copia”. Divulgue la nueva fase de comstackción Copiar archivos y configure el Destino en “Directorio de productos”. Establezca el Subtrayecto para incluir / $ {PRODUCT_NAME}. Esto copiará los archivos en una carpeta con el nombre de su biblioteca (tomada de la configuración de comstackción de PRODUCT_NAME), dentro de una carpeta denominada incluir, dentro de su directorio de productos creados. La carpeta de inclusión dentro de un directorio de productos de comstackción está en la ruta de búsqueda de encabezado predeterminada para las aplicaciones, por lo que este es un lugar apropiado para colocar los archivos de encabezado.

Estoy seguro de que en muchas situaciones existentes, el enfoque de Apple puede no ser suficiente. Publico esto aquí para cualquiera que esté empezando su viaje en el jardín estático de la biblioteca; este puede ser el mejor punto de partida para casos simples.

http://developer.apple.com/library/ios/#technotes/iOSStaticLibraries/Articles/creating.html

Según la documentación de Apple:

Su biblioteca tendrá uno o más archivos de encabezado que los clientes de esa biblioteca deben importar. Para configurar qué encabezados se exportan a los clientes, seleccione su proyecto de biblioteca para abrir el editor de proyectos, seleccione el objective de la biblioteca para abrir el editor de destino y seleccione la pestaña de fases de comstackción. Si el objective de su biblioteca tiene una fase de comstackción “Copiar cabeceras”, debe eliminarlo; las fases de comstackción de los encabezados de copia no funcionan correctamente con los objectives de la biblioteca estática cuando se realiza la acción “Archivar” en Xcode.

Eche un vistazo a la solución de Jonah Wlliam (a mitad de camino) y el modelo de GitHub (en comentarios) para obtener una idea. http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/

Agregue $ (OBJROOT) / UninstalledProducts / exactPathToHeaders a las rutas de búsqueda de encabezado.

Por alguna razón, la checkbox recursiva no funcionó para mí y tuve que agregar el rest de la ruta a donde están ubicados los encabezados.

En Log Navigator en Xcode (la pestaña a la derecha del navegador de puntos de interrupción) puede ver el historial de comstackción. Si selecciona la falla de comstackción real, puede ampliar sus detalles para ver la ruta de acceso setenv y verificar que la ruta a sus archivos de encabezado esté allí.

Agregue la siguiente ruta a sus rutas de búsqueda de encabezado de usuario:

 $(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts 

¡Esto es verificado!

A riesgo de mostrar lo idiota que soy … He estado sufriendo de XCode negándome a encontrar mis archivos .h toda la tarde.

Entonces me di cuenta.

Debido a que estaba usando “XCode 4”, decidí “inteligentemente” poner todos mis proyectos en una subcarpeta de una carpeta llamada ” XCode 4 projects “.

Esos espacios en el nombre de la carpeta arruinaron XCode a lo grande.

Cambiar el nombre de esta carpeta a ” XCode_4_Projects ” ha traído alegría (y menos palabrotas) a mi vida.

Recuérdame de nuevo, ¿qué año es esto?

Tal vez alguien podría decirles a los desarrolladores de Apple …

Ninguna de estas respuestas funcionó para mí. Esto es lo que hizo. Agregue exactamente lo siguiente (copie y pegue incluidas las comillas dobles) a la configuración de comstackción de las Rutas de búsqueda del encabezado del usuario :

 "$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts/include/" 

Tenga en cuenta la adición del subdirectorio “/ include /” en comparación con otras respuestas. Como otros usuarios han señalado, la opción “recursiva” no parece hacer nada, por lo que puede ignorarla.

Mi proyecto ahora podía archivar correctamente al importar archivos de cabecera de biblioteca estática de la siguiente forma:

 #import "LibraryName/HeaderFile.h" 

No es necesario que habilite la configuración de las Rutas de usuario de búsqueda permanente , a menos que incluya los encabezados de la biblioteca estática con corchetes angulares ( #import ), pero realmente no debería hacerlo de todos modos si no es así. un encabezado de sistema / marco.

Ninguna de las respuestas anteriores funcionó para mí en Xcode 7, pero me dieron una buena idea. Para los chicos que luchan en Xcode 7, esto se solucionó agregando lo siguiente a las rutas de búsqueda del encabezado del usuario (incluir citas)

 "$(BUILT_PRODUCTS_DIR)/usr/local/include" 

Cambie la parte de URL relativa usr/local/include acuerdo con lo que hay en la configuración de “Ruta de carpeta de encabezado público” de la biblioteca estática

En mi caso, mi espacio de trabajo tenía un par de proyectos de biblioteca estática y uno de ellos tiene dependencia, incluidos archivos de encabezado con el otro. El problema era con el orden de construcción. En la página Editar esquema en la sección Generar, deseleccioné la opción paralelizar y organicé el orden de los objectives según las dependencias y lo resolvió por problema

Este es un tema relacionado que me llevó a esta pregunta, así que estoy agregando mi solución estrictamente para la documentación / podría ahorrarle a otro alma horas de sudoración

No se encontró el archivo DropboxSDK.h

Después de días de tratar de hacer que VES comstackra para iOS, finalmente me topé con este problema. el DropboxSDK.h definitivamente estaba al scope de search headers de search headers , incluso lo agregué a la ruta de búsqueda de los framework headers del framework headers , include d .h y directamente a todo tipo de longitudes para intentar obtener DropboxSDK.h .

Solución

EXPLICITY arrastre el archivo DropboxSDK.framework al DropboxSDK.framework de Project Navigation de Xcode y asegúrese de que Copy Files if needed esté marcado. También asegúrese de que su objective esté marcado según sea necesario.

Advertencia

Establecer la ubicación del marco explícito en las build phases no funcionó para mí. Tuve que arrastrar el .framework a Xcode y asegurarme de que los archivos se copiaron en mi proyecto.

# mbp2015 # xcode7 # ios9

Hay varias formas complejas de hacer esto, y se proponen algunas soluciones muy inteligentes en este hilo.

El principal problema para todas estas soluciones es que disminuye seriamente la portabilidad de su biblioteca.

  • Cada vez que necesita comenzar un nuevo proyecto usando su biblioteca y archivarlo para iTunes, es un infierno de la configuración.
  • Cada vez que necesite compartir su proyecto con su equipo o sus clientes, puede romperse por cualquier motivo (contexto, versión de Xcode, lo que sea, …)

Mi elección ha sido, finalmente, utilizar frameworks, siempre, como recomienda Apple (WWDC Videos).

¡Es tan fácil y hace el mismo trabajo al final!

Otra solución bastante elegante que parece funcionar es usar Cocoapods privados. Cocoapods hace todo el trabajo de configuración, copia de encabezado y demás.

Frameworks rock!

Esto es lo que resolvió el mismo problema para mí.

Tengo un objective de aplicación y un objective de extensión de iMessage. Luego tuve 2 SDK (el mío), con los que se vincula la aplicación de destino.

El problema era: mi objective de iMessage también usaba los 2 SDK (proyectos por separado), pero no estaba vinculando con ellos en Build Fhases -> Link Binary With Libraries. Tuve que agregar mis 2 SDK al destino de iMessage allí, para que coincida con mi objective de la aplicación, y ahora se archiva.

Entonces, la moraleja de la historia es: si tienes objectives múltiples, como extensiones, asegúrate de que todos tus objectives se vinculen con las bibliotecas que necesitan. Pudo construir e implementar en el simulador y el dispositivo, pero no en Archivar.

Actualización: Xcode 9

Las respuestas anteriores no funcionaron para mí usando Xcode 9, pero esta respuesta funcionó perfectamente para mí. He añadido $(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include a mis “Rutas de búsqueda de encabezado” y Xcode vinculó el encabezado de mi biblioteca estática sin problemas.

Ahórrese el problema y haga esto = cree una nueva cuenta de usuario en su Mac – abra el proyecto en la nueva cuenta de usuario– todos los problemas desaparecen. Ahorre su tiempo y mantenga su cordura. todas esas respuestas nerds no ayudan !!

Buena suerte