代码之家  ›  专栏  ›  技术社区  ›  Matthieu M.

Visual Studio 2010的奇怪“警告LNK4042”

  •  73
  • Matthieu M.  · 技术社区  · 14 年前

    我刚刚被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) ?查看函数中引用的@identity@test@@yaxxz) void __cdecl test::identity::identity(void) ?标识@0测试@yaxxz)
    1 identity.obj:错误lnk2019:未解析的外部符号 void __cdecl test::identity::make(void) ?使@identity@test@@yaxxz)在函数中被引用 void uu cdecl test::identity::identity(void) ?标识@0测试@yaxxz)
    1 range.obj:错误lnk2019:未解析的外部符号 void __cdecl test::range::is(void) ?函数中引用了@range@test@@yaxxz) void __cdecl test::range::range(void) ?范围@0测试@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 回复  |  直到 6 年前
        1
  •  93
  •   Saurav Sahu    7 年前

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

    美元(intdir)/%(relativedir)/

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

        2
  •  125
  •   Cédric Bignon    11 年前

    我对链接器警告也有类似的问题 LNK4042:对象指定了多次;忽略附加项 . 在我的例子中,Visual Studio试图编译具有相同名称的头文件和源文件- MyClass.h MyClass.cpp . 因为我改名了 .cpp 文件到 .h 而Visual Studio也很困惑。我通过查看编译器日志发现了这个问题。 Debug 目录。要解决,只需删除 h 项目中的文件,然后再次添加。

        3
  •  8
  •   Hans Passant    14 年前

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

    你可以改变设置,比如 $(IntDir)\is2.obj . 或者从一个组中选择所有文件(使用shift+单击),然后将设置更改为,例如, $(IntDir)\identity\

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

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

        4
  •  5
  •   Phạm Mạnh    10 年前

    右键单击头文件-&属性;-gt;ItMyType(选择C/C++头)。用CPP文件做同样的操作,但是选择C/C++编译器(这是我的工作)

        5
  •  4
  •   Csimbi    11 年前

    我使用$(in didir)\%(目录)在C/C++ +gt;输出文件-gt;“对象文件名”。

        6
  •  3
  •   Knasterbax    12 年前

    我对stdafx.cpp有问题。不知为什么stdafx.cpp被复制了,所以还有第二个stdafx.cpp(注意不同的情况)。

    在我取出stdafx.cpp之后,一切正常!

    使用VS 2010。

        7
  •  3
  •   user007    6 年前

    除了删除和生成新文件,您还可以更改编译/包含设置。

    去你的 VCXPROJ 文件,用编辑器打开它,找到类似HTML的行 <ItemGroup> .

    它应该看起来像:

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

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

    假设您的实现文件是.cpp,声明是.hpp。如果您有多个声明文件,请确保您的所有实现文件都列在第一节和第二节之间。

        8
  •  2
  •   Bill Kotsias    7 年前

    我以前在同一个项目中 C CPP 档案带 相同的文件名 . 文件放在到处的文件夹中,其他人提供的解决方案造成了混乱,文件夹地狱(在我的情况下)。偶数 释放 生成将覆盖 调试 建造!

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

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

    至少分开了 C 从生成对象文件 CPP .