LNK4098 해결 : defaultlib 'MSVCRT'가


216

이 경고 :

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts
  with use of other libs; use /NODEFAULTLIB:library

Visual Studio에서 상당히 일반적인 경고입니다. 나는 그 이유와 그것을 처리하는 올바른 방법을 이해하고 싶습니다.

이것은로 컴파일 된 디버그 빌드로 나타납니다 /MDd. 이 프로젝트는 창과 같은 것들과 연결되어 Version.dll있으며 pdh.dll그 자체는와 연결되어 MSVCRT.dll있습니다. 분명히, 나는 이것들의 디버그 버전이 없으며 컴파일 할 수 없습니다.

/NODEFAULTLIB:MSVCRT링커 명령 줄에 추가 하여 실제로 경고를 제거했습니다. 그러나 이것이 실제로 무엇을합니까? 왜 필요한가요?

답변:


273

vc \ lib에는 4 가지 버전의 CRT 링크 라이브러리가 있습니다.

  • libcmt.lib : 릴리스 빌드 (/ MT) 용 정적 CRT 링크 라이브러리
  • libcmtd.lib : 디버그 빌드 (/ MTd)를위한 정적 CRT 링크 라이브러리
  • msvcrt.lib : 릴리스 DLL 버전의 CRT (/ MD) 용 가져 오기 라이브러리
  • msvcrtd.lib : 디버그 DLL 버전의 CRT (/ MDd) 용 가져 오기 라이브러리

링커 옵션, 프로젝트 + 속성, 링커, 명령 줄을보십시오. 이러한 라이브러리가 여기에 언급되지 않은 방법에 유의하십시오. 링커는 컴파일러에서 사용한 / M 스위치와 #pragma comment 지시문을 통해 어떤 .lib를 연결해야하는지 자동으로 파악합니다. 중요한 것은 / M 옵션과 링크 한 .lib가 일치하지 않으면 끔찍한 링크 오류가 발생하고 런타임 오류를 진단하기가 어렵다는 것입니다.

링커에 msvcrt.lib libcmt.lib 에 연결하라는 메시지가 표시되면 인용 한 오류 메시지가 표시됩니다 . / MT로 컴파일 된 코드를 / MD와 연결된 코드와 연결하면 이런 일이 발생합니다. CRT 버전은 하나만있을 수 있습니다.

/ NODEFAULTLIB는 링커에게 / MT 컴파일 된 코드에서 생성 된 #pragma comment 지시문을 무시하도록 지시합니다. 다른 링커 오류가 드물지 않지만 이것은 효과적 일 수 있습니다. 정적 CRT 버전에서는 extern int이지만 DLL 버전에서는 함수로 매크로 된 errno 와 같은 것들 . 많은 사람들이 그렇게 좋아합니다.

글쎄,이 문제를 올바른 방법으로 수정하고 잘못된 / M 옵션으로 컴파일 된 링크하고있는 .obj 또는 .lib 파일을 찾으십시오. 실마리가 없다면 "/ MT"에 대한 .obj / .lib 파일을 grepping하여 찾을 수 있습니다.

Btw : version.dll과 같은 Windows 실행 파일에는 작업을 수행하기위한 자체 CRT 버전이 있습니다. c : \ windows \ system32에 있으며 자신의 프로그램에 안정적으로 사용할 수 없으며 CRT 헤더를 사용할 수 없습니다. 프로그램이 사용하는 CRT DLL의 이름이 다릅니다 (예 : msvcrt90.dll).


2
이 게시물 덕분에 / MDd를 계속 사용하고있는 .lib를 계속 찾았으며 결국 하나를 찾았습니다! 감사합니다, +1
ceztko

64
방금 잘못된 CRT 라이브러리를 가져 오는 라이브러리를 추적하는 법을 배운 트릭 /verbose:lib은 추가 링커 옵션 을 추가 하는 것입니다. .lib 파일이로드 된 순서를 보여
주어

1
한스, 얼마나 위험 해? 이를 고칠 수 없다면 (공급 업체로부터 컴파일 된 lib를 얻음) 어떤 결과를 겪을 수 있습니까?
Ivan Nikitin

3
@obmarg '주석이 유용하다는 것을 알았지 만 msdn.microsoft.com/en-us/library/aa267384(v=vs.60).aspx 를 찾을 때까지 자세한 출력을 사용하는 방법을 아직 확실하지 않았습니다. 링크 문제와 관련된 모든 런타임 라이브러리 만 알려주십시오. 그런 다음 충돌하는 런타임 라이브러리로 컴파일 된 링크 입력을 파악해야합니다.
buzz3791

