2011-03-02 40 views
12

¿Cuál es el mejor método para incluir un archivo que tiene el mismo nombre en otra carpeta de directorios de inclusión adicionales?La biblioteca incluye rutas con el mismo nombre de encabezado

Ejemplo:

lib1/include/foo.h 
lib2/include/foo.h

donde tanto lib1/incluir y lib2/include se añaden en adicionales incluyen directorios.

Editar:

Las bibliotecas son de diferente SDK y todos los desarrolladores las instala en su propio lugar. Lo único que es seguro es que tanto las carpetas están en IDE adicionales incluyen caminos

método 1:

#include "../../lib1/include/foo.h

metodo2:

Añadir LIB1/include antes LIB2/incluir en las rutas de búsqueda y debido que se buscan en orden con:

#include "foo.h"

li b1/include/foo.h se incluirá

+1

Método 2 es malo porque la compilación del programa depende de un entorno (incluya el fin directorio) no en el código en sí Si alguien tuviera que reconstruir la configuración del proyecto, no será obvio que este problema esté presente, y mucho menos cuál sea la configuración adecuada. –

+0

@Mike Sé que estos no son los mejores métodos, pero son los únicos métodos que tengo en mente ahora. Como no me gustan ninguno de estos métodos, pedí mejores. – Felics

Respuesta

4

En primer lugar, esta respuesta supone que las protecciones incluidas para los dos encabezados son compatibles (es decir, no tienen los mismos símbolos).

Una cosa que puede hacer es crear enlaces en ubicaciones conocidas a los archivos de encabezado de interés, dando a los enlaces nombres propios. Por ejemplo, supongamos que sus dos bibliotecas están instaladas en $ LIB1PATH y $ LIB2PATH, que podrían tener diferentes valores en diferentes entornos de compilación. Por lo tanto, los encabezados que desea obtener están en $ LIB1PATH/include/foo.h y $ LIB2PATH/include/foo.h.

Podría ir de dos maneras con esto. Una es mediante la creación de enlaces directos. Esto podría tener este aspecto en el árbol de directorios de su proyecto:

$PROJDIR/ 
    include/ 
    lib_include/ 
     lib1_foo.h -> $LIB1PATH/include/foo.h 
     lib2_foo.h -> $LIB2PATH/include/foo.h 
    src/ 

Esto podría ser complicado si el código está en un repositorio, porque no se podía comprobar estos enlaces en; estarían equivocados en otros entornos. Además, si tienes muchos de estos enlaces y pocas bibliotecas, tendrías que volver a crearlos cuando lib1 o lib2 se muevan ... no genial. Puede solucionar este problema mediante la creación de enlaces en el directorio que contiene el directorio del proyecto:

$PROJDIR/ 
    include/ 
    lib_include/ 
     lib1_foo.h -> ../../lib1/include/foo.h 
     lib2_foo.h -> ../../lib2/include/foo.h 
    src/ 
lib1 -> $LIB1PATH/ 
lib2 -> $LIB2PATH/ 

En ambos casos, es necesario asegurarse de $PROJDIR/lib_include está en su ruta de inclusión. Además, solo necesita tener $LIB1PATH/include y $LIB2PATH/include en su ruta de inclusión si los dos encabezados foo.h extraen más encabezados de esos directorios. También podría poner los enlaces en include y deshacerse de lib_include, pero me gusta mantener estas cosas separadas.

5

Sólo puede hacer esto:

#include "lib1/include/foo.h" 
#include "lib2/include/foo.h" 

y asegúrese de que los directorios padre de ambos lib1 y lib2 están en la ruta de búsqueda para los incluye (pero no los propios subdirectorios include).

Tenga en cuenta que si ambas cabeceras utilizan el mismo símbolo como una guardia de incluir a continuación, este método no funcionará - que tendría que quitar la definición del símbolo de conflicto entre los dos incluye:

#include "lib1/include/foo.h" 
#undef FOO_H 
#include "lib2/include/foo.h" 
+0

Las bibliotecas son de diferentes SDK y cada desarrollador las instala en su propio lugar. Lo único que es seguro es que ambas carpetas están en las rutas de inclusión adicionales de IDE – Felics

+0

@Felics: Por eso es necesario evitar '#include" foo.h "'. ¿Estás diciendo que los nombres de los directorios en los que están instalados los SDK ('lib1' y' lib2' en este ejemplo) no son seguros? Si es así, su única solución es crear enlaces con nombres diferentes a los dos archivos de encabezado, y usar esos enlaces para llegar a los encabezados. Incluso eso podría no funcionar debido a la cuestión de incluir guardia que eznme menciona. –

+0

¿Por qué el voto abajo anónimo? Si el votante a la baja tiene una crítica válida, no dude en transmitirla y con gusto modificaré mi respuesta o la eliminaré en consecuencia. –

7
#include "lib1/include/foo.h" 
#include "lib2/include/foo.h" 

está bien como siempre que esta sea la ruta relativa real a esos encabezados y los guardias incluyen son diferentes. Por ejemplo, si ambos foo.h utilizar

#ifndef _foo_h_ 

entonces esto le dará algo que no desea (sólo se incluirá uno, pero no ambos y que uno depende de la orden de ejecución).

+0

+1: ¡buen punto sobre los guardias incluidos! –

+0

muchas gracias señor, y usted: ¡buen punto sobre los caminos de búsqueda! –

1

me gustaría incluir los archivos de un directorio sin ambigüedades que está en la lista -I (Es decir la ruta de acceso al directorio que contiene LIB1 y LIB2):

#include "lib1/include/foo.h" 
#include "lib2/include/foo.h" 

Por lo tanto no habrá ambigüedad porque el precompilador mirará lib1/include/foo.h dentro de su lista de directorios y eso no ocurre desde lib1/include/ o lib2/include/, sino solo desde el directorio principal.

Como dije antes: tenga cuidado con las protecciones, incluso si para un encabezado lib, el nombre debe incluir el nombre de lib para evitar tales confusiones.

4

Me pregunto que con las 4 respuestas y 1709 visitas en este momento nadie ha aconsejado una solución tan fácil y sencilla.

Puede incluir los archivos que desee, el único problema real con el que se encontrará es sobre los mismos encabezados de guardia. Por lo tanto, debe crear un encabezado que incluya los dos archivos de encabezado en conflicto. Vamos a llamarlo inc_foo_lib1_lib2.h. En este archivo, incluye el primer foo.h, luego, si el encabezado guard fue definido, defínalo, a continuación incluya el segundo foo.h.

Como ejemplo supongamos que el foo.h tienen un guardia de cabecera FOO_H_INCLUDED, entonces su inc_foo_lib1_lib2.h es el siguiente aspecto:

#include "lib1/foo.h" 
#ifdef FOO_H_INCLUDED 
#undef FOO_H_INCLUDED 
#else 
COMPILATION ERROR — the header guard was changed! 
#endif //FOO_H_INCLUDED 
#include "lib2/foo.h" 
Cuestiones relacionadas