82

我刚刚被来自 Visual Studio 2010 (C++) 的一些重要警告打得头破血流。

编译给出了以下输出:

1 Debug\is.obj : 警告 LNK4042:对象指定了不止一次;附加被忽略
1 Debug\make.obj : 警告 LNK4042: 对象指定了不止一次;额外被忽略
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:在函数(?range@0test void __cdecl test::range::is(void)) 中引用的未解析的外部符号 (?is@range@test@@YAXXZ) void __cdecl test::range::range(void)@@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 不展平文件层次结构?

4

10 回答 10

155

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

于 2011-06-13T17:11:55.890 回答
100

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.

于 2010-09-16T23:29:49.303 回答
8

右键单击头文件 -> 属性 -> ItemType(选择C/C++ Header)。对 Cpp 文件执行相同操作,但选择 C/C++ 编译器(它对我有用)

于 2015-01-01T17:28:39.820 回答
8

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

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

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

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

于 2010-09-12T14:49:12.093 回答
4

除了删除和创建新文件之外,您还可以更改编译/包含设置。

转到您的project.vcxproj文件,使用编辑器打开它,找到类似行的 html <ItemGroup>

它应该看起来像:

<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>

<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`

假设您的实现文件是 .cpp 并且您的声明是 .hpp。如果您有多个声明文件,请确保您的所有实现文件都列在第一部分之间,同样在第二部分中列出多个声明文件。

于 2013-03-05T21:16:18.947 回答
4

我在 C/C++ -> 输出文件 -> “对象文件名”下使用 $(IntDir)\%(Directory)\。

于 2013-03-19T23:15:21.537 回答
3

我对 stdafx.cpp 有这个问题。不知何故,stdafx.cpp 被复制了,所以有第二个 StdAfx.cpp(注意不同的情况)。

删除 StdAfx.cpp 后一切正常!

使用 VS 2010。

于 2013-01-11T17:55:08.150 回答
2

我曾经在同一个项目中拥有相同文件名的.c.cpp文件。这些文件到处都是文件夹,其他人提供的解决方案造成了混乱,文件夹地狱(在我的情况下)。即使是发布版本也会覆盖调试版本!

一个好的(不是完美的)解决方案是使用 $(ParentName),但由于某种超出任何人理解的原因,它已从更高版本的 Visual Studio(2015+)中删除。

我现在成功使用的是: $(IntDir)%(Filename)%(Extension).obj

至少将.c构建的目标文件与.cpp分开。

于 2017-03-16T15:31:06.750 回答
0

我想指出一个可能的原因,为什么ItemTypea.h file会从C/C++ header变为C/C++ compiler

  1. Solution ExplorerVS(这里是2019)的窗口中,右键项目名称,选择Add -> New Item
  2. 选择C++ File (.cpp)模板,但something.h在名称输入区输入,然后点击OK添加;
  3. 然后,如果文件包含在多个文件中,您将遇到LNK4042警告。something.h.cpp
于 2021-04-30T07:41:43.780 回答
0

我刚刚克服了类似的错误消息,并且通过以下过程获得了更多信息。症状:对特定标头中定义的每个函数的每次调用都会出现一个链接器错误,并且对于标头中定义的每个函数,在输出末尾都会出现一个链接器错误。

然后我记得当我最初创建这个头文件时,我不小心选择了“add->new item->c++ file”,虽然我将它命名为“whatever.h”,但似乎 Visual Studio 认为它们都是相同类型的文件因为我以前添加了一个不正确的操作。 检查构建输出日志使这一点变得显而易见。

解决方案(使用 VS Community 2019)

  1. 首先备份项目(为了安全起见)。
  2. 右键单击有问题的头文件并选择“从项目中排除”(这不会删除它们;VS 项目只会忽略它们)。
  3. 对匹配的 .c 或 .cpp 文件执行相同操作。
  4. 做构建->清理项目
  5. 做 Build->Rebuild on project -- 当然会有错误---
  6. 右键单击 Header Files->Add->Existing Item,然后选择 .h 文件
  7. 右键单击 Source Files->Add->Existing Item,选择 .c 或 .cpp 文件
  8. 对项目执行 Build->Rebuild。

这完全为我清理了它,从这个问题的标题中解脱了许多恼人的链接器错误,包括 LNK4042。

于 2021-11-09T12:42:29.967 回答