build — C ++ Unity Сборка файла библиотеки, LNK2005

Я новичок в построении единства. Я провел небольшое исследование и получил отличную информацию от:

Однако теперь, когда я начал вносить изменения в некоторые из моих проектов, я немного растерялся.

Для простоты, скажем, у меня есть только 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.

Мой вопрос: почему это работает, когда файлы компилируются отдельно, но не работает со сборкой Unity?

Что отличает один файл .lib от другого? Я имею в виду, технически LibProj.lib имеет символы для VerboseMonitor::print в обоих случаях сборки, и эти символы переопределены ExecProj. Однако дело построения единства терпит неудачу.

Одним из способов решения этой проблемы является создание другого файла lib, который содержит только Verbose.cpp, и удаление его из обоих проектов. Тем не менее, я хотел бы понять, почему это происходит в первую очередь.

Кроме того, кто-то может придумать лучший способ обойти эту проблему?

0

Решение

Я думаю, что знаю, что происходит.

Unity.cpp содержит Verbose.cpp и Client.cpp
-Verbose.cpp имеет значение Распечатать.
-Client.cpp включает Verbose.hpp, который вносит в реализацию Распечатать.
Таким образом, Unity.obj имеет 2 реализации Распечатать.

Это означает, что библиотека (LibProj.lib) содержит один .файл obj с Распечатать дубликаты. Поэтому, когда мы пытаемся установить ссылку на библиотеку, компилятор не знает, какая Распечатать использовать.

Причина, по которой это работает на обычных сборках, заключается в том, что обычно Verbose.cpp создает Verbose.obj, который содержит реализацию Распечатать в нем, и Client.cpp создает Client.obj, который содержит реализацию Распечатать в этом тоже. Это означает, что библиотека (LibProj.lib) содержит два .файлы obj с Распечатать определены в каждом, так что компилятор выбирает один (хотя я не знаю, как).

Чтобы проверить эту теорию, я создал 2 файла Unity.
Unity.cpp включает Verbose.cpp
Unity2.cpp включает в себя Client.cpp

С помощью этой реализации я могу построить. Это потому, что LibProj.lib теперь имеет два .файлы obj (Unity.obj & Unity2.obj), каждый из которых содержит реализацию Распечатать, так что нет столкновения символов.

Это просто обоснованное предположение, и я оставляю за собой право ошибаться :). Однако, если я ошибаюсь, поправьте меня.

Благодарю.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]