2010-04-07 14 views
14

Mi proyecto de Xcode se basa en variaciones del mismo producto utilizando dos objetivos. La diferencia entre los dos es solo en qué versión de una biblioteca incluida se utiliza. Para los archivos de origen .c, es fácil asignar la versión correcta al destino correcto utilizando la casilla de verificación de destino. Sin embargo, incluir el archivo de encabezado siempre incluye el mismo. Esto es correcto para un objetivo, pero incorrecto para el otro.controlando qué archivo de encabezado de proyecto Xcode incluirá

¿Hay alguna forma de controlar qué archivo de encabezado incluye cada objetivo?

Aquí es mi jerarquía de archivo de proyecto (que se replica en Xcode):

MyProject 
    TheirOldLib 
    theirLib.h 
    theirLib.cpp 
    TheirNewLib 
    theirLib.h 
    theirLib.cpp 
myCode.cpp 

y myCode.cpp hace tal cosa como:

#include "theirLib.h" 
… 
somecode() 
{ 
#if OLDVERSION 
    theirOldLibCall(…); 
#else 
    theirNewLibCall(…); 
#endif 
} 

Y, por supuesto, defino OLDVERSION por una objetivo y no para el otro.

Tenga en cuenta que #include debe ser como se muestra. Ambos de los siguientes errores fallar con un archivo no encontrado:

#include "TheirOldLib/theirLib.h" 
#include "TheirNewLib/theirLib.h" 

Entonces, ¿hay una manera de saber lo que Xcode theirLib.h para incluir por objetivo?

Restricciones:
- los dos archivos de encabezado tienen el mismo nombre. Como último recurso, podría cambiarle el nombre a uno de ellos, pero preferiría evitarlo, ya que esto provocará un importante tirón de cabello en las otras plataformas.
- tener que cambiar el #include para agregar una referencia a la carpeta adjunta también es algo que preferiría evitar, porque tendría que hacerlo dos veces con una directiva de compilación condicional.
- Soy libre de modificar mi proyecto ya que de lo contrario me parece bien

Gracias por cualquier ayuda.

Respuesta

21

La parte clave de la respuesta es usar USE_HEADERMAP = NO como lo sugirió Chris en un comentario. Aquí están los detalles.

receta corto (comprobado en Xcode 3.2.2):

  1. agregar una configuración de generación personalizada de USE_HEADERMAP = NO para cada objetivo en cuestión. Aquí está cómo:
    1.1. Abra el panel de información del objetivo en el panel "Crear".
    1.2. Abra el menú emergente de acción en la esquina inferior izquierda de la ventana, seleccione "Agregar configuración definida por el usuario".
    1.3. En la línea recién agregada, configure la primera columna ("Configuración") en USE_HEADERMAP, y la segunda columna ("Valor") en NO.

  2. agregue la ruta de inclusión correcta a cada destino (configuraciones de compilación de destino "Rutas de búsqueda de encabezado"). En mi ejemplo, sería:
    2.1. agregue TheirOldLib para el objetivo "viejo"
    2.2.añadir TheirNewLib para "nuevo" objetivo

Paso 1 desactiva la función de mapa automática del cabezal de Xcode, a través del cual cualquier archivo de cabecera incluida en el proyecto que se accede a través de su nombre, cualquiera que sea su trayectoria real. Cuando dos encabezados tienen el mismo nombre, esta característica conduce a una ambigüedad irresoluble.

El paso 2 permite que el #include "theirLib.h" funcione sin calificar el nombre de ruta actual del archivo de encabezado.

Estos dos pasos juntos cumplen mis dos limitaciones.

Finalmente, USE_HEADERMAP es no documentado por Apple, por lo que puedo decir. Voy a llenar un informe de error para eso, ya que esta configuración es crucial en una serie de casos, como lo revela Google. Reportado como rdar: // 7840694. También en Radar abierto como http://openradar.appspot.com/radar?id=253401

+0

Esto funciona perfectamente. Gracias. El póster debería haber marcado esto como Respuesta. – SmallChess

+2

¿No debería en el paso 2. ser "Rutas de búsqueda de encabezado de usuario" en lugar de "Rutas de búsqueda de encabezado"? como usas #include "" y no #include <> – Olof

+0

, supongo que estás en lo cierto. 'Header Search Paths' funciona, pero' User Header Search Paths' debería ser mejor. –

0

¿Por qué no puedes simplemente usar diferentes rutas de inclusión en cada objetivo?

+2

Si tiene dos encabezados con el mismo nombre pero diferentes rutas, debe establecer USE_HEADERMAP = NO en una configuración de compilación personalizada en ambos destinos. – cdespinosa

+0

aseado. Supongo que nunca lo intenté. Es bueno ver que Mike Ferris todavía está luchando la buena batalla contra la usabilidad. –

+0

usando diferentes rutas de inclusión en cada destino no funciona: incluya archivos * en * Xcode siempre tiene acceso al proyecto sin ninguna ruta. Esta es la razón por la que surge el problema en primer lugar: sin un camino para desambiguar, parece que no hay forma de decirle a Xcode cuál es el archivo correcto para incluir. La sugerencia de Chris es deshabilitar esa característica, para revertir a un esquema de ruta de inclusión más convencional. Escribiré la respuesta en detalle. –

Cuestiones relacionadas