我是团结构建的新手。我一直在做一些研究,我从中得到了很好的信息:
但是,现在我开始对我的一些项目进行更改,我有点困惑。
为简单起见,假设我的解决方案中只有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
调用两者中的函数。
毋庸置疑,以正常的方式建设一切都有效。
现在问题......
我在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的lib文件,并将其从两个项目中删除。但是,我想了解为什么会发生这种情况。
此外,有人可以想出更好的方法来解决这个问题吗?
答案 0 :(得分:0)
我想我知道发生了什么。
Unity.cpp包含Verbose.cpp和Client.cpp
-Verbose.cpp具有 print 的实现
-Client.cpp包含Verbose.hpp,它引入了 print 的实现
所以Unity.obj有2个 print 的实现。
这意味着库(LibProj.lib)包含带有 print 重复项的一个 .obj文件。因此,当我们尝试链接到库时,编译器不知道要使用哪个 print 。
这适用于常规版本的原因是,通常,Verbose.cpp创建Verbose.obj,其中包含 print 的实现,而Client.cpp创建包含实现的Client.obj其中的 print 也是如此。这意味着库(LibProj.lib)包含两个 .obj文件,每个文件中都定义了 print ,因此编译器会选择一个(我不知道如何)
为了测试这个理论,我创建了2个Unity文件
Unity.cpp包括Verbose.cpp
Unity2.cpp包括Client.cpp
通过这个实现,我能够构建。那是因为LibProj.lib现在有两个 .obj文件(Unity.obj和Unity2.obj),每个文件都包含 print 的实现,因此没有符号冲突。< / p>
这只是一个有根据的猜测,我保留错误的权利:)。但是,如果我错了,请纠正我。
感谢。