使用具有redudant依赖关系的子模块来CMake项目

时间:2017-02-11 23:46:58

标签: cmake git-submodules

我有以下项目结构:

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-libroot-projectmy-lib都使用googletest进行测试,其中包含git-submodule

我已经接受了这样一个事实,即使用googletest我将拥有多余的git-submodule目录。但问题是,仅使用add_subdirectory连接整个项目最终会产生多个gtest目标。

我的问题root-project是否有办法构建my-lib并且只能看到目标my-lib而不是测试目标googletest ? (即,在构建期间,多余的googletest是否可以隐藏")

我的第二个问题:鉴于我的菜鸟CMake状态,我是否以有缺陷的方式组织这些项目?是否有更优先的方式来组织避免此问题的项目?我们欢迎一些有建设性的CMake建议!

1 个答案:

答案 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,它才会构建测试目标所需的内容。

希望有所帮助!