从Debug切换到Release配置时出现链接错误

11

你好,我有一个 VC++ 2008 项目,在 debug 模式下编译没有错误, 但是当我尝试在 release 模式下构建时,出现以下链接错误。

1>Linking...
1>LIBCMTD.lib(dbgheap.obj) : error LNK2005: __heap_alloc already defined in LIBCMT.lib(malloc.obj)
1>LIBCMTD.lib(dbgheap.obj) : error LNK2005: __recalloc already defined in LIBCMT.lib(recalloc.obj)
1>LIBCMTD.lib(dbgheap.obj) : error LNK2005: __msize already defined in LIBCMT.lib(msize.obj)
1>LIBCMTD.lib(malloc.obj) : error LNK2005: _V6_HeapAlloc already defined in LIBCMT.lib(malloc.obj)
1>LIBCMTD.lib(dbghook.obj) : error LNK2005: __crt_debugger_hook already defined in LIBCMT.lib(dbghook.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_pHeaderDefer already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: __get_sbh_threshold already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: __set_sbh_threshold already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: __set_amblksiz already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: __get_amblksiz already defined in LIBCMT.lib(sbheap.obj)......

如何修复它? 谢谢。

6个回答

24

你混合使用了不同版本的VS运行库 - 请确保你的项目和所有链接到的库的 "项目属性/C++/代码生成/运行库" 设置相同。


1
好的,不是“完全”一样的,例如如果调试使用/MTd,则发布应该使用/MT等,但调试不应该使用/MT。 - ildjarn
3
不,其中一个使用“/MTd” - 这是创建对“LIBCMTD”的依赖关系的原因。您还可以检查发布版本是否定义了“NDEBUG”而没有定义“_DEBUG”。 - Erik
1
@herzl shemuelian: 是的。也将其编译为发布版本。 - Erik
非常感谢您提供的解决方案。但是,您能否告诉我何时需要更改“项目属性/C++/代码生成/运行时库”以进行调试和发布时的MT,以及何时不需要这样做?我在C++方面相当幼稚 :(. @ildjarn - the_naive
哎呀,这节省了我不少时间。我正在处理一个仅以发布模式编译的非调试文件,所以我必须将调试构建设置为非调试。 - Joe Plante
显示剩余10条评论

7
我和你一样遇到了同样的问题。这个问题的原因是,连接器包含许多您看不见的库(例如,您将包括 windows.h,它包括 windef.h等...)。并且由于这些文件没有傻瓜式编写(#ifndef 缺失),连接器会尝试多次 #define 相同的内容 - 这就是问题所在。
我的解决办法是设置该字段: 项目属性-> 链接器-> 输入-> 忽略特定库
为 "libcmt.lib"。
这样,您的链接器将忽略默认情况下已包含的有问题的库,包括发布配置中的所有内容,一切都应该可以工作了... :-)
祝您愉快.. :-)
P.S. 如果您想避免这些链接器误解,请保持在 "所有配置" 而不是调试或发布配置中配置项目。此选项位于项目配置的左上角。

我会将 LIBCMTD.lib 添加到忽略列表中,因为您正在尝试构建一个发布版本。 - Anonymous

2

您正在链接一个在Debug配置中编译的.obj或.lib文件。最好的方法是确保该文件也在Release模式下进行构建。次优的方法是告诉链接器忽略链接到libcmtd.lib的请求。项目 + 属性,链接器,输入,忽略特定库 = libcmtd.lib。但只有在尽力获取.lib的Release版本后仍然无法获得时才这样做。


我使用了ignore libcmtd.lib,但是我看到其他链接错误:
LINK : 警告 LNK4098: 默认库'LIBCMT'与其他库的使用冲突;请使用 /NODEFAULTLIB:library 1>libcpmtd.lib(stdthrow.obj) : 错误 LNK2001: 未解析的外部符号__CrtDbgReportW 1>fifi++.lib(Field.obj) : 错误 LNK2001: 未解析的外部符号__CrtDbgReportW 1>fifi++.lib(Int32Field.obj) : 错误 LNK2001: 未解析的外部符号__CrtDbgReportW
- herzl shemuelian
1
这个 .lib 实际上使用了调试功能。你 真的 需要重新构建它,快捷方式是行不通的。 - Hans Passant

1
我遇到了类似的问题,与您包含的库是否以正确的结束状态构建有关。如果您在发布模式下构建程序并指向以调试模式编译的*.lib文件,则会出现符号不匹配错误。特别是如果您的程序在调试模式下构建良好或反之亦然。

这可能不完全是您的问题,但对于遇到与我一样的问题的人来说是有用的信息。


1
你可以删除预处理定义“DEBUG”来解决你的问题。

0

你可能已经在“Debug”配置中定义了所有链接信息。这意味着你需要重新定义它来适用于“Release”,或将其移动到“所有配置”中以便共享。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接