首页 文章

Visual Studio 2010的奇怪“警告LNK4042”

提问于
浏览
71

我刚刚被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)(?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不展平文件层次结构?

8 回答

  • 2

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

    $(IntDir)/%(RelativeDir)/

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

  • 121

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

  • 91

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

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

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

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

  • 8

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

  • 4

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

  • 5

    我有stdafx.cpp这个问题 . 某种程度上stdafx.cpp得到了重复,所以还有第二个StdAfx.cpp(请注意不同的情况) .

    删除StdAfx.cpp后,一切正常!

    使用VS 2010 .

  • 3

    或者,要删除并创建新文件,您可以更改编译/包含设置 .

    转到你的project.vcxproj文件,用编辑器打开它,找到像行 <ItemGroup> 这样的html .

    它应该看起来像:

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

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

    假设您的实现文件是.cpp,您的声明是.hpp . 确保你的所有实现文件都列在第一部分之间,如果你有多个,第二部分同样适用于多个声明文件 .

  • 3

    我以前在同一个项目 .c.cpp 文件中有 the same filenames . 文件存放在整个文件夹中,其他人提供的解决方案造成了混乱,文件夹地狱(在我的情况下) . 即使 Release 版本也会覆盖 Debug 版本!

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

    我现在成功使用的是:$(IntDir)%(文件名)%(扩展名).obj

    至少将 .c 构建的目标文件从 .cpp 中分离出来 .

相关问题