Visual Studio 2010 的奇怪“警告 LNK4042”
我刚刚被 Visual Studio 2010 (C++) 的一些重要警告狠狠地打了一顿。
编译给出以下输出:
1 Debug\is.obj :警告 LNK4042:多次指定对象;额外内容被忽略
1 Debug\make.obj :警告 LNK4042:多次指定对象;额外内容被忽略
1 Debug\view.obj :警告 LNK4042:多次指定对象;额外内容被忽略
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)
(?is@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
解决方案中的层次结构也是如此(我总是将其设置为模仿“真实”文件夹结构)。
诊断输出:
Debug\is.obj
Debug\make.obj
Debug\view.obj
伴随着一条警告,表明 .obj
已被传递给链接器两次,并且其中一次将被忽略。
不再搜索:Visual 已经整齐地展平了我的文件夹层次结构,因此无法整齐地编译源代码。
目前,我只是想重命名文件,这应该可以解决问题......
但是有没有办法让 Visual Studio 不展平文件层次结构?
I've just been beaten (rather hardly) on the head by some non-trivial warning from Visual Studio 2010 (C++).
The compilation gave the following output:
1 Debug\is.obj : warning LNK4042: object specified more than once; extras ignored
1 Debug\make.obj : warning LNK4042: object specified more than once; extras ignored
1 Debug\view.obj : warning LNK4042: object specified more than once; extras ignored
1 identity.obj : error LNK2019: unresolved external symbolvoid __cdecl
(?view@identity@test@@YAXXZ) referenced in function
test::identity::view(void)void __cdecl test::identity::identity(void)
(?identity@0test@@YAXXZ)
1 identity.obj : error LNK2019: unresolved external symbolvoid __cdecl test::identity::make(void)
(?make@identity@test@@YAXXZ) referenced in functionvoid __cdecl test::identity::identity(void)
(?identity@0test@@YAXXZ)
1 range.obj : error LNK2019: unresolved external symbolvoid __cdecl test::range::is(void)
(?is@range@test@@YAXXZ) referenced in functionvoid __cdecl test::range::range(void)
(?range@0test@@YAXXZ)
Linker errors are always a pain to debug... but there were unresolved references, and so I checked... but the source is well-formed... and finally it hit me:
My folder hierarchy looks like so:
src/
identity/
is.cpp
make.cpp
view.cpp
range/
is.cpp
make.cpp
view.cpp
and so does the hierarchy in the Solution (I always set it up so that it mimicks the "real" folder structure).
And the diagnostic outputs:
Debug\is.obj
Debug\make.obj
Debug\view.obj
Along with a warning which says that the .obj
has been passed twice to the linker and that one will be ignored.
Search no more: Visual has neatly flatten my folder hierarchy, and therefore is unable to neatly compile the source.
At the moment, I am simply thinking of renaming the files, that should cover the issue...
... but is there a way to have Visual Studio NOT flatten the file hierarchy ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我有一个类似的问题,链接器警告LNK4042:多次指定对象;附加内容被忽略。就我而言,Visual Studio 尝试编译具有相同名称的头文件和源文件 -
MyClass.h
和MyClass.cpp
。发生这种情况是因为我将.cpp
文件重命名为.h
并且 Visual Studio 感到困惑。我通过查看 Debug 目录中的编译器日志注意到了这个问题。要解决此问题,只需从项目中删除.h
文件,然后再次添加即可。I had a similar problem with linker warning LNK4042: object specified more than once; extras ignored. In my case Visual Studio was trying to compile both header and source files with the same name -
MyClass.h
andMyClass.cpp
. It happened because I renamed.cpp
file to.h
and Visual Studio got confused. I noticed the problem by looking at the compiler logs in theDebug
directory. To resolve just remove.h
file from the project then add it again.只是想交叉发布我认为的答案,如果您打开整个项目的属性,并更改
C/C++ -> > 下的值。输出文件 -> “对象文件名”如下:
$(IntDir)/%(RelativeDir)/
在 VS 2010 下,我相信这将消除所有对象文件的歧义(因为我相信 Windows 不会让你在任何疯狂的情况是同一目录中有两个同名的文件)。另请查看详细信息 在这里。
Just wanted to cross post what I believe to be the answer, if you open the properties for the entire project, and the change the value under
C/C++ -> Output Files -> "Object File Name"
to be the following:$(IntDir)/%(RelativeDir)/
Under VS 2010, I believe this will disambiguate all of the object files (as I believe windows won't let you under any crazy circumstances have two files with the same names in the same directory). Please also check out the details here.
右键单击“解决方案资源管理器”窗口中的 .cpp 文件,依次选择“属性”、“C/C++”、“输出文件”、“对象文件名”设置。默认值为
$(IntDir)\
,这就是进行扁平化的操作。所有 .obj 文件都将进入 $(IntDir),即调试配置中的“Debug”目录。您可以更改设置,例如
$(IntDir)\is2.obj
。或者从一组中选择所有文件(使用 Shift+单击)并将设置更改为$(IntDir)\identity\
或者您可以更改 .cpp 文件名,以便 .obj 文件不存在不要互相覆盖。在两个目录中拥有完全相同名称的文件有点奇怪。
或者,您可以创建多个项目,例如为标识和范围中的文件创建 .lib 项目。例如,通常在 makefile 项目中完成。然而,除非您使用项目属性表,否则这确实会使管理编译和链接设置变得更加麻烦。
Right-click the .cpp file in the Solution Explorer window, Properties, C/C++, Output Files, Object File Name setting. The default is
$(IntDir)\
, that's what is doing the flattening. All the .obj file will go into $(IntDir), the "Debug" directory in the debug configuration.You can change the setting, say
$(IntDir)\is2.obj
. Or select all the files from one group (use Shift+Click) and change the setting to, say,$(IntDir)\identity\
Or you can change the .cpp filename so that .obj files don't overwrite each other. Having files with the exact same name in two directories is a bit odd.
Or you can create multiple projects, creating, say, .lib projects for the files in identity and range. Commonly done in makefile projects for example. That does however make managing the compile and link settings more of a hassle unless you use project property sheets.
右键单击头文件->属性-> ItemType(选择C/C++ 标头)。对 Cpp 文件执行相同操作,但选择 C/C++ 编译器(这对我有用)
Right click on header file -> Property -> ItemType (select C/C++ Header). Do the same with Cpp file but select C/C++ Compiler (it's work for me)
除了删除并创建新文件之外,您还可以更改编译/包含设置。
转到您的 project.vcxproj 文件,使用编辑器打开它,找到类似
行的 html。它应该类似于:
并
假设您的实现文件是 .cpp,您的声明是 .hpp。如果您有多个声明文件,请确保您的所有实现文件都列在第一部分之间,对于多个声明文件,请确保在第二部分中列出。
Alternatively to deleting and making a new file you can change the compile/include settings.
Go to your project.vcxproj file, open it with an editor, find the html like line
<ItemGroup>
.It should look something like:
and
Assuming your implementation files are .cpp and your declarations are .hpp. Make sure your all your implementation files are listed between the first section if you have more then one and likewise for the second section for multiple declaration files.
我在 stdafx.cpp 中遇到了这个问题。不知何故,stdafx.cpp 被重复,因此有第二个 StdAfx.cpp(注意不同的情况)。
删除 StdAfx.cpp 后,一切正常!
使用VS 2010。
I had this problem with stdafx.cpp. Somehow stdafx.cpp got duplicated, so there was a second StdAfx.cpp (mind the different case).
After I removed the StdAfx.cpp everything worked fine!
Using VS 2010.
我在 C/C++ 下使用 $(IntDir)\%(Directory)\ ->输出文件 -> “对象文件名”。
I use $(IntDir)\%(Directory)\ under C/C++ -> Output Files -> "Object File Name".
我曾经在同一个项目中拥有.c和.cpp文件,它们具有相同的文件名。这些文件位于各处的文件夹中,其他人提供的解决方案造成了混乱,文件夹地狱(就我而言)。即使发布版本也会覆盖调试版本!
一个好的(不完美)解决方案是使用 $(ParentName),但由于某些超出任何人掌握的原因,它已从 Visual Studio 的更高版本(2015+)中删除。
我现在成功使用的是:
$(IntDir)%(Filename)%(Extension).obj
至少将 .c 构建的目标文件与 .cpp 分开。
I used to have in the same project .c and .cpp files with the same filenames. The files were in folders all over the place and the solutions provided by others created a mess, and folder hell (in my case). Even Release builds would overwrite Debug builds!
A good (not perfect) solution would be to use $(ParentName), but for some reason beyond anyone's grasp it has been removed from later versions of Visual Studio (2015+).
What I use succesfully now is:
$(IntDir)%(Filename)%(Extension).obj
which at least separates .c built object files from .cpp.
我想指出
.h 文件
的ItemType
从C/C++ header
更改为的一个可能原因>C/C++编译器
:解决方案资源管理器
窗口中(这里是2019),右键单击项目名称,选择添加->添加新项目
;C++ File (.cpp)
模板,但在名称输入区域中输入something.h
,然后单击OK
添加它;something.h
文件包含在多个.cpp
文件中,您就会遇到LNK4042
警告。I'd like to point out one possible reason for why the
ItemType
of a.h file
would change fromC/C++ header
toC/C++ compiler
:Solution Explorer
window of VS (2019 here), right click the project name, chooseAdd -> New Item
;C++ File (.cpp)
template, but typesomething.h
in the name input area, then clickOK
to add it;LNK4042
warning if thesomething.h
file be included within more than one.cpp
files.我刚刚克服了类似的错误消息,并且通过以下过程解决了更多问题。症状:每次调用特定标头中定义的每个函数都会出现一个链接器错误,并且在标头中定义的每个函数的输出末尾都会出现一个链接器错误。
然后我记得当我最初创建此标头时,我不小心选择了“add->new item->c++ file”,虽然我将其命名为“whatever.h”,但由于我的操作不正确,Visual Studio 似乎将它们视为同一类型的文件。用于添加一个。检查构建输出日志使这一点显而易见。
解决方案(使用 VS Community 2019)
-- 当然会有错误---
这完全为我清理了它,使我摆脱了许多恼人的链接器错误,包括这个问题标题中的 LNK4042。
I just overcame a similar error message, and lots more with the procedure below. Symptom: one linker error for every invocation of every function defined in a particular header, plus one at the end of output for every function defined in the header.
Then I remembered that when I had originally created this header, I accidentally had selected "add->new item->c++ file" and though I named it 'whatever.h', it seems Visual Studio considered them both the same kinds of files because of the incorrect action I used to add one. Examining the build output logs made this obvious.
SOLUTION (Using VS Community 2019)
-- there of course will be errors---
This completely cleaned it up for me, relieving me of many irritating linker errors including LNK4042 from the title of this question.
我通过更改项目中的文件名解决了这个问题。有两个名为 main.c 和 main.cpp 的文件。我改变了其中之一并工作了。
I resolved it changing filenames in my project. There was two files named main.c and main.cpp. I changed one of them and worked.