Скомпилируйте gtest из исходного кода с помощью catkin
Я пытаюсь скомпилировать gtest из исходного кода (вместо использования существующей установленной версии). Я работаю над проектом cmake на основе сережек.
Я добавил исходный код из https://github.com/google/googletest в свою рабочую область и включил папку с add_subdirectory.
Тем не менее, я получаю nameclash с существующим gtest:
CMake Error at src/test_env/GTest/googletest/cmake/internal_utils.cmake:151 (add_library):
add_library cannot create target "gtest" because another target with the
same name already exists. The existing target is a shared library created
in source directory "/usr/src/gtest". See documentation for policy CMP0002
for more details.
Из других сообщений и самой инструкции googletest ( https://github.com/google/googletest/tree/master/googletest) я понимаю, что это не должно быть проблемой.
Я думаю, что проблема может заключаться в том, как сережка обрабатывает gtest. И, по общему признанию, обычно я мог просто использовать установленную версию. Но я хочу убедиться, что все используют одну и ту же (в комплекте) версию gtest.
Любые предложения и советы приветствуются.
1 ответ
Итак, сообщение об ошибке на самом деле довольно ясно. "Target" cmake - это "то, что будет создано сборкой", будь то библиотека, или исполняемый файл, или что-то еще. Итак, проблема в том, что вы пытаетесь добавить цель с именем "gtest", и catkin уже делает то же самое. И то и другое создаст библиотеку "libgtest.so", и, конечно, в одной папке может быть только одна из них. Вы можете переименовать "свой" gtest, изменив имя цели в googletest / CMakelists.txt, но я настоятельно рекомендую вам не делать этого.
По моему мнению, gtest вообще не должен быть общей библиотекой, особенно если вы используете разные флаги сборки для разных проектов в вашем хранилище. Есть альтернатива, и это в основном только включение исходного кода gtest в папку, а затем включение заголовочных файлов и исходных файлов в ваши юнит-тесты main.cpp
, GoogleTest уже идет с помощниками для этого, то есть src/gtest-main.cc
,
Вот как я бы это структурировал:
- Добавьте нужную версию gtest в качестве подмодуля в git (если вы используете git). Таким образом, у вас есть указанная версия для всех проектов в вашем репо, и вы можете обновить ее в другой ветке. Я назову эту папку "GTEST_DIR".
- Напишите свои юнит-тесты в
.cpp
файлы, которые#include <gtest/gtest.h>
по одномуhpp
вы хотите проверить, и#include
обаhpp
иcpp
в вашемtest.cpp
, Это обеспечивает отделение ваших тестов от других классов и позволяет очень легко переключать зависимые классы с помощью ложных или фиктивных объектов. Вам не понадобитсяmain()
функция, так как тот уже находится вgtest-main.cc
, Напишите макрос cmake следующим образом:
macro(add_gtest NAME FILES) add_executable(my_gtest_$NAME $FILES GTEST_DIR/src/gtest.cc GTEST_DIR/src/gtest-death-test.cc GTEST_DIR/src/gtest-filepath.cc GTEST_DIR/src/gtest-port.cc GTEST_DIR/src/gtest-printers.cc GTEST_DIR/src/gtest-test-part.cc GTEST_DIR/src/gtest-typed-test.cc GTEST_DIR/src/gtest-main.cc ) target_include_directories(my_gtest_$NAME GTEST_DIR/include) endmacro()
Конечно, вы можете сделать это более сложным или менее сложным, но это суть. Конечно, таким образом время компиляции будет больше, чем при использовании gtest в качестве разделяемой библиотеки, но это на самом деле гарантирует, что ваши модули будут тестироваться изолированно, что, на мой взгляд, очень ценно. Также вы можете использовать ccache
значительно улучшить время компиляции в этом сценарии, потому что объектные файлы gtest никогда не меняются. Кроме того, это обеспечит компиляцию gtest именно с теми флагами, которые вам нужны. Например, вы можете создать 2 отдельных модульных теста для одного и того же класса, один с включенными исключениями и один без.