La extraña “advertencia LNK4042” de Visual Studio 2010

Me acaban de derrotar (bastante difícilmente) en la cabeza por una advertencia no trivial de Visual Studio 2010 (C ++).

La comstackción dio el siguiente resultado:

1 Debug \ is.obj: advertencia LNK4042: objeto especificado más de una vez; extras ignorados
1 Debug \ make.obj: advertencia LNK4042: objeto especificado más de una vez; extras ignorados
1 Debug \ view.obj: advertencia LNK4042: objeto especificado más de una vez; extras ignorados
1 identity.obj: error LNK2019: símbolo externo sin resolver void __cdecl test::identity::view(void) (? View @ identity @ test @@ YAXXZ) al que se hace referencia en la función void __cdecl test::identity::identity(void) ( ? identity @ 0test @@ YAXXZ)
1 identity.obj: error LNK2019: símbolo externo sin resolver void __cdecl test::identity::make(void) (? Make @ identity @ test @@ YAXXZ) al que se hace referencia en la función void __cdecl test::identity::identity(void) ( ? identity @ 0test @@ YAXXZ)
1 range.obj: error LNK2019: símbolo externo no resuelto void __cdecl test::range::is(void) (? Es @ range @ test @@ YAXXZ) al que se hace referencia en la función void __cdecl test::range::range(void) ( ? range @ 0test @@ YAXXZ)

Los errores del enlazador siempre son difíciles de depurar … pero había referencias no resueltas, así que lo comprobé … pero la fuente está bien formada … y finalmente me di cuenta:

La jerarquía de mi carpeta se ve así:

 src/ identity/ is.cpp make.cpp view.cpp range/ is.cpp make.cpp view.cpp 

y también lo hace la jerarquía en la Solución (siempre lo configuro para que imite la estructura de carpetas “reales”).

Y las salidas de diagnóstico:

 Debug\is.obj Debug\make.obj Debug\view.obj 

Junto con una advertencia que dice que el .obj se ha pasado dos veces al vinculador y que se ignorará.

No busque más: Visual ha aplanado cuidadosamente la jerarquía de mi carpeta y, por lo tanto, no puede comstackr cuidadosamente la fuente.

Por el momento, simplemente estoy pensando en cambiar el nombre de los archivos, eso debería cubrir el problema …

… pero ¿hay alguna manera de que Visual Studio NO aplana la jerarquía de archivos?

Solo quería publicar lo que creo que es la respuesta, si abre las propiedades para todo el proyecto y cambia el valor en C/C++ -> Output Files -> "Object File Name" para que sea el siguiente:

$ (IntDir) /% (RelativeDir) /

Bajo VS 2010, creo que esto eliminará la ambigüedad de todos los archivos de objetos (ya que creo que Windows no le permitirá bajo ninguna circunstancia loca tener dos archivos con los mismos nombres en el mismo directorio). Por favor, revisa los detalles aquí .

Tuve un problema similar con la advertencia del vinculador LNK4042: objeto especificado más de una vez; extras ignorados En mi caso, Visual Studio intentaba comstackr tanto el encabezado como los archivos de origen con el mismo nombre: MyClass.h MyClass.cpp . Sucedió porque .cpp nombre del archivo .cpp a .h y Visual Studio se confundió. Noté el problema mirando los registros del comstackdor en el directorio Debug . Para resolver solo elimine el archivo .h del proyecto y luego agréguelo nuevamente.

Haga clic con el botón derecho en el archivo .cpp en la ventana del Explorador de soluciones, propiedades, C / C ++, archivos de salida, configuración del nombre del archivo de objeto. El valor predeterminado es $(IntDir)\ , eso es lo que hace el aplanamiento. Todo el archivo .obj irá a $ (IntDir), el directorio “Debug” en la configuración de depuración.

Puede cambiar la configuración, digamos $(IntDir)\is2.obj . O seleccione todos los archivos de un grupo (use Shift + Click) y cambie la configuración a, por ejemplo, $(IntDir)\identity\

O puede cambiar el nombre de archivo .cpp para que los archivos .obj no se sobrescriban entre sí. Tener archivos con exactamente el mismo nombre en dos directorios es un poco extraño.

O puede crear proyectos múltiples, creando, por ejemplo, proyectos .lib para los archivos en identidad y rango. Comúnmente hecho en proyectos de archivos MAKE, por ejemplo. Sin embargo, eso hace que manejar la configuración de comstackción y enlace sea más complicado a menos que use hojas de propiedades del proyecto.

Haga clic con el botón derecho en el archivo de encabezado -> Propiedad -> Tipo de elemento (seleccione Encabezado C / C ++). Haga lo mismo con el archivo Cpp pero seleccione C / C ++ COmpiler (me funciona)

Tuve este problema con stdafx.cpp. De alguna manera stdafx.cpp se duplicó, por lo que hubo un segundo StdAfx.cpp (tenga en cuenta el caso diferente).

Después de eliminar el StdAfx.cpp, todo funcionó bien.

Usando VS 2010.

Yo uso $ (IntDir) \% (Directorio) \ bajo C / C ++ -> Archivos de salida -> “Nombre de archivo de objeto”.

Alternativamente, para eliminar y crear un archivo nuevo, puede cambiar la configuración de comstackción / inclusión.

Vaya a su archivo project.vcxproj , ábralo con un editor, encuentre la línea similar a html .

Debería verse algo así como:

    

y

   ` 

Suponiendo que sus archivos de implementación son .cpp y sus declaraciones son .hpp. Asegúrese de que todos sus archivos de implementación figuren en la lista entre la primera sección si tiene más de uno y, asimismo, para la segunda sección para archivos de statement múltiple.

Solía ​​tener en el mismo proyecto archivos .c y .cpp con los mismos nombres de archivo . Los archivos estaban en carpetas por todos lados y las soluciones proporcionadas por otros crearon un caos y una carpeta infernal (en mi caso). ¡Incluso las comstackciones de Release sobrescribirían las comstackciones de Debug !

Una buena (no perfecta) solución sería usar $ (ParentName), pero por alguna razón que no está al scope de todos, se ha eliminado de las versiones posteriores de Visual Studio (2015+).

Lo que uso con éxito ahora es: $ (IntDir)% (Filename)% (Extension) .obj

que al menos separa archivos de objetos construidos .c de .cpp .