2017-02-11 103 views
2

子模塊我有以下項目結構:CMake的項目有redudant依賴

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

我已經接受了使用git-submodule來獲得冗餘googletest目錄的事實。但是,問題在於只需使用add_subdirectory連接整個項目就會以多個gtest目標結束。

我的問題:是有一個root-project方式來構建my-lib,只看到目標my-lib,而不是測試目標googletest? (即,可以將多餘googletest是「隱藏」在生成過程中?)

我的第二個問題:給我的新秀CMake的狀態,沒有我在一個有缺陷的方式來組織這些項目?有沒有更好的方式來組織避免這個問題的項目?歡迎提供一些建設性的CMake建議!

+0

你知道add_subproject嗎? – usr1234567

+0

不是。但我想我應該熟悉它。 – nick

+0

雖然它似乎並不存在:https://cmake.org/?s=add_subproject – nick

回答

2

我不知道這是在這種情況下,最好的做法,但我結束了在我的項目做的,是寫一個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() 

編輯:
我對測試目標所做的事情通常是使用add_executableEXCLUDE_FROM_ALL屬性將它們排除在常規構建之外。您也可以將該標誌用於add_subdirectory,這樣,只有在想要運行測試時才能包含gtest。例如,你可以寫這樣的事情在你的CMakeLists.txt:

# 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測試目標明確,通過運行它只會構建它製作測試目標所需的內容。

希望有幫助!

+0

這仍然會編譯來自任何子項目的所有測試,對吧?只需使用一個常見的'googletest'? – nick

+0

@nick是的。所有子項目都將使用加載的第一個googletest。 – galsh83

+0

有沒有辦法從子項目中排除測試?當你創建一個子項目時,你能檢測它是否被用作更大項目的一部分嗎? – nick