我正在尝试从源代码编译gtest(而不是使用现有的已安装版本)。我正在开发一个基于catkin的cmake项目。
我已将源代码从https://github.com/google/googletest添加到我的工作区,并将该文件夹包含在add_subdirectory中。
然而,我得到了现有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#incorporating-into-an-existing-cmake-project)我明白这应该没问题。
我认为问题可能在于catkin如何处理gtest。而且,诚然,通常我可以使用已安装的版本。但我想确保每个人都使用相同的(捆绑式)gtest版本。
欢迎任何建议和提示。
答案 0 :(得分:1)
好的,所以错误信息实际上非常清楚。一个cmake"目标"是"将由构建"生成的东西,无论是库,还是可执行文件,还是其他东西。所以,问题是你正在尝试添加名为" gtest"的目标,并且catkin已经做了同样的事情。两者都会产生库" libgtest.so",当然只有一个在同一个文件夹中。你可以重命名"你的" gtest通过更改googletest/CMakelists.txt中的目标名称,但我强烈建议您不要这样做。
在我看来,gtest根本不应该是一个共享库,特别是如果你在存储库中为不同的项目使用不同的构建标志。有一个替代方案,基本上只包括文件夹中的gtest源代码,然后在单元测试main.cpp
中包含头文件和源文件。 googletest已经附带了帮助,即src/gtest-main.cc
。
这就是我如何构建它:
.cpp
个文件中,#include <gtest/gtest.h>
,每个hpp
要测试一个,#include
hpp
和cpp
1 {} 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个单独的单元测试,一个启用异常,另一个不启用。