我是统一构建的新手。我一直在做一些研究,并从以下方面获得了很好的信息:
- http://buffered.io/posts/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.hpp
并Client.cpp
使用verbose <<
. MyMainFile.cpp
调用它们中的函数。
不用说,使用正常的构建方式,一切正常。
现在问题...
我Unity.cpp
在 LibProj 中创建。它的内容是:
#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 的 lib 文件并将其从两个项目中删除。但是,我想先了解为什么会发生这种情况。
另外,有人能想出更好的方法来解决这个问题吗?