Разрешение LNK4098: конфликт библиотеки по умолчанию "MSVCRT" конфликтует с
Это предупреждение:
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
в командной строке компоновщика, и он действительно удалил предупреждение. Но что это на самом деле делает? И зачем это нужно?
6 ответов
В 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, Командная строка. Обратите внимание, что эти библиотеки не упоминаются здесь. Компоновщик автоматически определяет, какой ключ /M использовался компилятором и какой.lib должен быть связан через директиву комментария #pragma. Очень важно, что вы получите ужасные ошибки ссылок и трудно диагностировать ошибки времени выполнения, если существует несоответствие между параметром /M и.lib, с которым вы связываетесь.
Вы увидите сообщение об ошибке, которое вы процитировали, когда компоновщик получит указание на ссылку на msvcrt.lib и libcmt.lib. Что произойдет, если вы свяжете код, который был скомпилирован с /MT с кодом, который был связан с /MD. Может быть только одна версия ЭЛТ.
/ 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).
Это означает, что один из зависимых dll скомпилирован с другой библиотекой времени выполнения.
Проект -> Свойства -> C/C++ -> Генерация кода -> Библиотека времени выполнения
Просмотрите все библиотеки и убедитесь, что они скомпилированы одинаково.
Подробнее об этой ошибке в этой ссылке:
предупреждение LNK4098: defaultlib "LIBCD" конфликтует с использованием других библиотек
ИМО, эта ссылка от Yochai Timmer была очень хорошей и актуальной, но было больно читать. Я написал резюме.
Йохай, если ты когда-нибудь прочитаешь это, пожалуйста, посмотри записку в конце.
Для оригинального сообщения читать: предупреждение LNK4098: defaultlib "LIBCD" конфликтует с использованием других библиотек
ошибка
ССЫЛКА: предупреждение LNK4098: defaultlib "LIBCD" конфликтует с использованием других библиотек; использовать /NODEFAULTLIB: библиотека
Имея в виду
одна часть системы была скомпилирована для использования однопоточной стандартной библиотеки (libc) с отладочной информацией (libcd), которая статически связана
в то время как другая часть системы была скомпилирована для использования многопоточной стандартной библиотеки без отладочной информации, которая находится в DLL и использует динамическое связывание
Как решить
Не обращайте внимания на предупреждение, ведь это всего лишь предупреждение. Однако ваша программа теперь содержит несколько экземпляров одних и тех же функций.
Используйте параметр компоновщика /NODEFAULTLIB:lib. Это не полное решение, даже если вы можете заставить свою программу связываться таким образом, вы игнорируете предупреждающий знак: код был скомпилирован для разных сред, часть вашего кода может быть скомпилирована для однопоточной модели, в то время как другой код многопоточный.
[...] просмотрите все ваши библиотеки и убедитесь, что они имеют правильные настройки ссылок
В последнем, как это упоминалось в оригинальном сообщении, могут возникнуть две общие проблемы:
У вас есть сторонняя библиотека, которая по-разному связана с вашим приложением.
В ваш код встроены другие директивы: обычно это MFC. Если какие-либо модули в вашей системе связаны с MFC, все ваши модули должны быть номинально связаны с одной и той же версией MFC.
В этих случаях убедитесь, что вы понимаете проблему и выбираете решение.
Примечание: я хотел включить это краткое изложение ссылки Йохая Тиммера в его собственный ответ, но, поскольку у некоторых людей возникают проблемы с корректным рассмотрением изменений, мне пришлось написать это в отдельном ответе. сожалею
Я получаю это каждый раз, когда хочу создать приложение на VC++.
Щелкните правой кнопкой мыши по проекту, выберите "Свойства", затем в разделе "Свойства конфигурации | C/C++ | Генерация кода ", выберите" Многопоточная отладка (/MTd)"для конфигурации отладки.
Обратите внимание, что это не меняет настройки для вашей конфигурации выпуска - вам нужно перейти в то же место и выбрать "Многопоточность (/MT)" для выпуска.
Щелкните правой кнопкой мыши по проекту, выберите "Свойства", затем в разделе "Свойства конфигурации | Линкер | Вход | Проигнорируйте определенную Библиотеку и напишите msvcrtd.lib
Это предупреждение было исправлено для меня, когда ни одна библиотека в проекте не была включена дважды. В моем случае это было в исходном файле с#pragma comment
и на странице свойств проекта: Компоновщик -> Ввод -> Дополнительные зависимости.