Visual Studio 2010的奇怪"警告LNK4042"

Mat*_* M. 76 c++ visual-studio-2010 visual-studio visual-c++ visual-c++-2010

我刚刚被Visual Studio 2010(C++)发出的一些非平凡的警告殴打(而不是很难).

编译给出了以下输出:

1 Debug\is.obj:警告LNK4042:对象指定多次; 附加项忽略
1 Debug\make.obj:警告LNK4042:对象指定多次; extras忽略
1 Debug\view.obj:警告LNK4042:对象指定多次; extras忽略
1 identity.obj:错误LNK2019:未解析的外部符号void __cdecl test::identity::view(void)(?view @ identity @ test @@ YAXXZ)在函数中引用void __cdecl test::identity::identity(void)(?identity @ 0test @@ YAXXZ)
1 identity.obj:错误LNK2019:未解析的外部符号void __cdecl test::identity::make(void)(?make @ identity @ test @@ YAXXZ)在函数中引用void __cdecl test::identity::identity(void)(?identity @ 0test @@ YAXXZ)
1 range.obj:错误LNK2019:未解析的外部符号void __cdecl test::range::is(void)(?是@ range @ test @@ YAXXZ)在函数中引用void __cdecl test::range::range(void)(?range @ 0test @@ YAXXZ)

链接器错误总是很难调试...但是有未解决的引用,所以我检查了......但是源代码是格式良好的......最后它击中了我:

我的文件夹层次结构如下:

src/
  identity/
    is.cpp
    make.cpp
    view.cpp
  range/
    is.cpp
    make.cpp
    view.cpp
Run Code Online (Sandbox Code Playgroud)

解决方案中的层次结构也是如此(我总是将其设置为模仿"真正的"文件夹结构).

并且诊断输出:

Debug\is.obj
Debug\make.obj
Debug\view.obj
Run Code Online (Sandbox Code Playgroud)

除了警告,表示.obj已经两次传递给链接器,并且将忽略该链接.

不再搜索:Visual整齐地压缩了我的文件夹层次结构,因此无法整齐地编译源代码.

目前,我只是想重命名文件,这应该涵盖这个问题......

...但有没有办法让Visual Studio不展平文件层次结构?

小智 132

链接器警告LNK4042:对象指定了多次,我遇到了类似的问题; 演员忽略.在我的情况下,Visual Studio试图编译具有相同名称的头文件和源文件 - MyClass.hMyClass.cpp.之所以发生这种情况是因为我将.cpp文件重命名为.hVisual Studio而感到困惑.我通过查看Debug目录中的编译器日志来注意到这个问题.要解决只是.h从项目中删除文件,然后再次添加.

  • 或者,您可以右键单击解决方案资源管理器中的`foo.h`文件,并将"项类型"设置为"C/C++标头"而不是"C/C++编译器". (30认同)
  • 谢谢发帖!旧的删除文件并添加回来例程也为我做了伎俩.我真的开始在这个墙上撞到我的头. (2认同)
  • 感谢@AndreyLevichev-此回复也为我解决了问题。在项目文件中很清楚.h文件位于“ ClCompile”组而不是“ ClInclude”组中 (2认同)
  • @Yaur-或者更好的是,将其更改为`CLInclude`条目 (2认同)

M. *_*its 96

只是想交叉发布我认为是答案的内容,如果您打开整个项目的属性,并将值更改C/C++ -> Output Files -> "Object File Name"为以下内容:

$(IntDir)/%(RelativeDir)/

在VS 2010下,我相信这将消除所有目标文件的歧义(因为我相信Windows不会让你在任何疯狂的情况下在同一目录中有两个具有相同名称的文件).请在这里查看详细信息.

  • 只是添加:似乎%(RelativeDir)不会剥离任何../ ..(不是它应该,但似乎没有任何替代)你的路径所以你可能不得不添加"假"目录让你的文件在"正确"的目录中构建.例如,我有$(IntDir)/ a/a /%(RelativeDir)/只是因为它可以在$(IntDir)中构建,因为我的.cpp的路径中有两个../(路径是相对于$(ProjectDir) ), 我认为).还要注意%(RelativeDir)是一个%而$(IntDir)是一个$(答案是正确的,只是通过快速读取,这个事实可能会被遗漏). (7认同)
  • 嗯......我想知道为什么默认情况下没有设置.好吧,我想我只是将它添加到每个项目中(如果没有此修复,几乎没有任何编译) (2认同)

Han*_*ant 8

右键单击"解决方案资源管理器"窗口中的.cpp文件,"属性","C/C++","输出文件","对象文件名"设置.默认是$(IntDir)\,这就是做扁平化的内容.所有.obj文件都将进入$(IntDir),调试配置中的"Debug"目录.

你可以更改设置$(IntDir)\is2.obj.或者从一个组中选择所有文件(使用Shift +单击)并将设置更改为,例如,$(IntDir)\identity\

或者您可以更改.cpp文件名,以便.obj文件不会互相覆盖.在两个目录中具有完全相同名称的文件有点奇怪.

或者,您可以创建多个项目,为身份和范围中的文件创建.lib项目.例如,通常在makefile项目中完成.但是,除非您使用项目属性表,否则这会使编译和链接设置更加麻烦.


小智 5

右键单击头文件 - > Property - > ItemType(选择C/C++ Header).对Cpp文件执行相同操作但选择C/C++ COmpiler(这对我有用)