8

Aquí es mi estructura de carpetas:VS2008: ¿Puedo construir un proyecto con 2 archivos CPP del mismo nombre en diferentes carpetas?

/ 
| 
-- program.cpp 
-- utility.h 
-- utility.cpp 
| 
-- module/ 
    | 
    -- utility.h 
    -- utility.cpp 

// Note that I have two files named utility.h and two named utility.cpp 

En la construcción del proyecto, aparece un error de enlace (LNK2028: símbolo sin resolver y así sucesivamente ...) diciendo que algunos símbolos no están definidos. He confirmado que todos los símbolos están definidos y que todas las funciones declaradas tienen una definición correspondiente.

Tengo la sensación de que al compilar mi proyecto, los archivos utility.cpp de ambas carpetas se compilan en el mismo utility.obj en la carpeta de salida. Como resultado, uno sobrescribe al otro.

  1. ¿Este comportamiento es esperado?
  2. ¿Cómo construyo un archivo binario C++ que tiene dos archivos con el mismo nombre (aunque en carpetas diferentes)?
+0

lo que está buscando son los espacios de nombres –

+4

@fuzzy: Esto no tiene nada que ver con los espacios de nombres. Solo uno de los 2 archivos .obj se está arrastrando al paso de enlace. –

+1

@fuzzy: digamos que la primera 'utility.cpp' que se compila define todo bajo el espacio de nombres' foo_ns' y la segunda 'utilty.cpp' que se compila compila todo bajo el espacio de nombres' bar_ns', el compilador sobrescribe 'utility.obj' cuando compilando el segundo 'utility.cpp' ... para el momento en que el enlazador entra en acción, solo' bar_ns' está disponible en el archivo .obj. –

Respuesta

12

Haga clic derecho en tanto/o bien archivos .cpp>properties>C/C++>Output Files>Object File Name> definir un nombre personalizado. p.ej. si ambos archivos se llaman MyFile.cpp en la carpeta A y otro en la carpeta B, puede establecer que la salida sea AMyFile y BMyFile.

Alternativamente, también puede usar una macro para prefijar los nombres de los objetos con el nombre de la carpeta principal inmediata (es decir, usando $(IntDir)\$(SafeParentName)$(SafeInputName)). Si esto no es suficiente (por ejemplo, tiene A/B/MyFile.cpp y C/B/MyFile.cpp) y no le molesta que algunos archivos de objetos llenen su árbol fuente, también puede usar $(InputDir)\ que colocará los archivos del objeto en la misma carpeta que el archivo fuente.

los archivos cpp se compilarán en dos archivos de objetos diferentes ...

¡diviértase!

Actualización para VS2010: Hay una solución mejor en VS2010, compruébalo here. Gracias a n1ckcomment

Por cierto, si los contenidos tienen el mismo nombre, ¿los separa utilizando diferentes espacios de nombres?

namespace A { // in folder A 
    class CMyFile {}; 
}; 

namespace B{ // in folder B 
    class CMyFile {}; 
}; 

// client.cpp 
#include "A/MyFile.h" 
#include "B/MyFile.h" 
int main() { 
    A::CMyFile aMyFile; 
    B::CMyFile bMyFile; 
    return 0; 
} 

No sé si es importante, pero es sin duda más clara a humano: D

+0

Esta es la solución, pero ten en cuenta que, por algún motivo, tiene diferentes nombres para el archivo .cpp y el archivo .obj ralentiza drásticamente el ciclo de compilación/enlace. No tengo idea de por qué. –

+0

Esto * debería * funcionar y * debería * ser la solución, pero no funcionó para mí. VS crearía ambos archivos .obj pero trataría de vincularlos en solo uno de ellos. –

+0

Lo llevo atrás: volver a cargar la solución parecía hacer que esta técnica funcionara (como debería). +1. VS está siendo sensible para mí esta mañana por alguna razón. –

2

Usted podría intentar agregar otro proyecto para su solución, que construirá un archivo estático mudule.lib de .cpp.h, a continuación, vincular su proyecto principal de su módulo con que lib. Debería hacer que VS envíe archivos .obj en un directorio separado, y usted debería poder enlazar sin problemas.

0

Quizás las bibliotecas (estáticas o dinámicas) ayuden con su caso. Pero aún tendrá problemas si hay símbolos públicos con el mismo nombre, como en el ejecutable u otra biblioteca.

0

No conozco la cadena de compilación VS.

Sin embargo, cada .cpp se compila primero en un archivo .obj. Los pasos de vinculación los fusionan.

Es muy común poner todos los archivos .obj en el mismo directorio. Entonces, como suponía, al compilar el segundo, borra el primero. Por lo tanto, algunos símbolos faltan durante la compilación.

Probablemente haya una opción (de nuevo, no trabajo con VS) para dejar el .obj en el mismo directorio que el archivo .cpp. El inconveniente es un poco de basura en el árbol de código fuente.

Mi opinión personal sería refactorizar.

1

¿Realmente QUIERES dos archivos diferentes pero del mismo nombre en el mismo proyecto?

+4

Claro. Los 'utility.h' y' utility.cpp' en la subcarpeta agregan funcionalidad específica a la característica implementada en esa carpeta. –

+4

A menudo no tiene otra opción si incluye otras utilidades en su compilación. –

1

La cosa más fácil que funciona bien es poner los .OBJs en conflicto en diferentes subcarpetas (He utilizado esta técnica con 2003 y 2008) en base a los directorios fuente.

Por ejemplo: "\ Debug \ gui /"

Para src \ GUI \ conjunto utils.cpp "Nombre de objeto File" para y para src \ database \ utils.cpp otra vez en" \. Debug \ database/".

Mientras lo hago de forma manual cada vez que veo un conflicto, me imagino que escribir un script que actualice el proyecto para cada archivo .cpp (o solo para los conflictivos) sería una tarea bastante trivial.

Cuestiones relacionadas