提问人:Matthieu M. 提问时间:9/12/2010 最后编辑:James McNellisMatthieu M. 更新时间:5/25/2022 访问量:47131
Visual Studio 2010 奇怪的“警告LNK4042”
Visual Studio 2010's strange "warning LNK4042"
问:
我刚刚被Visual Studio 2010(C++)的一些重要警告打了(相当严重)。
编译给出了以下输出:
1 Debug\is.obj:警告 LNK4042:多次指定对象;忽略的额外内容
1 Debug\make.obj : warning LNK4042: object specified than once;extras ignored
1 Debug\view.obj : warning LNK4042: object specified than once;忽略的额外内容
1 Identity.obj:错误 LNK2019:函数 (?identity@0test@@YAXXZ) 中引用的未解析的外部符号 (?view@identity@test@@YAXXZ) 1 identity.obj:错误 LNK2019:函数 (?identity@0test@@YAXXZ) 中引用的未解析的外部符号 (?make@identity@test@@YAXXZ) 1 range.obj:错误 LNK2019:函数 (?range@0test@@YAXXZ) 中引用的未解析的外部符号 (?is@range@test@@YAXXZ)void __cdecl test::identity::view(void)
void __cdecl test::identity::identity(void)
void __cdecl test::identity::make(void)
void __cdecl test::identity::identity(void)
void __cdecl test::range::is(void)
void __cdecl test::range::range(void)
链接器错误总是调试起来很痛苦...但是有未解决的参考资料,所以我检查了......但来源是格式良好的......最后它击中了我:
我的文件夹层次结构如下所示:
src/
identity/
is.cpp
make.cpp
view.cpp
range/
is.cpp
make.cpp
view.cpp
解决方案中的层次结构也是如此(我总是对其进行设置,使其模仿“真实”文件夹结构)。
诊断输出:
Debug\is.obj
Debug\make.obj
Debug\view.obj
以及一个警告,指出已将 传递给链接器两次,并且将忽略其中一次。.obj
不再搜索:Visual 整齐地扁平化了我的文件夹层次结构,因此无法整齐地编译源代码。
目前,我只是在考虑重命名文件,这应该涵盖了这个问题......
...但是有没有办法让Visual Studio不扁平化文件层次结构?
答:
右键单击“解决方案资源管理器”窗口、“属性”、“C/C++”、“输出文件”、“对象文件名”设置中的 .cpp 文件。默认值是 ,这就是进行扁平化的原因。所有 .obj 文件都将进入 $(IntDir),即调试配置中的“Debug”目录。$(IntDir)\
您可以更改设置,比如 .或者从一组中选择所有文件(使用 Shift+Click),然后将设置更改为,$(IntDir)\is2.obj
$(IntDir)\identity\
或者,您可以更改 .cpp 文件名,以便 .obj 文件不会相互覆盖。在两个目录中拥有完全相同名称的文件有点奇怪。
或者,您可以创建多个项目,例如为 identity 和 range 中的文件创建 .lib 项目。例如,通常在 makefile 项目中完成。但是,除非使用项目属性表,否则管理编译和链接设置会更加麻烦。
评论
$(IntDir)
只是想交叉发布我认为是答案的东西,如果你打开整个项目的属性,并将下面的值更改为以下内容:C/C++ -> Output Files -> "Object File Name"
$(IntDir)/%(RelativeDir)/
在 VS 2010 下,我相信这将消除所有目标文件的歧义(因为我相信 Windows 不会让您在任何疯狂的情况下在同一目录中拥有两个同名的文件)。请在此处查看详细信息。
评论
cl.exe
我在链接器警告LNK4042遇到了类似的问题:多次指定对象; extras 被忽略。就我而言,Visual Studio 试图编译具有相同名称的头文件和源文件 - 和 .发生这种情况是因为我将文件重命名为 并且 Visual Studio 感到困惑。我通过查看目录中的编译器日志注意到了这个问题。要解决此问题,只需从项目中删除文件,然后再次添加它。MyClass.h
MyClass.cpp
.cpp
.h
Debug
.h
评论
foo.h
<ClCompile Include="foo.h" />
CLInclude
我在stdafx.cpp上遇到了这个问题。不知何故,stdafx.cpp 被复制了,所以有第二个 StdAfx.cpp(注意不同的情况)。
在我删除了StdAfx.cpp后,一切正常!
使用 VS 2010。
评论
或者,除了删除和创建新文件外,还可以更改编译/包含设置。
转到您的项目.vcxproj文件,使用编辑器打开它,找到htmllike行。<ItemGroup>
它应该看起来像这样:
<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>
和
<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`
假设您的实现文件是.cpp的,您的声明是 .hpp。如果有多个声明文件,请确保在第一部分之间列出所有实现文件,对于多个声明文件,请确保在第二部分之间列出所有实现文件。
我在 C/C++ -> 输出文件 -> “对象文件名” 下使用 $(IntDir)\%(Directory)\。
评论
右键单击头文件 -> 属性 -> ItemType(选择 C/C++ Header)。对 Cpp 文件执行相同的操作,但选择 C/C++ 编译器(它对我有用)
评论
我曾经在同一个项目中拥有具有相同文件名的 .c 和 .cpp 文件。这些文件到处都是文件夹,其他人提供的解决方案造成了混乱,文件夹地狱(在我的情况下)。即使是发布版本也会覆盖调试版本!
一个好的(不完美的)解决方案是使用 $(ParentName),但由于某种任何人都无法理解的原因,它已从 Visual Studio (2015+) 的更高版本中删除。
我现在成功使用的是: $(IntDir)%(文件名)%(扩展名).obj
这至少将 .c 构建的目标文件与.cpp分开。
我想指出一个可能的原因,为什么 a 会从 :ItemType
.h file
C/C++ header
C/C++ compiler
- 在 VS(此处为 2019)的窗口中,右键单击项目名称,选择
Solution Explorer
Add -> New Item
; - 选择模板,但在名称输入区域输入,然后单击添加;
C++ File (.cpp)
something.h
OK
- 然后,如果文件包含在多个文件中,则会遇到警告。
LNK4042
something.h
.cpp
我刚刚克服了类似的错误消息,以及以下过程的更多内容。症状:每次调用特定标头中定义的每个函数时都会出现一个链接器错误,对于标头中定义的每个函数,输出末尾会出现一个链接器错误。
然后我想起了当我最初创建此标头时,我不小心选择了“add->new item->c++ file”,尽管我将其命名为“whatever.h”,但似乎 Visual Studio 认为它们都是同一种文件,因为我使用了不正确的操作来添加一个。检查生成输出日志使这一点显而易见。
解决方案(使用 VS Community 2019)
- 首先备份项目(为了安全起见)。
- 右键单击有问题的头文件,然后选择“从项目中排除”(这不会删除它们;VS 项目只会忽略它们)。
- 对匹配的 .c 或 .cpp 文件执行相同的操作。
- 在项目上执行 Build->Clean
- 对项目执行生成>重建 --当然会有错误---
- 右键单击“头文件->添加->现有项”,然后选择 .h 文件
- 右键单击“源文件”->“添加”->现有项,选择 .c 或 .cpp 文件
- 对项目执行 Build-Rebuild >Rebuild。
这为我彻底清理了它,减轻了我许多令人恼火的链接器错误,包括从这个问题的标题中LNK4042。
我解决了它,在我的项目中更改文件名。有两个名为 main.c 和 main.cpp 的文件。我换了其中一个并工作了。
评论