2016-06-24 5 views
0

enthalten habe ich ein CMake Projekt, das wie folgt aussieht:CMake nicht Header Verzeichnis Submodul A innerhalb Submodul B

project/ 
    CMakeLists.txt 
    subprojectA/ 
    CMakeLists.txt 
    include/ 
     headerA.hpp 
    src/ 
     libraryA.cpp 
    subprojectB/ 
    CMakeLists.txt 
    src/ 
     mainB.cpp 

Die „Bibliothek“ Teilprojekt A, als eine statische Bibliothek kompiliert wird, werden libsubprojectA .ein. Das "Haupt" -Projekt, B, ist als Binärdatei kompiliert und hängt von der Bibliothek ab. mainB.cpp enthält einen Verweis auf headerA.hpp. Hier

ist subprojectA/CMakeLists.txt:

project(SubProjectA) 
include_directories(include) 
add_library(subprojectA STATIC src/libraryA.cpp) 
set(${PROJECT_NAME}_INCLUDE_DIRS 
    ${PROJECT_SOURCE_DIR}/include 
    CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE) 

Und hier ist subprojectB/CMakeLists.txt:

project(SubProjectB) 
include_directories(${SubProjectA_INCLUDE_DIRS}) 
add_executable(mainBinary src/mainB.cpp) 
target_link_libraries(mainBinary subprojectA) 

Das Hauptprojekt CMakeLists.txt wie folgt aussieht:

project(Project) 
add_subdirectory(subprojectB) 
add_subdirectory(subprojectA) 

Beachten Sie, dass Subprojekt B, das Hauptprojekt, vor Sub aufgeführt ist ProjektA.

Hier ist das Problem. Wenn ich "cmake" in diesem Projekt zum ersten Mal ausführe, wird ${SubProjectA_INCLUDE_DIRS} nicht innerhalb von SubProjectB gesetzt.

Was ich denke ist, dass die CMakeLists für SubProjectB zuerst lädt, wenn ${SubProjectA_INCLUDE_DIRS} noch nicht festgelegt wurde. Es setzt seinen eigenen Include-Pfad als Ergebnis auf eine leere Zeichenfolge. Auch wenn libsubprojectA.a vor mainBinary erfolgreich erstellt wird, wurde der Include-Pfad bereits vorher leer gesetzt. Als Ergebnis bekomme ich diesen Fehler, wenn sie versuchen mainBinary zu machen:

subprojectB/src/mainB.cpp:1:23: fatal error: headerA.hpp: No such file or directory 
#include "headerA.hpp" 
        ^

Es ist eine Abhilfe subprojectA vor subprojectB in dem Hauptprojekt CMakeLists im deklarativen Welt von CMake zu setzen. Was ich wirklich will, ist, die richtige Weise zu wissen, dass CMake, dass die include_directories(${SubProjectA_INCLUDE_DIRS}) Linie auf die Definitionen, die in SubProjectA CMakeLists existieren, ist. Gibt es einen besseren Weg, dies zu tun?

Antwort

1

Wenn Sie zum Ausdruck bringen wollen, dass Directory gehören subprojectA/include ist eine Schnittstelle der Bibliothek subprojectA, befestigen Sie diese Eigenschaft auf dem Ziel mit target_include_directories Befehl:

subprojectA/CMakeLists.txt :

project(SubProjectA) 
add_library(subprojectA STATIC src/libraryA.cpp) 
# PUBLIC adds both: 
#  1) include directories for compile library and 
#  2) include directories for library's interface 
target_include_directories(subprojectA PUBLIC include) 

So eine ausführbare Datei (oder eine andere Bibliothek), die mit subproje verknüpft ctA wird dieses Verzeichnis automatisch enthalten hat:

subprojectB/CMakeLists.txt:

project(SubProjectB) 
add_executable(mainBinary src/mainB.cpp) 
target_link_libraries(mainBinary subprojectA) 

Natürlich für letzten Befehl ordnungsgemäß müssen Sie Verzeichnis mit Bibliothek verarbeiten vor einem mit ausführbarem:

CMakeLists. txt:

project(Project) 
add_subdirectory(subprojectA) 
add_subdirectory(subprojectB) 
+0

Der letzte Teil in Bezug auf die Reihenfolge der Verweise auf die Unterverzeichnisse, ist das größte Element. Trotz CMake's Design als allgemein deklarative Sprache, hat es immer noch Elemente, die nur in der richtigen Reihenfolge sein müssen. Also ich denke, das ist das Beste, was ich für jetzt tun kann. Vielen Dank. –