Kurze Frage zu CMake



  • Ich mache mich momentan mit CMake vertraut, unter anderem möchte ich dazu den LibQGLViewer als Third-PArty Library einbinden.

    Die CMakeLists.txt im zugehörigen Unterverzeichnis sieht folgendermaßen aus, wobei der Teil, bzgl. dessen ich eine Frage habe, bei Zeile 25-28 ist. Ich habe ein paar Header und sourcen rausgelassen damit der Post übersichtlicht bleibt

    cmake_minimum_required (VERSION 3.5.1 FATAL_ERROR)
    
    set(target_name QGLViewerQt5)
    project(${target_name})
    
    message(STATUS "BUILDING QGLViewer-2.7.0 FROM SOURCE!")
    
    set(BASE_DIR QGLViewer)
    set(VRENDER_DIR VRender)
    set(CMAKE_AUTOMOC ON)
    
    set(QGLheaders
    	${BASE_DIR}/camera.h
        	${BASE_DIR}/config.h
    	${BASE_DIR}/${VRENDER_DIR}/AxisAlignedBox.h
    	${BASE_DIR}/${VRENDER_DIR}/Exporter.h
    )
    
    set(QGLsources
    	${BASE_DIR}/camera.cpp
            ${BASE_DIR}/${VRENDER_DIR}/Exporter.cpp
    )
    
    add_library(${target_name} ${QGLsources} ${QGLheaders})
    target_include_directories(${target_name} 
      PUBLIC .
      )
    
    target_link_libraries(${target_name}
      ${OPENGL_LIBRARIES}
      Qt5::Core
      Qt5::Widgets
      Qt5::Xml
      Qt5::OpenGL
    )
    
    set(CMAKE_AUTOMOC OFF)
    
    install(TARGETS ${target_name} DESTINATION lib)
    

    Die Header und Src-Files liegen bei der Lib zusammen im Ordner. Das ganz baut und meine Anwendung läuft.

    Nun lese ich überall, dass man bei add_library nur die sourcen einbinden soll und darunter bei target_include_directories die Header. Also habe ich den die Passage geändert zu

    add_library(${target_name} SHARED ${QGLsources})
    target_include_directories(${target_name} 
      PUBLIC 
        ${PROJECT_SOURCE_DIR}/QGLViewer 
        ${PROJECT_SOURCE_DIR}/QGLViewer/VRender
      )
    

    Bekomme jedoch dann beim bauen meiner Applikation den Fehler

    fatal error: QGLViewer/qglviewer.h: No such file or directory
    compilation terminated.

    und es wäre toll, wenn ihr mir bei diesem Problem kurz helfen könntet, deshalb ein paar Fragen

    • Was genau bewirkt PUBLIC . ?
    • Wieso funktionieren meine Änderungen nicht?

    Danke schon mal für eure Hilfe



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (alle ISO-Standards) in das Forum Compiler- und IDE-Forum verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Sewing schrieb:

    • Was genau bewirkt PUBLIC . ?

    Die Zeile fügt das Verzeichnis '.' , also für jede Quellcodedatei das jeweils aktuelle Verzeichnis in dem sich diese befindet, zu den Include-Verzeichnissen hinzu.

    Sewing schrieb:

    • Wieso funktionieren meine Änderungen nicht?

    Ich kann nur vermuten (bin mir aber relativ sicher), dass eine Datei, die sich in dem QGLViewer/ übergeordneten Verzeichnis befindet, ein

    #include <QGLViewer/qglviewer.h>
    

    beinhaltet. Gehört nun das aktuelle Verzeichnis '.' zu den Include-Verzeichnissen, so wird hier die Datei ./QGLViewer/qglviewer.h gefunden
    (beachte den Punkt am Anfang, das ist eines der Include-Verzeichnisse, die dem Compiler mitgegeben wurden!). Bei den Include-Verzeichnissen,
    die du jedoch angegeben hast, funktioniert das nicht. Dort sucht der Compiler entweder nach

    ${PROJECT_SOURCE_DIR}/QGLViewer/QGLViewer/qglviewer.h

    oder

    ${PROJECT_SOURCE_DIR}/QGLViewer/VRender/QGLViewer/qglviewer.h

    ... also <Include-Verzeichnis> + den 'QGLViewer/qglviewer.h' -Teil aus dem #include .

    Lösung:

    Entweder wieder '.' zu den Include-Verzeichnissen hinzufügen wie gehabt, oder

    ${PROJECT_SOURCE_DIR}

    hinzufügen - letzteres könnte aber eventuell nicht zuverlässig funktionieren, da vielleicht auch noch weitere Header in anderen Verzeichnissen
    "relativ" mit #include <> referenziert werden könnten (statt mit #include "" , was eigentlich für solche relativen includes gedacht ist)



  • Erst einmal vielen Dank für deine ausführliche und hilfreiche Antwort.

    ich würde gerne einen einhaltlichen Syntax verwenden und . finde ich da nicht so günstig. Habe ich das richtig verstanden, dass die Problematik hier aufgrund der Strujtur der Header und Source file Aufteilung entsteht?



  • Sewing schrieb:

    Erst einmal vielen Dank für deine ausführliche und hilfreiche Antwort.

    ich würde gerne einen einhaltlichen Syntax verwenden und . finde ich da nicht so günstig. Habe ich das richtig verstanden, dass die Problematik hier aufgrund der Strujtur der Header und Source file Aufteilung entsteht?

    Das Problem entsteht durch ein

    #include <QGLViewer/qglviewer.h>

    in einer der Dateien. #include <datei.h> (mit spitzen Klammern) sucht die Dateien in den Standard-Include-Verzeichnissen des Compilers
    (z.B. mit -I<Verzeichnis> an den Compiler übrgeben, oder eben in CMake via target_include_directories() hinzugefügt). Anders verhält
    sich #include "datei.h" , hier wird die Datei unabhängig von den Include-Verzeichnissen in dem Verzeichnis gesucht, in dem sich die
    einbindende Datei befindet. Beachte auch dass man beim #include auch Unterverzeichnisse angegeben werden können, diese werden
    dann auf die selbe weise gesucht, also relativ zu den Include-Verzeichnissen (bei spitzen Klammern) oder eben relativ zum Verzeichnis der
    einbindenden Datei.

    Damit das oben genannte #include funktioniert, ist es also erforderlich, dass eines der Include-Verzeichnisse ein Unterverzeichnis
    QGLViewer/ enthält, in dem sich die Datei qglviewer.h befindet.

    Ich habe mir mal die Quellcode-Verzeichnisstruktur (ZIP-Datei) von LibQGLViewer angesehen, und für mich sieht es erstmal so aus als ob
    der Code erwartet, dass sich das Verzeichnis, in welches du die ZIP-Datei entpackt hast, in der Liste Include-Verzeichnnissen befindet.

    Mach das doch erstmal einfach so, z.B. mit:

    target_include_directories(${target_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
    

    Das fügt das Verzeichnis, in dem sich die aktuelle CMakeLists.txt befindet, zu den Include-Verzeichnissen für dieses Target hinzu.
    Dabei gehe ich davon aus, dass du deine CMakeLists.txt (die ZIP-Datei selbst enthält ja keine solche) in dem Verzeichnis erstellt
    hast, in das du auch die ZIP-Datei entpackt hast, also dort, wo sich z.B. auch die libQGLViewer-2.7.0.pro befindet (das QMake-
    Pendant zu deiner CMakeLists.txt).

    Ob die von dir angegebenen Include-Verzeichnisse

    `${PROJECT_SOURCE_DIR}/QGLViewer

    ${PROJECT_SOURCE_DIR}/QGLViewer/VRender

    `

    tatsächlich erforderlich sind, halte ich für unwahrscheinlich, falls LibQGLViewer alle Header in der selben Form einbindet: #include <QGLViewer/header.h> .



  • wow vielen Dank, ich hoffe jetzt habe ich es besser verstanden.


Log in to reply