C++ Visual Studio 2010 的奇怪“警告 LNK4042”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3695174/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Visual Studio 2010's strange "warning LNK4042"
提问by Matthieu M.
I've just been beaten (rather hardly) on the head by some non-trivial warning from Visual Studio 2010 (C++).
我刚刚被来自 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 test::identity::view(void)
(?view@identity@test@@YAXXZ) referenced in functionvoid __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)
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)
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.
伴随着一条警告,指出.obj
已传递给链接器两次,并且将忽略一次。
Search no more: Visual has neatly flatten my folder hierarchy, and therefore is unable to neatly compile the source.
不再搜索:Visual 已经整齐地扁平化我的文件夹层次结构,因此无法整齐地编译源代码。
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 ?
...但是有没有办法让 Visual Studio 不扁平化文件层次结构?
回答by Andrey Levichev
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
and MyClass.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 the Debug
directory. To resolve just remove .h
file from the project then add it again.
我在链接器警告LNK4042: 多次指定对象时遇到了类似的问题;演员被忽略。在我的情况下,Visual Studio 试图编译具有相同名称的头文件和源文件 -MyClass.h
和MyClass.cpp
. 发生这种情况是因为我将.cpp
文件重命名为.h
并且 Visual Studio 感到困惑。我通过查看Debug
目录中的编译器日志注意到了这个问题。要解决只需.h
从项目中删除文件然后再次添加它。
回答by M. Tibbits
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:
只是想交叉发布我认为是答案的内容,如果您打开整个项目的属性,并将C/C++ -> Output Files -> "Object File Name"
下面的值更改为以下内容:
$(IntDir)/%(RelativeDir)/
$(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.
在 VS 2010 下,我相信这将消除所有对象文件的歧义(因为我相信 Windows 不会让您在任何疯狂的情况下在同一目录中有两个同名的文件)。另请在此处查看详细信息。
回答by Hans Passant
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.
右键单击解决方案资源管理器窗口中的 .cpp 文件,属性,C/C++,输出文件,对象文件名设置。默认是$(IntDir)\
,这就是扁平化的作用。所有 .obj 文件都将进入 $(IntDir),即调试配置中的“Debug”目录。
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\
您可以更改设置,例如$(IntDir)\is2.obj
。或者从一组中选择所有文件(使用 Shift+单击)并将设置更改为,例如,$(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.
或者您可以更改 .cpp 文件名,以便 .obj 文件不会相互覆盖。在两个目录中拥有完全相同名称的文件有点奇怪。
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.
或者,您可以创建多个项目,例如为标识和范围中的文件创建 .lib 项目。例如,通常在 makefile 项目中完成。但是,除非您使用项目属性表,否则这确实会使管理编译和链接设置变得更加麻烦。
回答by Ph?m M?nh
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)
右键单击头文件 -> 属性 -> ItemType(选择 C/C++ Header)。对 Cpp 文件执行相同操作,但选择 C/C++ 编译器(它对我有用)
回答by Csimbi
I use $(IntDir)\%(Directory)\ under C/C++ -> Output Files -> "Object File Name".
我在 C/C++ -> 输出文件 -> “对象文件名”下使用 $(IntDir)\%(Directory)\。
回答by Knasterbax
I had this problem with stdafx.cpp. Somehow stdafx.cpp got duplicated, so there was a second StdAfx.cpp (mind the different case).
我在 stdafx.cpp 上遇到了这个问题。不知何故 stdafx.cpp 被复制了,所以有第二个 StdAfx.cpp (注意不同的情况)。
After I removed the StdAfx.cpp everything worked fine!
删除 StdAfx.cpp 后,一切正常!
Using VS 2010.
使用 VS 2010。
回答by user1222064
Alternatively to deleting and making a new file you can change the compile/include settings.
除了删除和创建新文件,您还可以更改编译/包含设置。
Go to your project.vcxprojfile, open it with an editor, find the html like line <ItemGroup>
.
转到您的project.vcxproj文件,用编辑器打开它,找到类似 line 的 html <ItemGroup>
。
It should look something like:
它应该看起来像:
<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>
and
和
<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`
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.
假设您的实现文件是 .cpp,而您的声明是 .hpp。如果您有多个声明文件,请确保您的所有实现文件都列在第一部分之间,对于多个声明文件的第二部分也是如此。
回答by Bill Kotsias
I used to have in the same project .cand .cppfiles 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 Releasebuilds would overwrite Debugbuilds!
我曾经在同一个项目中拥有相同文件名的.c和.cpp文件。这些文件到处都是文件夹,其他人提供的解决方案造成了混乱和文件夹地狱(就我而言)。即使是发布版本也会覆盖调试版本!
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+).
一个好的(不完美的)解决方案是使用 $(ParentName),但由于某些人无法理解的原因,它已从 Visual Studio (2015+) 的更高版本中删除。
What I use succesfully now is: $(IntDir)%(Filename)%(Extension).obj
我现在成功使用的是: $(IntDir)%(Filename)%(Extension).obj
which at least separates .cbuilt object files from .cpp.
它至少将.c构建的目标文件与.cpp分开。