visual-studio 解决 LNK4098:defaultlib 'MSVCRT' 与

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3007312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 12:05:49  来源:igfitidea点击:

Resolving LNK4098: defaultlib 'MSVCRT' conflicts with

visual-studiodlllinkerwarningsmsvcrt

提问by shoosh

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.

是 Visual Studio 中相当常见的警告。我想了解它的确切原因以及处理它的正确方法(如果有的话)。

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

这出现在调试版本中,使用/MDd. 该项目链接到诸如 windows 之类的东西,Version.dllpdh.dll这些东西本身又与MSVCRT.dll. 显然,我没有这些的调试版本,也无法编译它们。

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

所以我添加/NODEFAULTLIB:MSVCRT到链接器命令行,它实际上确实删除了警告。但这实际上有什么作用呢?为什么有必要?

回答by Hans Passant

There are 4 versions of the CRT link libraries present in vc\lib:

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

  • libcmt.lib: static CRT link library for a release build (/MT)
  • libcmtd.lib: static CRT link library for a debug build (/MTd)
  • msvcrt.lib: import library for the release DLL version of the CRT (/MD)
  • msvcrtd.lib: import library for the debug DLL version of the CRT (/MDd)
  • libcmt.lib:用于发布版本 (/MT) 的静态 CRT 链接库
  • libcmtd.lib:用于调试版本 (/MTd) 的静态 CRT 链接库
  • msvcrt.lib:CRT (/MD) 发行版 DLL 版本的导入库
  • msvcrtd.lib:CRT (/MDd) 调试 DLL 版本的导入库

Look at the linker options, Project + Properties, Linker, Command Line. Note how these libraries are not mentioned here. The linker automatically figures out what /M switch was used by the compiler and which .lib should be linked through a #pragma comment directive. Kinda important, you'd get horrible link errors and hard to diagnose runtime errors if there was a mismatch between the /M option and the .lib you link with.

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

You'll see the error message you quoted when the linker is told both to link to msvcrt.lib andlibcmt.lib. Which will happen if you link code that was compiled with /MT with code that was linked with /MD. There can be only one version of the CRT.

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

/NODEFAULTLIB tells the linker to ignore the #pragma comment directive that was generated from the /MT compiled code. This might work, although a slew of other linker errors is not uncommon. Things like errno, which is a extern int in the static CRT version but macro-ed to a function in the DLL version. Many others like that.

/NODEFAULTLIB 告诉链接器忽略从 /MT 编译代码生成的 #pragma 注释指令。这可能会奏效,尽管许多其他链接器错误并不少见。诸如errno之类的东西,它是静态 CRT 版本中的 extern int 但宏编辑为 DLL 版本中的函数。许多其他人都这样。

Well, fix this problem the Right Way, find the .obj or .lib file that you are linking that was compiled with the wrong /M option. If you have no clue then you could find it by grepping the .obj/.lib files for "/MT"

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

Btw: the Windows executables (like version.dll) have their own CRT version to get their job done. It is located in c:\windows\system32, you cannot reliably use it for your own programs, its CRT headers are not available anywhere. The CRT DLL used by your program has a different name (like msvcrt90.dll).

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

回答by Yochai Timmer

It means that one of the dependent dlls is compiled with a different run-time library.

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

Project -> Properties -> C/C++ -> Code Generation -> Runtime Library

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

Go over all the libraries and see that they are compiled in the same way.

浏览所有库并查看它们的编译方式相同。

More about this error in this link:

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

warning LNK4098: defaultlib "LIBCD" conflicts with use of other libs

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

回答by ForceMagic

IMO this linkfrom Yochai Timmerwas very good and relevant but painful to read. I wrote a summary.

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

Yochai, if you ever read this, please see the note at the end.

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



For the original post read : warning LNK4098: defaultlib "LIBCD" conflicts with use of other libs

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

Error

错误

LINK : warning LNK4098: defaultlib "LIBCD" conflicts with use of other libs; use /NODEFAULTLIB:library

链接:警告 LNK4098:defaultlib“LIBCD”与其他库的使用冲突;使用 /NODEFAULTLIB:library

Meaning

意义

one part of the system was compiled to use a single threaded standard (libc) library with debug information (libcd) which is statically linked

while another part of the system was compiled to use a multi-threaded standard library without debug information which resides in a DLL and uses dynamic linking

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

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

How to resolve

如何解决

  • Ignore the warning, after all it is only a warning. However, your program now contains multiple instances of the same functions.

  • Use the linker option /NODEFAULTLIB:lib. This is not a complete solution, even if you can get your program to link this way you are ignoring a warning sign: the code has been compiled for different environments, some of your code may be compiled for a single threaded model while other code is multi-threaded.

  • [...] trawl through all your libraries and ensure they have the correct link settings

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

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

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

In the latter, as it in mentioned in the original post, two common problems can arise :

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

  • You have a third party library which is linked differently to your application.

  • You have other directives embedded in your code: normally this is the MFC. If any modules in your system link against MFC all your modules must nominally link against the same version of MFC.

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

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

For those cases, ensure you understand the problem and decide among the solutions.

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



Note : I wanted to include that summary of Yochai Timmer's link into his own answer but since some people have trouble to review edits properly I had to write it in a separate answer. Sorry

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

回答by user1016736

I get this every time I want to create an application in VC++.

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

Right-click the project, select Properties then under 'Configuration properties | C/C++ | Code Generation', select "Multi-threaded Debug (/MTd)" for Debug configuration.

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

Note that this does not change the setting for your Release configuration - you'll need to go to the same location and select "Multi-threaded (/MT)" for Release.

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

回答by raehee

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

右键单击该项目,选择“属性”,然后在“配置属性 | 链接器 | 输入 | 忽略特定库并编写 msvcrtd.lib