【问题标题】:What is causing VS2013 error LNK2005: __xi_a already defined in MSVCRT.lib(cinitexe.obj)?是什么导致 VS2013 错误 LNK2005: __xi_a 已在 MSVCRT.lib(cinitexe.obj) 中定义?
【发布时间】:2014-01-22 00:18:46
【问题描述】:

我昨天构建的解决方案。今天除了 .hpp.cpp 文件什么都没改变之后,它没有。

来自 Visual Studio 2013 的完整错误文本(使用 2013 年 11 月的 CTP):

Error   1   error LNK2005: __xi_a already defined in MSVCRT.lib(cinitexe.obj)   C:\Users\drtwox\dev\repos\game\trunk\engine\game\LIBCMT.lib(crt0init.obj)   game
Error   2   error LNK2005: __xi_z already defined in MSVCRT.lib(cinitexe.obj)   C:\Users\drtwox\dev\repos\game\trunk\engine\game\LIBCMT.lib(crt0init.obj)   game
Error   3   error LNK2005: __xc_a already defined in MSVCRT.lib(cinitexe.obj)   C:\Users\drtwox\dev\repos\game\trunk\engine\game\LIBCMT.lib(crt0init.obj)   game
Error   4   error LNK2005: __xc_z already defined in MSVCRT.lib(cinitexe.obj)   C:\Users\drtwox\dev\repos\game\trunk\engine\game\LIBCMT.lib(crt0init.obj)   game
Error   7   error LNK1169: one or more multiply defined symbols found   C:\Users\drtwox\dev\repos\game\trunk\engine\build\x64\Test\game.exe 1   1   game

就像戳眼睛一样有用......

This answerthis similar question 说:

您正在混合使用 /MD 编译的代码(使用 DLL 版本的 CRT)与使用 /MT 编译的代码(使用静态 CRT 库)。 那不行,所有源代码文件必须用相同的编译 环境。假设您使用的是用 /MD 预编译的库, 几乎总是正确的设置,你必须编译你自己的代码 这个设置也是。

我已经检查(并重新检查)解决方案中的所有项目仍在使用相同的运行时库; Multi-threaded DLL 用于发布,Multi-threaded Debug DLL 用于调试。为了确定,我已经完成了完整的解决方案重建。

Subversion 日志显示包含所有 3rd 方库的“外部”目录自 2013-12-04 以来未修改;一个月前。我检查了它们的配置并重建了它们。

Subversion 日志还显示,从昨天开始,只有现有的 .hpp.cpp 文件被修改过。没有添加新的库,没有新的外部头文件#included,也没有更改项目配置。在 7 个文件中有超过 200 行更改和新的代码。

可能是什么问题?

更新:来自编译器的日志:http://pastebin.com/aHJ5Xi2V

解决方案:问题不是 /MT /MD 编译器标志不正确,而是 GLEW 库和缺少 #define GLEW_STATIC。我将 GLEW 项目设置更改为使用 /Zl(省略默认库名称),如下所述:http://msdn.microsoft.com/en-us/library/f1tbxcxh.aspx

【问题讨论】:

  • "...在只更改 .hpp 和 .cpp 文件之后..." 我肯定我并不是唯一一个对这些更改感兴趣的人。 Visual C++ 允许通过#pragma comment 将链接命令修改为在编译源代码时 的项目。完全可以想象,您要忽略的看似无关的更改之一通过以前未遇到的标头引入了这样一个指令。
  • @WhozCraig,在整个解决方案的任何地方都没有使用#pragma。 #included 没有新的外部标头。我会在问题中提到很多。
  • 毫无疑问,两个运行时正在被链接。如果不更改项目配置,其他唯一可能的原因是不正确的 pragma cmets(不是您的,也不是其他人的)或非常肮脏的构建,而您说您已经考虑到了这一点。
  • @WhozCraig,我没有添加任何新的#include,但我已经移动了一些#include。我对 GLEW(#included 标头之一)之前引起问题的记忆模糊......你给了我一些调查!
  • GLEW 的发布版本配置为链接到 libcmt.lib 作为默认库 - 至少 GLEW 源代码分发中的 MSVC 10 项目是这样设置的。我不知道为什么以前不会出现问题,但是链接器的工作方式可能有些神秘,它们处理目标文件输入的顺序以及它们碰巧遇到引用的时间会影响它们查找外部名称的方式。

标签: c++ visual-studio visual-studio-2013


【解决方案1】:

某些东西导致两个运行时都被链接。

首先尝试清理(手动)您的项目创建的所有 .obj 和 .lib 文件并重新构建它。

如果这没有帮助,请在 IDE 中设置链接器的 /VERBOSE 标志(“Linker | General | Show Progress” = “Display all progress messages (/VERBOSE)”)。

然后看输出;在 IDE 中,它将位于名为 <project-name>.log 的文件中的构建输出目录中。

您将看到搜索每个库的位置以及导致搜索库的目标文件。


更新:

日志输出显示正在搜索LIBCMT.lib,原因是一个或多个正在处理的对象文件(可能是库中的对象文件)中的DEFAULTLIB 指令。

但是,我并不清楚日志输出中哪个输入负责 - 我认为是 glew32s.lib(其中的 glew.obj 对象)。

请参阅this SO answer,了解查找哪些.obj/.lib 文件具有DEFAULTLIB 指令的方法。

您可能会在项目属性中设置/NODEFAULTLIB:libcmt.lib 选项(“忽略特定默认库”)。

【讨论】:

  • 日志长达3562行!我到底在寻找什么?我已经在这里上传了pastebin.com/aHJ5Xi2V
  • 感谢您的帮助。 GLEW 导致了问题。
猜你喜欢
  • 2010-09-25
  • 1970-01-01
  • 2013-01-06
  • 2011-02-13
  • 2012-04-25
  • 1970-01-01
  • 2015-04-13
  • 2014-12-21
  • 2015-08-10
相关资源
最近更新 更多