2017-02-11 2 views
2

Ich habe die folgende Projektstruktur haben:CMake Projekte mit Submodule, die redudant Abhängigkeiten

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 
       |-> ... 

Die root-project baut eine ausführbare Datei namens foo die my-lib auf der Bibliothek abhängt. Sowohl die root-project als auch die my-lib verwenden googletest zum Testen, die als git-submodule enthalten ist.

Ich habe die Tatsache akzeptiert, dass ich googletest Verzeichnisse unter Verwendung git-submodule redundant haben werde. Das Problem ist jedoch, dass die einfache Verwendung von add_subdirectory zum Verbinden des gesamten Projekts mit mehreren gtest Zielen enden wird.

Meine Frage: Gibt es eine Möglichkeit für root-projectmy-lib zu bauen und nur das Ziel my-lib und nicht die Prüfziel googletest sehen? (Das heißt, kann die redundante googletest sein „versteckt“ während des Build?)

Meine zweite Frage: Da meine Rookie CMake Status, habe ich diese Projekte in einer fehlerhaften Art und Weise organisieren? Gibt es eine bevorzugtere Möglichkeit, die Projekte zu organisieren, die dieses Problem vermeiden? Einige konstruktive CMake Beratung ist willkommen!

+0

Ist Ihnen bekannt, add_subproject? – usr1234567

+0

Nein. Aber ich denke, ich sollte mich damit vertraut machen. – nick

+0

Obwohl es nicht zu existieren scheint: https://cmake.org/?s=add_subproject – nick

Antwort

2

Ich bin mir nicht sicher, ob dies die beste Praxis in diesem Fall ist, aber was ich in meinem Projekt getan habe, war ein cmake Modul schreiben gtest.cmake für gtest zu meinem Projekt hinzuzufügen. In diesem Modul überprüfe ich, ob es bereits gegeben, und wenn es war, ich habe gerade die erzeugte ${gtest_SOURCE_DIR} Variable wieder verwendet:

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() 

EDIT:
Was ich für Testziele normalerweise tun, ist, sie von einem normalen Build auszuschließen, mit der EXCLUDE_FROM_ALL Eigenschaft von add_executable. Sie können dieses Flag auch für add_subdirectory verwenden, so dass ggtest nur dann einbezogen werden kann, wenn Sie die Tests ausführen möchten. Zum Beispiel könnte man so etwas in Ihrem CMakeLists.txt schreiben:

# 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) 

Und haben Ihre cmake/gtest.cmake wie folgt geschrieben:

if(gtest_SOURCE_DIR) 
    message(STATUS "gtest variables already defined. Skipping.") 
else() 
    add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/external/gtest" EXCLUDE_FROM_ALL) 
endif() 

Dann nur, wenn Sie make das Testziel explizit, indem Sie make myProject_tests es wird nur gebaut, was es braucht, um das Testziel zu machen.

Hoffe, dass hilft!

+0

Dies wird immer noch alle Tests aus jedem Teilprojekt kompilieren, oder? Verwenden Sie einfach einen gemeinsamen "googestest"? – nick

+0

@nick Das stimmt. Alle Teilprojekte verwenden den ersten googletest, der geladen wurde. – galsh83

+0

Gibt es eine Möglichkeit, Tests von Unterprojekten auszuschließen? Können Sie beim Erstellen eines Unterprojekts erkennen, ob es als Teil eines größeren Projekts verwendet wird? – nick

Verwandte Themen