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 viatarget_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 Dateiqglviewer.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 deineCMakeLists.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 dielibQGLViewer-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.