Я думаю, что этот вопрос может нарушать некоторые из стандартов вопросов и ответов для сайта, поскольку ответы, которые я могу получить, могут рассматриваться как основанные на мнении. Тем не менее, вот оно...
Предположим, мы работаем над проектом C++, используя CMake для управления процессом сборки/тестирования/упаковки, а также GTest и GMock для тестирования. Далее предположим, что структура нашего проекта выглядит так:
cool_project
|
|-- source
| |
| |-- module_foo
| | |
| | |-- (bunch of source files)
| |
| |-- module_bar
| |
| |-- (yet more source files)
|
|-- tests
|
|-- module_foo
| |
| |-- (tests for module_foo)
|
|-- module_bar
|
|-- (tests for module_bar)
Это, конечно, упрощенная ситуация, но вы поняли.
Итак, если эти модули являются библиотеками и каждый тест (то есть каждый каталог в tests
) является исполняемым файлом, нам нужно связать последний с первым. Дело в том, что если эти библиотеки являются общими, загрузчик, конечно, должен их найти. Очевидное решение — установить рабочий каталог теста в каталог библиотеки, используя CMake set_property
. Однако, если и GTest, и GMock также были созданы как разделяемые библиотеки, это не сработает, поскольку их также необходимо загрузить.
Решения, которые я придумал, были:
- Скопируйте обе библиотеки (например, GTest и GMock) в каталог сборки модуля. Это выглядит довольно глупо, поскольку основное преимущество разделяемых библиотек (то есть совместное использование кода между программами) полностью игнорируется, и в итоге мы получаем несколько их копий по всему каталогу сборки.
- Вместо этого создайте и GTest, и GMock как статические библиотеки. Это означает, что теперь мы получаем копию обеих библиотек в каждом исполняемом файле, что увеличивает его размер. Несмотря на то, что у нас нет 1000 тестов, это как-то неловко.
Итак, учитывая эту ситуацию, я хотел бы знать, сталкивался ли кто-нибудь с этим, и какой путь он/она выбрал. (Если бы решение было другим, чем те, которые я упомянул, я был бы рад услышать все об этом.) В идеале я хотел бы быть в положении, в котором я мог бы make && make test
и выполнять все тесты, не запуская любой дополнительный сценарий для размещения вещей. Сборка всех библиотек как статических справится со своей задачей, но что, если вместо этого я создам их как общие библиотеки? Должен ли я строить их дважды? Это глупо.
Другая проблема также работает в этом направлении, но я думаю, что ее решение связано с редизайном или подобным артефактом. Предположим, что module_foo
зависит от сторонней библиотеки, например. library_baz
. Если module_foo
напрямую ссылается на library_baz
, то при любом тестировании первого потребуется загрузить library_baz
, даже если он может проверять несвязанную функциональность. Возникает такая же проблема.
Насмешки кажутся правильными здесь, но почему-то я чувствую, что нет особого смысла рефакторить module_foo
, чтобы он мог общаться с интерфейсом (будь то в силу динамического или статического полиморфизма), поскольку он не нужна такая гибкость: library_baz
делает свою работу. Я полагаю, что некоторые люди сказали бы что-то вроде «Конечно, вам не нужна гибкость сегодня, но кто знает завтра?». Мне кажется нелогичным пытаться предварительно просмотреть все возможные сценарии, с которыми может столкнуться система, но опять же, есть люди с гораздо большим опытом, чем я.
есть идеи?
gtest
иgmock
в качестве локальных общих библиотек в системе, то есть в/usr/local/lib
? Динамическое связывание найдет их там, если вашиldconfig
пути поиска нормальные, а затем вы можете просто добавить-lgtest -lgmock -pthread
к параметрам связывания ваших тестов. Есть ли какая-то причина, по которой ваша тестовая установка не работает? - person Mike Kinghan   schedule 21.01.2014