Una advertencia no trivial de Visual Studio 2010 (C ++) me ha golpeado en la cabeza (bastante difícilmente).
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 no resueltovoid __cdecl test::identity::view(void)
(? view @ identity @ test @@ YAXXZ) referenciado en la funciónvoid __cdecl test::identity::identity(void)
(? identity @ 0test @@ YAXXZ)
1 identity.obj: error LNK2019: símbolo externo no resueltovoid __cdecl test::identity::make(void)
(? make @ identity @ test @@ YAXXZ) referenciado 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)
(? is @ range @ test @@ YAXXZ) referenciado en la funciónvoid __cdecl test::range::range(void)
(? range @ 0test @@ YAXXZ)
Los errores del vinculador son siempre difíciles de depurar ... pero había referencias sin resolver, así que verifiqué ... pero la fuente está bien formada ... y finalmente me di cuenta:
Mi jerarquía de carpetas 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 la configuro para que imite la estructura de carpetas "real").
Y las salidas de diagnóstico:
Debug\is.obj
Debug\make.obj
Debug\view.obj
Junto con una advertencia que dice que .obj
se ha pasado dos veces al enlazador y que se ignorará.
No busque más: Visual ha aplanado perfectamente la jerarquía de mi carpeta y, por lo tanto, no puede compilar perfectamente el código 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 apile la jerarquía de archivos?
fuente
Respuestas:
Solo quería publicar lo que creo que es la respuesta, si abre las propiedades para todo el proyecto y cambia el valor
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 objeto (ya que creo que Windows no le permitirá bajo ninguna circunstancia loca tener dos archivos con los mismos nombres en el mismo directorio). Consulte también los detalles aquí .
fuente
cl.exe
en CLI?Tuve un problema similar con la advertencia del enlazador LNK4042: objeto especificado más de una vez; extras ignorados . En mi caso, Visual Studio estaba intentando compilar los archivos fuente y de encabezado con el mismo nombre,
MyClass.h
yMyClass.cpp
. Sucedió porque cambié el nombre del.cpp
archivo a.h
y Visual Studio se confundió. Noté el problema al mirar los registros del compilador en elDebug
directorio. Para resolverlo, simplemente elimine el.h
archivo del proyecto y luego agréguelo nuevamente.fuente
foo.h
archivo en el explorador de soluciones y establecer "Tipo de elemento" en "Encabezado C / C ++" en lugar de "Compilador C / C ++".CLInclude
entradaHaga 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 de nombre de 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, por ejemplo
$(IntDir)\is2.obj
. O seleccione todos los archivos de un grupo (use Shift + Click) y cambie la configuración a, digamos,$(IntDir)\identity\
O puede cambiar el nombre del 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 varios proyectos, creando, digamos, proyectos .lib para los archivos en identidad y rango. Se hace comúnmente en proyectos de archivos MAKE, por ejemplo. Sin embargo, eso hace que administrar la configuración de compilación y enlace sea más complicado a menos que utilice hojas de propiedades del proyecto.
fuente
$(IntDir)
por archivo en una hoja de propiedades? Sé que puede configurarlo para todo el proyecto en una hoja de propiedades, pero no sé si puede configurarlo en función de la ruta del archivo que se está compilando. (Supongo que no, pero soy un novato de MSBuild completo)Haga clic derecho en el archivo de encabezado -> Propiedad -> ItemType (seleccione Encabezado C / C ++ ). Haga lo mismo con el archivo Cpp pero seleccione C / C ++ Compiler (es un trabajo para mí)
fuente
Yo uso $ (IntDir) \% (Directory) \ en C / C ++ -> Archivos de salida -> "Nombre de archivo de objeto".
fuente
Alternativamente a eliminar y crear un nuevo archivo, puede cambiar la configuración de compilación / inclusión.
Vaya a su archivo project.vcxproj , ábralo con un editor, busque la línea html como
<ItemGroup>
.Debería verse algo 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 estén enumerados entre la primera sección si tiene más de uno e igualmente para la segunda sección para varios archivos de declaración.
fuente
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 StdAfx.cpp, ¡todo funcionó bien!
Usando VS 2010.
fuente
Yo solía tener en el mismo proyecto .c y Cpp archivos con los mismos nombres de archivo . Los archivos estaban en carpetas por todas partes y las soluciones proporcionadas por otros crearon un desastre y un infierno de carpetas (en mi caso). ¡Incluso las versiones de lanzamiento sobrescriben las versiones de depuración !
Una buena solución (no perfecta) sería usar $ (ParentName), pero por alguna razón fuera del alcance de cualquiera, se ha eliminado de versiones posteriores de Visual Studio (2015+).
Lo que uso con éxito ahora es: $ (IntDir)% (Nombre de archivo)% (Extensión) .obj
que al menos separa los archivos de objeto .c construidos de .cpp .
fuente