262

This warning:

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

is a fairly common warning in Visual Studio. I'd like to understand the exact reason for it and the right way (if at all) to handle it.

This comes up in a debug build, compiled with /MDd. The project is linked to things like windows Version.dll and pdh.dll which themselves link with MSVCRT.dll. Obviously, I don't have the debug versions of these and can't compile them.

So I added /NODEFAULTLIB:MSVCRT to the linker command line and it actually did remove the warning. But what does this actually do? And why is it necessary?

4

5 回答 5

304

vc\lib 中存在 4 个版本的 CRT 链接库:

  • libcmt.lib:发布版本 (/MT) 的静态 CRT 链接库
  • libcmtd.lib:用于调试构建 (/MTd) 的静态 CRT 链接库
  • msvcrt.lib:CRT (/MD) 的发布 DLL 版本的导入库
  • msvcrtd.lib:CRT (/MDd) 的调试 DLL 版本的导入库

查看链接器选项,项目+属性,链接器,命令行。请注意这里没有提到这些库。链接器会自动确定编译器使用了哪个 /M 开关,以及应该通过 #pragma 注释指令链接哪个 .lib。有点重要,如果 /M 选项和链接的 .lib 不匹配,你会得到可怕的链接错误并且很难诊断运行时错误。

当告诉链接器同时链接到 msvcrt.liblibcmt.lib 时,您将看到您引用的错误消息。如果您将使用 /MT 编译的代码与使用 /MD 链接的代码链接起来,就会发生这种情况。CRT 只能有一个版本。

/NODEFAULTLIB 告诉链接器忽略从 /MT 编译代码生成的#pragma 注释指令。这可能会起作用,尽管大量其他链接器错误并不少见。像errno之类的东西,它是静态 CRT 版本中的 extern int ,但在 DLL 版本中是一个函数的宏。许多其他人都喜欢这样。

好吧,以正确的方式解决此问题,找到您要链接的使用错误 /M 选项编译的 .obj 或 .lib 文件。如果您不知道,那么您可以通过 grepping .obj/.lib 文件中的“/MT”来找到它

顺便说一句:Windows 可执行文件(如 version.dll)有自己的 CRT 版本来完成工作。它位于 c:\windows\system32,你不能可靠地将它用于你自己的程序,它的 CRT 头文件在任何地方都不可用。您的程序使用的 CRT DLL 具有不同的名称(如 msvcrt90.dll)。

于 2010-06-09T16:43:02.647 回答
54

这意味着其中一个依赖 dll 是使用不同的运行时库编译的。

项目 -> 属性 -> C/C++ -> 代码生成 -> 运行时库

查看所有库并查看它们是否以相同的方式编译。

此链接中有关此错误的更多信息:

警告 LNK4098:defaultlib "LIBCD" 与其他库的使用冲突

于 2011-04-11T12:30:57.050 回答
33

IMO来自Yochai Timmer的这个链接非常好且相关,但阅读起来很痛苦。我写了一个总结。

Yochai,如果你读过这篇文章,请看最后的注释。


对于原始帖子阅读:警告LNK4098:defaultlib“LIBCD”与使用其他库发生冲突

错误

LINK : 警告 LNK4098: defaultlib "LIBCD" 与其他库的使用冲突;使用 /NODEFAULTLIB:library

意义

系统的一部分被编译为使用带有静态链接的调试信息 (libcd) 的单线程标准 (libc) 库

而系统的另一部分被编译为使用没有调试信息的多线程标准库,它驻留在 DLL 中并使用动态链接

如何解决

  • 忽略警告,毕竟这只是一个警告。但是,您的程序现在包含相同函数的多个实例。

  • 使用链接器选项 /NODEFAULTLIB:lib。这不是一个完整的解决方案,即使您可以让您的程序以这种方式链接,您也忽略了一个警告信号:代码已针对不同的环境编译,您的某些代码可能针对单线程模型编译,而其他代码是多线程。

  • [...] 浏览所有库并确保它们具有正确的链接设置

在后者中,正如在原始帖子中提到的那样,可能会出现两个常见问题:

  • 您有一个第三方库,它与您的应用程序的链接方式不同。

  • 您的代码中嵌入了其他指令:通常这是 MFC。如果系统中的任何模块链接到 MFC,则所有模块名义上必须链接到相同版本的 MFC。

对于这些情况,请确保您了解问题并在解决方案中做出决定。


注意:我想将 Yochai Timmer 链接的摘要包含在他自己的答案中,但由于有些人无法正确审查编辑,我不得不将其写在单独的答案中。对不起

于 2013-12-18T05:13:35.903 回答
8

每次我想在 VC++ 中创建应用程序时都会得到这个。

右键单击项目,选择“属性”,然后在“配置属性 | C/C++ | Code Generation',Debug配置选择“Multi-threaded Debug (/MTd)”。

请注意,这不会更改发布配置的设置 - 您需要转到同一位置并为发布选择“多线程 (/MT)”。

于 2012-05-31T20:21:53.810 回答
6

Right-click the project, select Properties then under 'Configuration properties | Linker | Input | Ignore specific Library and write msvcrtd.lib

于 2017-08-24T07:33:30.963 回答