Visual Studio 2010의 이상한 “경고 LNK4042” LNK2019 : unresolved external

저는 Visual Studio 2010 (C ++)의 사소하지 않은 경고로 머리가 거의 맞지 않았습니다.

컴파일 결과는 다음과 같습니다.

1 Debug \ is.obj : 경고 LNK4042 : 개체가 두 번 이상 지정되었습니다. 추가 무시 됨
1 Debug \ make.obj : 경고 LNK4042 : 개체가 두 번 이상 지정되었습니다. 추가 항목 무시 됨
1 Debug \ view.obj : 경고 LNK4042 : 개체가 두 번 이상 지정되었습니다. extras ignore
1 identity.obj : error LNK2019 : unresolved external symbol void __cdecl
test::identity::view(void)
(? view @ identity @ test @@ YAXXZ) referenced in function void __cdecl test::identity::identity(void)(? identity @ 0test @@ YAXXZ)
1 identity.obj : error LNK2019 : unresolved external symbol void __cdecl test::identity::make(void)(? make @ identity @ test @@ YAXXZ) 함수에서 참조 됨 void __cdecl test::identity::identity(void)(? identity @ 0test @@ YAXXZ)
1 range.obj : 오류 LNK2019 : void __cdecl test::range::is(void)함수 void __cdecl test::range::range(void)(? range @ 0test 에서 참조되는 해결되지 않은 외부 기호 (? is @ range @ test @@ YAXXZ) @@ YAXXZ)

링커 오류는 항상 디버그하기가 어렵지만 해결되지 않은 참조가 있었기 때문에 확인했습니다 …하지만 소스가 잘 구성되어 있습니다.

내 폴더 계층 구조는 다음과 같습니다.

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

솔루션의 계층도 마찬가지입니다 (저는 항상 “실제”폴더 구조를 모방하도록 설정했습니다).

그리고 진단 출력 :

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

.obj링커에 두 번 전달되었으며 무시 된다는 경고와 함께 .

더 이상 검색 할 필요 없음 : Visual은 내 폴더 계층 구조를 깔끔하게 정리하여 소스를 깔끔하게 컴파일 할 수 없습니다.

지금은 파일 이름을 바꾸는 것만으로 문제를 해결할 수 있습니다.

…하지만 Visual Studio가 파일 계층 구조를 평면화하지 않도록하는 방법이 있습니까?



답변

전체 프로젝트의 속성을 열고 값을 C/C++ -> Output Files -> "Object File Name"다음 과 같이 변경하면 대답이라고 생각되는 내용을 교차 게시하고 싶었습니다 .

$ (IntDir) / % (RelativeDir) /

VS 2010에서 나는 이것이 모든 개체 파일을 명확하게 할 것이라고 믿습니다 (창이 어떤 미친 상황에서도 같은 디렉토리에 같은 이름을 가진 두 개의 파일을 가질 수 없다고 믿기 때문에). 여기 에서 자세한 내용도 확인 하십시오 .


답변

링커 경고 LNK4042 와 비슷한 문제가 발생했습니다 . 개체가 두 번 이상 지정되었습니다. 추가 항목은 무시 됩니다. 내 경우에는 Visual Studio에서 같은 이름을 가진 두 헤더 및 소스 파일을 컴파일하려고했다 – MyClass.hMyClass.cpp. .cpp파일 이름을로 바꾸고 .hVisual Studio가 혼란스러워서 발생했습니다. Debug디렉토리 의 컴파일러 로그를보고 문제를 발견했습니다 . 해결하려면 .h프로젝트에서 파일을 제거한 다음 다시 추가하십시오.


답변

솔루션 탐색기 창, 속성, C / C ++, 출력 파일, 개체 파일 이름 설정에서 .cpp 파일을 마우스 오른쪽 단추로 클릭합니다. 기본값은 $(IntDir)\입니다. 이것이 병합을 수행하는 것입니다. 모든 .obj 파일은 디버그 구성의 “Debug”디렉토리 인 $ (IntDir)로 이동합니다.

설정을 변경할 수 있습니다 $(IntDir)\is2.obj. 또는 한 그룹에서 모든 파일을 선택하고 (Shift + 클릭 사용) 설정을 다음과 같이 변경합니다.$(IntDir)\identity\

또는 .obj 파일이 서로 덮어 쓰지 않도록 .cpp 파일 이름을 변경할 수 있습니다. 두 디렉토리에 정확히 같은 이름의 파일을 갖는 것은 약간 이상합니다.

또는 ID 및 범위의 파일에 대해 .lib 프로젝트를 만드는 등 여러 프로젝트를 만들 수 있습니다. 예를 들어 일반적으로 메이크 파일 프로젝트에서 수행됩니다. 그러나 프로젝트 속성 시트를 사용하지 않는 한 컴파일 및 링크 설정을 관리하는 것이 더 번거 롭습니다.


답변

헤더 파일-> 속성-> 항목 유형을 마우스 오른쪽 버튼으로 클릭합니다 ( C / C ++ 헤더 선택 ). Cpp 파일과 동일하게 수행하지만 C / C ++ 컴파일러를 선택하십시오 (나에게 적합합니다)


답변

C / C ++-> 출력 파일-> “개체 파일 이름”에서 $ (IntDir) \ % (Directory) \를 사용합니다.


답변

새 파일을 삭제하고 만드는 대신 컴파일 / 포함 설정을 변경할 수 있습니다.

project.vcxproj 파일로 이동하여 편집기로 열고 html과 같은 줄을 찾으십시오 <ItemGroup>.

다음과 같이 표시되어야합니다.

<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>

<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`

구현 파일이 .cpp이고 선언이 .hpp라고 가정합니다. 모든 구현 파일이 하나 이상있는 경우 첫 번째 섹션 사이에 나열되고 여러 선언 파일의 두 번째 섹션에 대해서도 마찬가지로 나열되는지 확인하십시오.


답변

stdafx.cpp 에서이 문제가 발생했습니다. 어떻게 든 stdafx.cpp가 복제되었으므로 두 번째 StdAfx.cpp가 있습니다 (다른 경우에 유의하십시오).

StdAfx.cpp를 제거한 후 모든 것이 잘 작동했습니다!

VS 2010 사용.