2013-07-15 9 views
14

Ich bin neu in CMake und möchte fragen, ob jemand in dem folgenden Problem helfen kann.Recursive CMake Suche nach Header und Quelldateien

Ich habe C++ - Quell- und Header-Dateien in ihren jeweiligen Ordnern und jetzt möchte ich eine CMake-Textdatei machen, die rekursiv nach ihnen sucht.

Derzeit mache ich es auf diese Weise:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 
PROJECT(CarDetectorDAISY) 

file(GLOB_RECURSE SRCS *.cpp) 
file(GLOB_RECURSE HDRS *.h) 

ADD_EXECUTABLE(stereo_framework ${SRCS} ${HDRS}) 
TARGET_LINK_LIBRARIES(stereo_framework) 

Das ist meine Datei CarDetectorDAISY.sln Lösung erstellt und wenn ich versuche, es zu bauen, es zeigt einen Fehler, die Header-Dateien werden nicht gefunden (Datei oder Verzeichnis existiert nicht).

Es wäre wirklich dankbar, wenn mir jemand helfen könnte. Vielen Dank.

Antwort

19

Sie vermissen wahrscheinlich einen oder mehrere include_directories Anrufe. Das Hinzufügen von Headern zur Liste der Dateien im add_executable-Aufruf fügt den Suchpfad des Compilers nicht wirklich hinzu - es ist eine praktische Funktion, durch die sie nur der Ordnerstruktur des Projekts in IDEs hinzugefügt werden.

Also, in Ihrem Stamm, sagen Sie /my_lib/foo.h haben, und Sie möchten, dass als

in einer Quelldatei enthalten
#include "my_lib/foo.h" 

Dann in Ihrem CMakeLists.txt, was Sie tun müssen:

include_directories(${CMAKE_SOURCE_DIR}) 

Wenn stattdessen wollen Sie nur

#include "foo.h" 

dann im CMakeLists.txt zu tun, tun

include_directories(${CMAKE_SOURCE_DIR}/my_lib) 


Ich sollte erwähnen, dass file(GLOB...) nicht die empfohlene Methode ist die Liste der Quellen zu sammeln - Sie sollten wirklich nur jede Datei explizit im CMakeLists.txt hinzuzufügen. Wenn Sie eine Quelldatei zu einem späteren Zeitpunkt hinzufügen oder entfernen, wird die CMakeLists.txt geändert und CMake wird beim nächsten Versuch automatisch erneut ausgeführt. Aus der Dokumentation für file:

:

Wir empfehlen nicht, GLOB zu verwenden, um eine Liste der Quelldateien aus Ihrem Quellverzeichnisbaum zu sammeln. Wenn sich keine CMakeLists.txt-Datei ändert, wenn eine Quelle hinzugefügt oder entfernt wird, kann das generierte Build-System nicht wissen, wann CMake aufgefordert werden soll, neu zu generieren.

+15

Aber ich würde lieber erneut ausführen CMake manuell als jede einzelne Quelldatei eingeben ... – Kapichu

+1

ich auf dem Zaun auf diesem bin. Ich stimme deinem Argument zu, aber das Gegenargument ist normalerweise, dass es ziemlich einfach ist, 'ls' oder' dir' zu machen, um die erste Liste von Quellen zu erhalten, und dann füge ich normalerweise nur eine oder zwei Dateien zu einem späteren Zeitpunkt hinzu . Es ist ziemlich sicher zu glob, wenn Sie alleine arbeiten. Wenn Sie Teil eines Teams sind, müssen Sie das Team "ausbilden", dass CMake immer ausgeführt wird, nachdem eine Datei hinzugefügt oder von einem entfernten VCS aktualisiert wurde, falls eine Datei von einem anderen Teammitglied hinzugefügt wurde. – Fraser

0

Nur weiter einen Punkt in Fraser Antwort zu klären:

Header nicht zu ADD_EXECUTABLE übergeben werden soll.

Der Grund dafür ist, dass der beabsichtigte Zusammenstellung Befehl zum Beispiel auf Linux ist einfach:

gcc main.c mylib.c 

und nicht:

gcc main.c mylib.c mylib.h 

Der C Pre-Prozessor dann analysiert mylib.c, und sieht ein #include "mylib.h", und verwendet den Suchpfad für diese Dateien.

Bei der Verwendung von include_directories ändern wir stattdessen den cpp-Präprozessorsuchpfad, was der richtige Ansatz ist. In GCC bedeutet dies die -I Flag auf der Befehlszeile hinzu:

gcc -Inew/path/to/search/for/headers main.c mylib.c 
+0

Es kann nützlich sein, Header im Befehl 'target_sources()' aufzulisten, da Header, die als Quellen aufgelistet sind, nicht direkt kompiliert werden. Wenn sie hinzugefügt werden, werden diese Header in der Projektdatei in IDEs aufgelistet, auch wenn keine Quelle vorhanden ist Datei # enthält sie direkt. Hinweis: Dies ist offensichtlich nur eine Ergänzung zum Befehl 'include_directories()' – SebNag