我有以下项目结构:
root-project/
|-> CMakeLists.txt
|-> src/
|-> foo.cpp
|-> include/
|-> foo.hpp
|-> test/
|-> test_foo.cpp
|-> googletest/
|-> CMakeLists.txt
|-> ...
|-> libs/
|-> my-lib/
|-> CMakeLists.txt
|-> src/
|-> bar.cpp
|-> include/
|-> bar.hpp
|-> test/
|-> test_bar.cpp
|-> googletest/
|-> CMakeLists.txt
|-> ...
root-project
构建一个名为foo
的可执行文件,它依赖于库my-lib
。 root-project
和my-lib
都使用googletest
进行测试,其中包含git-submodule
。
我已经接受了这样一个事实,即使用googletest
我将拥有多余的git-submodule
目录。但问题是,仅使用add_subdirectory
连接整个项目最终会产生多个gtest
目标。
我的问题:root-project
是否有办法构建my-lib
并且只能看到目标my-lib
而不是测试目标googletest
? (即,在构建期间,多余的googletest
是否可以隐藏")
我的第二个问题:鉴于我的菜鸟CMake状态,我是否以有缺陷的方式组织这些项目?是否有更优先的方式来组织避免此问题的项目?我们欢迎一些有建设性的CMake建议!
答案 0 :(得分:3)
我不确定这是否是这种情况下的最佳做法,但我最终在我的项目中做的是写一个cmake模块gtest.cmake
来为我的项目添加gtest。在那个模块中,我检查它是否已经添加,如果是,我只是重用生成的${gtest_SOURCE_DIR}
变量:
的CMakeLists.txt:
cmake_minimum_required(VERSION 3.3)
project(myProject CXX)
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake")
include(gtest)
# myTarget definition
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
target_link_libraries(myTarget gtest gtest_main)
cmake的/ gtest.cmake:
if(gtest_SOURCE_DIR)
message(STATUS "gtest variables already defined. Skipping.")
else()
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/external/gtest")
endif()
编辑:
我对测试目标所做的通常是使用EXCLUDE_FROM_ALL
的{{1}}属性将它们从常规版本中排除。您也可以将该标志用于add_executable
,这样只有在您想要运行测试时才能包含gtest。例如,您可以在CMakeLists.txt中编写类似的内容:
add_subdirectory
让你的# set ${TESTS_SOURCE_FILES} with the source files of your tests
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
add_executable(${PROJECT_NAME}_tests EXCLUDE_FROM_ALL ${TESTS_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME}_tests gtest gtest_main)
写得像这样:
cmake/gtest.cmake
然后,只有当if(gtest_SOURCE_DIR)
message(STATUS "gtest variables already defined. Skipping.")
else()
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/external/gtest" EXCLUDE_FROM_ALL)
endif()
显式地测试目标时,通过运行make
,它才会构建测试目标所需的内容。
希望有所帮助!