4
@ buzz3791은 / verbose : lib 대신 / verbose를 사용합니다. 표시되는 정보에는 라이브러리 검색 프로세스가 포함되며 각 라이브러리 및 객체 이름 (전체 경로 포함), 라이브러리에서 분석되는 심볼 및 심볼을 참조하는 객체 목록이 나열됩니다. / verbose는 충돌을 일으키는 나쁜 사람을 찾는 데 필요한 모든 정보를 표시 할 수 있습니다.
Yang Kui

46

종속 dll 중 하나가 다른 런타임 라이브러리로 컴파일되었음을 의미합니다 .

프로젝트-> 속성-> C / C ++-> 코드 생성-> 런타임 라이브러리

모든 라이브러리를 살펴보고 동일한 방식으로 컴파일되었는지 확인하십시오.

이 링크에서이 오류에 대한 추가 정보 :

경고 LNK4098 : defaultlib "LIBCD"가 다른 라이브러리 사용과 충돌


이것이 오류의 원인이었습니다! 팁 고마워.
rkachach

1
이것은 경험이 적은 프로그래머에게 가장 적합한 답변입니다.
meolic

32

IMO 이 링크 에서 Yochai 티 메르는 읽기 아주 좋은 및 관련 그러나 고통이었다. 나는 요약을 썼다.

Yochai,이 글을 읽었다면 마지막에있는 메모를 참조하십시오.


원본 게시물 읽기 : 경고 LNK4098 : defaultlib "LIBCD"가 다른 라이브러리 사용과 충돌

오류

LINK : 경고 LNK4098 : defaultlib "LIBCD"가 다른 라이브러리 사용과 충돌합니다. / NODEFAULTLIB : library를 사용하십시오.

의미

시스템의 한 부분은 정적으로 링크 된 디버그 정보 (libcd)와 함께 단일 스레드 표준 (libc) 라이브러리를 사용하도록 컴파일되었습니다.

시스템의 다른 부분은 DLL에 상주하고 동적 링크를 사용하는 디버그 정보없이 멀티 스레드 표준 라이브러리를 사용하도록 컴파일되었습니다.

해결하는 방법

  • 결국 경고 일 뿐이므로 경고를 무시하십시오. 그러나 프로그램에는 이제 동일한 기능의 여러 인스턴스가 포함됩니다.

  • 링커 옵션 / NODEFAULTLIB : lib를 사용하십시오. 프로그램이 이런 방식으로 링크하도록 경고 표시를 무시할 수있는 경우에도이 방법은 완벽한 해결책이 아닙니다. 멀티 스레드.

  • [...] 모든 라이브러리를 탐색하고 올바른 링크 설정이 있는지 확인하십시오.

후자는 원래 게시물에서 언급했듯이 두 가지 일반적인 문제가 발생할 수 있습니다.

  • 응용 프로그램과 다르게 연결된 타사 라이브러리가 있습니다.

  • 코드에 다른 지시문이 포함되어 있습니다. 일반적으로 MFC입니다. 시스템의 모듈이 MFC와 연결되어 있으면 모든 모듈이 동일한 버전의 MFC와 연결되어야합니다.

이러한 경우 문제점을 이해하고 솔루션을 결정하십시오.


참고 : Yochai Timmer의 링크에 대한 요약을 자신의 답변에 포함하고 싶었지만 일부 사람들은 편집 내용을 제대로 검토하는 데 문제가 있으므로 별도의 답변으로 작성해야했습니다. 죄송합니다


7

VC ++로 응용 프로그램을 만들 때마다 이것을 얻습니다.

프로젝트를 마우스 오른쪽 버튼으로 클릭하고 속성을 선택한 다음 '구성 속성 | C / C ++ | Code Generation '에서 디버그 구성에 대해 "멀티 스레드 디버그 (/ MTd)"를 선택하십시오.

이것은 릴리스 구성 설정을 변경하지 않습니다. 동일한 위치로 이동하여 릴리스에 대해 "멀티 스레드 (/ MT)"를 선택해야합니다.


4

프로젝트를 마우스 오른쪽 버튼으로 클릭하고 속성을 선택한 다음 '구성 속성 | 링커 | 입력 | 특정 라이브러리를 무시하고 msvcrtd.lib를 작성하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.