Я новичок в сборках Unity. Я провел некоторое исследование и получил отличную информацию от:
- 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, и удалить его из обоих проектов. Тем не менее, я хотел бы сначала понять, почему это происходит.
Кроме того, может ли кто-нибудь придумать лучший способ обойти эту проблему?