c++ Unity构建库文件,LNK2005

C++ Unity Building a Library File, LNK2005

本文关键字:LNK2005 文件 Unity 构建 c++      更新时间:2023-10-16

我是unity构建的新手。我一直在做一些研究,我得到了很多信息:

  • http://buffered。io/文章/the-magic-of-unity-builds/
  • http://oj.blackapache.net.s3.amazonaws.com/UnityBuilds.html

然而,现在我开始改变我的一些项目,我有点困惑。

为简单起见,假设我的解决方案中只有2个项目。一个库项目(它创建一个.lib文件)和一个可执行项目。我们叫它们LibProj和ExecProj。

这是每个项目的样子:

LibProj
>include
>>Client.hpp<br>
>>Driver.hpp<br>
>>Verbose.hpp
>source
>>Client.cpp<br>
>>Verbose.cpp
ExecProj
>source
>>MyMainFile.cpp<br>
  Verbose.cpp

Verbose.cpp用于调试目的。它包装了ostream,所以我不用cout <<,而是用verbose <<。这样做是为了控制何时将详细输出显示到控制台。在我的版本变体中,所有的详细输出都被跳过。

我在两个项目中都有Verbose.cpp副本的原因是,我可以在我的ExecProj中获得详细的输出,而不必在调试中构建LibProj。

Driver.hppClient.cpp使用verbose <<MyMainFile.cpp调用两个函数

不用说,用正常的方式构建一切都可以。

现在的问题是…

我在LibProj中创建了Unity.cpp。其内容为:

#include "Client.cpp"
#include "Verbose.cpp"

LibProj构建得很好。但是,当我构建ExecProj时,它在链接期间中断:

LibProj.lib(Unity.obj) : error LNK2005: "public: void __thiscall VerboseMonitor::print(char const *,int)"
(?print@VerboseMonitor@@QAEXPBDH@Z) already defined in Verbose.obj
LibProj.lib(Unity.obj) : error LNK2005: "public: __thiscall VerboseStream::VerboseStream(void)" 
(??0VerboseStream@@QAE@XZ) already defined in Verbose.obj
C:Users\...ExecProj.exe : fatal error
LNK1169: one or more multiply defined symbols found

基本上,它抱怨是因为我们重新定义了lib文件中已经存在的详细函数。

我的问题是,为什么当文件单独编译时它可以工作,但它不能与统一构建一起工作?

是什么使一个.lib文件与另一个不同?我的意思是,技术上LibProj.lib在两个构建情况下都有VerboseMonitor::print的符号,这些符号由ExecProj重新定义。但是,统一构建案例失败。

解决这个问题的一种方法是创建另一个仅包含Verbose.cpp的库文件,并将其从两个项目中删除。但是,我想先了解一下为什么会发生这种情况。

还有,有人能想出一个更好的方法来解决这个问题吗?

我想我知道是怎么回事了。

Unity.cpp包含Verbose.cpp和Client.cpp
-Verbose.cpp实现了打印.
-Client.cpp包括Verbose.hpp,它带来了打印的实现。所以团结。Obj有两种print的实现。

这意味着库(libproject .lib)包含一个与print重复的 .obj文件。因此,当我们尝试链接到库时,编译器不知道使用哪个print

这在常规构建中起作用的原因是,Verbose.cpp通常会创建Verbose。其中包含的实现,打印, Client.cpp创建Client。Obj,其中包含的实现,并在其中打印。这意味着库(libproject .lib)包含两个 .obj文件,每个文件中都定义了print,因此编译器选择一个(尽管我不知道如何)。为了验证这个理论,我创建了2个Unity文件。Unity.cpp包含Verbose.cpp
unity .cpp包含Client.cpp

通过这个实现,我可以构建。这是因为LibProj。lib现在有两个 .obj文件。obj,Unity2.obj),每个都包含一个print的实现,所以没有符号冲突。

这只是一个有根据的猜测,我保留错误的权利:)然而,如果我错了,请纠正我。

谢谢。