xcode4 header preprocessor static-libraries

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



header preprocessor (17)

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 compilació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 compilació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 objetivo 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 compilar como una dependencia?


El proyecto Xcode 4 no puede compilar 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 objetivo cuando se le solicite.

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 ...


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

Por alguna razón, la casilla de verificación recursiva no funcionó para mí y tuve que agregar el resto 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 compilación. Si selecciona la falla de compilació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!


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


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 compilació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 compilaciones regulares, y "$ (BUILD_ROOT) /../ IntermediateBuildFilesPath / UninstalledProducts", que funciona para compilaciones de archivos.



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 objetivos según las dependencias y lo resolvió por problema


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 objetivo de su biblioteca tiene una fase de compilación "Copiar cabeceras", debe eliminarlo; las fases de compilación de los encabezados de copia no funcionan correctamente con los objetivos 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 compilación" en la parte inferior del editor de destino y elija "Agregar archivos de copia". Divulgue la nueva fase de compilació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 compilació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 compilació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.


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

Tengo un objetivo de aplicación y un objetivo 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 objetivo 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 objetivo de la aplicación, y ahora se archiva.

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


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!


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 compilació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 objetivo de biblioteca estática> Fases de compilació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 compilació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 compilar. 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 compilació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 compilación intermedia que Xcode crea durante el proceso de compilació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 objetivo 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 objetivo de aplicación. Esto hace que las bibliotecas estáticas se compilen antes de su objetivo de aplicación.

Comience a usar la biblioteca

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

import <LibraryName/LibraryName.h>

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 compilar 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 compilados se mueven a la carpeta "UninstalledProjects" dentro del directorio de compilació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 compilación. Dado que este directorio de compilación temporal existe para las configuraciones de Depuración y Liberación, solo necesita una ruta única para que Xcode busque bibliotecas estáticas.


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 compilació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 <LibraryName/HeaderFile.h> ), 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


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 objetivo de la biblioteca para abrir el editor de destino y seleccione la pestaña de fases de compilación. Si el objetivo de su biblioteca tiene una fase de compilación "Copiar cabeceras", debe eliminarlo; las fases de compilación de los encabezados de copia no funcionan correctamente con los objetivos de la biblioteca estática cuando se realiza la acción "Archivar" en Xcode.


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 compilara para iOS, finalmente me topé con este problema. el DropboxSDK.h definitivamente estaba al alcance 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 objetivo 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


Actualización: Xcode 9

Las respuestas anteriores no funcionaron para mí usando Xcode 9, pero esta answer 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.