x32 - microsoft visual c++ 2013
La extraña "advertencia LNK4042" de Visual Studio 2010 (8)
Me acaban de derrotar (bastante difícilmente) en la cabeza por una advertencia no trivial de Visual Studio 2010 (C ++).
La compilació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 resolvervoid __cdecl test::identity::view(void)
(? View @ identity @ test @@ YAXXZ) al que se hace referencia en la funciónvoid __cdecl test::identity::identity(void)
( ? identity @ 0test @@ YAXXZ)
1 identity.obj: error LNK2019: símbolo externo sin resolvervoid __cdecl test::identity::make(void)
(? Make @ identity @ test @@ YAXXZ) al que se hace referencia en la funciónvoid __cdecl test::identity::identity(void)
( ? identity @ 0test @@ YAXXZ)
1 range.obj: error LNK2019: símbolo externo no resueltovoid __cdecl test::range::is(void)
(? Es @ range @ test @@ YAXXZ) al que se hace referencia en la funciónvoid __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 compilar 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?
Alternativamente, para eliminar y crear un archivo nuevo, puede cambiar la configuración de compilación / inclusión.
Vaya a su archivo project.vcxproj , ábralo con un editor, encuentre la línea similar a html <ItemGroup>
.
Debería verse algo así como:
<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>
y
<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`
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 declaración múltiple.
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 compilació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)
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 compilaciones de Release sobrescribirían las compilaciones de Debug !
Una buena (no perfecta) solución sería usar $ (ParentName), pero por alguna razón que no está al alcance 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 .
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 here .
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.
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 compilar 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 compilador en el directorio Debug
. Para resolver solo elimine el archivo .h
del proyecto y luego agréguelo nuevamente.
Yo uso $ (IntDir) /% (Directorio) / bajo C / C ++ -> Archivos de salida -> "Nombre de archivo de objeto".