2017-03-21 7 views
0

Ich bin gerade in cmake gekommen, weil ich anfing, an einem größeren Projekt zu arbeiten. Ich muss Modultests hinzufügen. Es gibt mehrere eingebettete Geräte, auf denen jeweils eigene Anwendungen ausgeführt werden.cmake für größeres Projekt mit gemeinsamem Code

Die meisten dieser Anwendungen teilen Code. So ist der Code in Module unterteilt. Das Problem ist, dass einige Module in den meisten anderen Modulen verwendet werden. Diese Module sind üblich, common-net und log.

Ein vereinfachtes Projekt (App) für ein Gerät hat folgende Struktur:

. 
    |-- CMakeLists.txt (for app) 
    |-- LICENSE 
    |-- app 
    | |-- inc 
    | | |-- appfile1.hpp 
    | | `-- appfile2.hpp 
    | `-- src 
    |  |-- appfile1.cpp 
    |  |-- appfile2.cpp 
    |  `-- main.cpp 
    |-- comp 
    | |-- comp1 
    | | |-- CMakeLists.txt (for test) 
    | | |-- comp 
    | | | |-- CMakeLists.txt (for lib) 
    | | | |-- intf 
    | | | | |-- comp1file.hpp 
    | | | | `-- comp1file.hpp 
    | | | `-- src 
    | | |  |-- comp1file.cpp 
    | | |  `-- comp1file.cpp 
    | | `-- test 
    | |  `-- src 
    | |   `-- comp1testfile.cpp 
    | |-- comp2 
    | | |-- CMakeLists.txt (for test) 
    | | |-- comp 
    | | | |-- CMakeLists.txt (for lib) 
    | | | |-- inc 
    | | | | `-- comp2file1.hpp 
    | | | |-- intf 
    | | | | |-- comp2file2.hpp 
    | | | | |-- comp2file3.hpp 
    | | | | |-- comp2file4.hpp 
    | | | `-- src 
    | | |  |-- comp2file1.cpp 
    | | |  |-- comp2file2.cpp 
    | | |  `-- comp2file3.cpp 
    | | `-- test 
    | |  |-- inc 
    | |  | `-- comp2testfile.hpp 
    | |  `-- src 
    | |   `-- comp2testfile.cpp 
    | |-- common 
    | | |-- CMakeLists.txt (for test) 
    | | `-- comp 
    | |  |-- inc 
    | |  | |-- commonfile1.hpp 
    | |  | `-- commonfile2.hpp 
    | |  `-- src 
    | |   `-- commonfile1.cpp 
    | |-- common-net 
    | | |-- CMakeLists.txt (for test) 
    | | |-- comp 
    | | | |-- inc 
    | | | | |-- netfile1.hpp 
    | | | | |-- netfile2.hpp 
    | | | | |-- netfile3.hpp 
    | | | | |-- netfile4.hpp 
    | | | | |-- netfile5.hpp 
    | | | `-- src 
    | | |  |-- netfile1.cpp 
    | | |  |-- netfile2.cpp 
    | | |  |-- netfile3.cpp 
    | | |  |-- netfile4.cpp 
    | | |  |-- netfile5.cpp 
    | | `-- test 
    | |  |-- inc 
    | |  | |-- nettestfile1.hpp 
    | |  `-- src 
    | |   |-- nettestfile1.cpp 
    | |   |-- nettestfile2.cpp 
    | |   |-- nettestfile3.cpp 
    | |-- comp3 
    | | |-- CMakeLists.txt (for test) 
    | | |-- comp 
    | | | |-- CMakeLists.txt (for lib) 
    | | | |-- intf 
    | | | | |-- comp3file1.hpp 
    | | | | `-- comp3file2.hpp 
    | | | `-- src 
    | | |  `-- comp3file1.cpp 
    | | `-- test 
    | |  `-- src 
    | |   `-- comp3testfile1.cpp 
    | |-- log 
    | | `-- comp 
    | |  |-- inc 
    | |  | |-- logfile1.hpp 
    | |  | |-- logfile2.hpp 
    | |  |-- intf 
    | |  | |-- logfile3.hpp 
    | |  | |-- logfile4.hpp 
    | |  `-- src 
    | |   |-- logfile1.cpp 
    | |   |-- logfile2.cpp 
    | |   |-- logfile3.cpp 
    | |   `-- logfile4.cpp 
    | |-- comp4 
    | | |-- CMakeLists.txt (for test) 
    | | |-- comp 
    | | | |-- CMakeLists.txt (for lib) 
    | | | |-- intf 
    | | | | |-- comp4file1.hpp 
    | | | | |-- comp4file2.hpp 
    | | | | |-- comp4file3.hpp 
    | | | `-- src 
    | | |  |-- comp4file1.cpp 
    | | |  |-- comp4file2.cpp 
    | | |  `-- comp4file3.cpp 
    | | `-- test 
    | |  |-- inc 
    | |  | |-- comp4testfile1.hpp 
    | |  | `-- comp4testfile2.hpp 
    | |  `-- src 
    | |   |-- comp4testfile1.cpp 
    | |   |-- comp4testfile2.cpp 
    | |   |-- comp4testfile3.cpp 
    | |   |-- comp4testfile4.cpp 
    | |   `-- comp4testfile5.cpp 
    |-- gcc-4.8.cmake 
    |-- gcc-4.9.cmake 
    `-- gcc-default.cmake 

Ich weiß, dass es eine Menge „comp“ in ihm, aber die Namensgebung war nicht bis zu mir ..

Jede Komposition hat 2 CMakefiles: Die oberste Ebene besteht darin, eine Unit-Test-Executable zu erstellen, um das Modul zu testen. Die in comp ist eine Bibliothek zu machen. Damit kann es mit add_subdirectory in der App CMakefile verwendet werden.

Das Problem ist, dass viele Module von common, common-net und log abhängig sind. Derzeit werden diese Teile nicht als libs erstellt. Ich vermute, weil add_subdirectory Probleme gab, wenn es in mehreren Modulen verwendet wurde? Ist das sauber?

Dies führt zu: Jedes abhängige Modul enthält die gemeinsamen Header in der comp CMakefile. Auf der obersten Ebene (App CMakefile) werden die gemeinsamen Quellen der ausführbaren Datei hinzugefügt. Aber für jeden Modultest muss ich auch die gemeinsamen Quellen zu der ausführbaren Testdatei hinzufügen.

Das scheint mir seltsam und ich denke, etwas stimmt nicht. Aber ich weiß nicht, wie man es sauber löst?

Blick auf den Projektbaum und die Notwendigkeit, jedes Modul unabhängig zu testen. Ist der Ansatz, Quellen auf der obersten Ebene hinzuzufügen, in Ordnung oder wird das nicht getan?

+0

Ty für den Link war eine sehr hilfreiche Lektüre. – rinn2883

Antwort

4

Also, wenn ich richtig verstehe, haben Sie zwei separate Probleme: die gemeinsamen Quellen zu jeder ausführbaren Datei hinzufügen müssen und die gemeinsamen Header für jede ausführbare Datei enthalten müssen.

Was Sie wirklich tun sollten, ist, jede der gemeinsamen Code-Bibliotheken zu einem statischen CMake-Bibliotheksziel zu machen. CMake löst Abhängigkeiten zwischen Bibliotheken und ausführbaren Dateien innerhalb eines Projekts, was Sie haben. Solange Sie die Unterverzeichnisse mit dem gemeinsamen Code (gemeinsamen, Common-net, und log) vor den Dingen, die diesen Code verwenden, fügen Sie nur so etwas wie

target_link_libraries(comp2 common common-net log) 

in jedem der comp Ordner tun können, und CMake wird mit den Abhängigkeiten und der Verknüpfung umgehen.

Darüber hinaus können Sie (unter anderem) Include-Pfade an ein Ziel anhängen, und sie werden automatisch auf alles angewendet, das mit diesem verknüpft ist.

Also, für die Protokollbibliothek zum Beispiel, würden Sie

target_include_directories(log PUBLIC inc intf) 

Dann nutzen Sie alles, was in der Protokollbibliothek verknüpft würden die comp/log/comp/inc und comp/log/comp/intf Ordner zu seinem Header Pfad automatisch hinzuzufügen.

Schließlich, wenn ich richtig verstehe, sind Sie add_subdirectory -Ing die comp4/CMakeLists.txt-Dateien, wenn Sie einen ausführbaren Test benötigen, und mit Hilfe der comp4/comp/CMakeLists.txt-Dateien, wenn Sie die Bibliothek für die Aufnahme in die App bauen müssen. Ein besserer Weg, dies zu tun, besteht darin, die Tests auch mit den Bibliotheken verknüpfen zu lassen.

So, zum Schluss, Ihre Projektstruktur ein bisschen sollte wie folgt aussehen:

Top-Level-CMakeLists.txt

add_subdirectory(comp) 
add_subdirectory(app) 

comp/CMakeLists.txt

add_subdirectory(common) 
add_subdirectory(common-net) 
add_subdirectory(log) 
add_subdirectory(comp1) 
<and so on for the other comps> 

comp/common-net/CMakeLists.txt

add_subdirectory(comp) 
add_executable(test-common-net <source for test>) 
target_link_libraries(test-common-net common-net) 

comp/common-net/comp/CMakeLists.txt

add_library(common-net STATIC <source for common-net>) 
target_include_directories(common-net PUBLIC inc) 

# assuming common-net depends on common 
target_link libraries(common-net common) 

comp/COMP1/CMakeLists.txt

add_subdirectory(comp) 
add_executable(test-comp1 <source for test>) 
target_link_libraries(test-comp1 comp1) 

comp/COMP1/comp/CMakeLists.txt

add_library(comp1 STATIC <source for common-net>) 
target_include_directories(comp1 PUBLIC inc) 

target_link libraries(comp1 common common-net log) 

Sie haben die Idee wahrscheinlich schon verstanden. Sie müssen nur eine Kette von Bibliotheken erstellen, die voneinander abhängen.

+0

ty Ich mache ein paar Sachen mit deinen Zeigern neu. Ich denke, es ist viel sauberer. Hoffentlich wird das Team sehen, dass dieser Weg besser ist. – rinn2883