Разрешение LNK4098: конфликт библиотеки по умолчанию «MSVCRT» конфликтует с - PullRequest
193 голосов
/ 09 июня 2010

Это предупреждение:

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

- довольно распространенное предупреждение в Visual Studio. Я хотел бы понять точную причину этого и правильный способ (если вообще) справиться с этим.

Это происходит в отладочной сборке, скомпилированной с /MDd. Проект связан с такими вещами, как windows Version.dll и pdh.dll, которые сами связаны с MSVCRT.dll. Очевидно, у меня нет этих отладочных версий и я не могу их скомпилировать.

Итак, я добавил /NODEFAULTLIB:MSVCRT в командную строку компоновщика, и это действительно убрало предупреждение. Но что это на самом деле делает? И зачем это нужно?

Ответы [ 5 ]

248 голосов
/ 09 июня 2010

В vc \ lib есть 4 версии библиотек ссылок CRT:

  • libcmt.lib: библиотека статических ссылок CRT для сборки выпуска (/ MT)
  • libcmtd.lib: статическая библиотека ссылок CRT для отладочной сборки (/ MTd)
  • msvcrt.lib: библиотека импорта для релизной версии библиотеки CRT (/ MD)
  • msvcrtd.lib: importбиблиотека для отладочной DLL-версии CRT (/ MDd)

Посмотрите на параметры компоновщика, Project + Properties, Linker, Командная строка.Обратите внимание, что эти библиотеки не упоминаются здесь.Компоновщик автоматически определяет, какой ключ / M использовался компилятором и какой .lib должен быть связан через директиву комментария #pragma.Очень важно, что вы получите ужасные ошибки ссылок и трудно диагностировать ошибки времени выполнения, если существует несоответствие между параметром / M и .lib, с которым вы связываетесь.

Вы увидите сообщение об ошибке, которое вы цитировали, когдакомпоновщик должен указать как ссылку на msvcrt.lib , так и libcmt.lib.Что произойдет, если вы свяжете код, который был скомпилирован с / MT с кодом, который был связан с / MD.Может быть только одна версия CRT.

/ NODEFAULTLIB говорит компоновщику игнорировать директиву комментария #pragma, сгенерированную из скомпилированного кода / MT.Это может работать, хотя множество других ошибок компоновщика не является редкостью.Такие вещи, как errno , который является extern int в статической версии CRT, но макропрограммирован для функции в версии DLL.Многим другим это нравится.

Что ж, исправьте эту проблему правильным способом, найдите файл .obj или .lib, который вы связываете и который был скомпилирован с неверной опцией / M.Если у вас нет подсказки, то вы можете найти ее, выбрав .obj / .lib файлы для "/ MT"

Кстати: исполняемые файлы Windows (например, version.dll) имеют свою собственную версию CRT, чтобы получить свою работусделанный.Он расположен в c: \ windows \ system32, вы не можете надежно использовать его для своих собственных программ, его CRT-заголовки нигде не доступны.DLL-библиотека CRT, используемая вашей программой, имеет другое имя (например, msvcrt90.dll).

42 голосов
/ 11 апреля 2011

Это означает, что один из зависимых dll скомпилирован с другой библиотекой времени выполнения .

Проект -> Свойства -> C / C ++ -> Генерация кода -> Runtime Library

Просмотрите все библиотеки и убедитесь, что они скомпилированы одинаково.

Подробнее об этой ошибке в этой ссылке:

предупреждение LNK4098: defaultlib "LIBCD" конфликтует с использованием других библиотек

29 голосов
/ 18 декабря 2013

IMO эта ссылка из Йохай Тиммер была очень хорошей и актуальной, но больно читать.Я написал резюме.

Йохай, если вы когда-либо читали это, см. Примечание в конце.


Исходное сообщение читайте: предупреждение LNK4098: defaultlib«LIBCD» конфликтует с использованием других библиотек

Ошибка

ССЫЛКА: предупреждение LNK4098: defaultlib «LIBCD» конфликтует с использованием других библиотек;use / NODEFAULTLIB: библиотека

Значение

одна часть системы была скомпилирована для использования однопоточной стандартной библиотеки (libc) с отладочной информацией (libcd), которая статическисвязанный

, в то время как другая часть системы была скомпилирована для использования многопоточной стандартной библиотеки без отладочной информации, которая находится в DLL и использует динамическое связывание

Как разрешить

  • Игнорировать предупреждение, ведь это всего лишь предупреждение.Однако ваша программа теперь содержит несколько экземпляров одних и тех же функций.

  • Используйте параметр компоновщика / NODEFAULTLIB: lib.Это не полное решение, даже если вы можете заставить свою программу связываться таким образом, вы игнорируете предупреждающий знак: код был скомпилирован для разных сред, часть вашего кода может быть скомпилирована для однопоточной модели, в то время как другой кодмногопоточный.

  • [...] просмотрите все ваши библиотеки и убедитесь, что они имеют правильные настройки ссылок

InВ последнем случае, как упоминалось в оригинальном сообщении, могут возникнуть две общие проблемы:

  • У вас есть сторонняя библиотека, которая по-разному связана с вашим приложением.

  • В ваш код встроены другие директивы: обычно это MFC.Если какие-либо модули в вашей системе связаны с MFC, все ваши модули должны быть номинально связаны с одной и той же версией MFC.

В этих случаях убедитесь, что вы понимаете проблему и выбираете изРешения.


Примечание. Я хотел включить это резюме ссылки Йохая Тиммера в его собственный ответ, но, поскольку у некоторых людей возникли проблемы с просмотром исправлений должным образом, мне пришлось написать его в отдельном ответе.К сожалению

7 голосов
/ 01 июня 2012

Я получаю это каждый раз, когда хочу создать приложение в VC ++.

Щелкните правой кнопкой мыши проект, выберите «Свойства», затем в разделе «Свойства конфигурации |C / C ++ |Генерация кода », выберите« Многопоточная отладка (/ MTd) »для конфигурации отладки.

Обратите внимание, что это не меняет настройки для конфигурации выпуска - вам нужно перейти в то же место и выбрать«Многопоточный (/ MT)» для выпуска.

3 голосов
/ 24 августа 2017

Щелкните правой кнопкой мыши проект, выберите «Свойства», затем в «Свойства конфигурации | Линкер | Вход | Игнорировать конкретную библиотеку и написать msvcrtd.lib

...