Разрешение LNK4098: defaultlib 'MSVCRT' конфликтует с

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

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 в командную строку компоновщика и фактически удалил предупреждение. Но что это на самом деле? И зачем это нужно?

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

Проект → Свойства → C/С++ → Генерация кода → Библиотека времени выполнения

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

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

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

Ответ 3

ИМО эта ссылка от Yochai Timmer была очень хорошей и актуальной, но болезненной для чтения. Я написал резюме.

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


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

ошибка

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

Имея в виду

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

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

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

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

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

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

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

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

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

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


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

Ответ 4

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

Щелкните правой кнопкой мыши проект, выберите "Свойства", затем в разделе "Свойства конфигурации". C/С++ | Code Generation ', выберите "Multi-threaded Debug (/MTd)" для конфигурации Debug.

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

Ответ 5

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