2010-01-21 8 views
42

Ich möchte alle .c Dateien in einem Verzeichnis finden und sie alle zu SRC Dateien hinzufügen, um sie in CMake zu kompilieren. Wie kann ich dies in CMakeList.txt tun.Wie finde ich alle * .c Dateien für Cmake Build System

für regelmäßigen Makefiles kann ich

SPECIFIED_SRC_FILE = $(foreach d,$(SPECIFIED_SRC_DIRS),$(wildcard $(addprefix $(d)/*,*.c))) 

schaffen, aber ich konnte nicht, wie in CMakeList.txt, so etwas zu tun.

+1

Beachten Sie, dass "alle Quelldateien mit glob sammeln" in CMake ** nicht empfohlen wird: * Wir empfehlen nicht, 'GLOB' zu verwenden, um eine Liste von Quelldateien aus Ihrer Quellstruktur 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. * - from [documentation] (https://cmake.org/cmake/help/ v3.7/command/file.html) –

+0

@FranklinYu gibt es eine Alternative, bei der nicht jeder Dateiname manuell geschrieben werden muss? –

+1

@Ciro Wenn Sie vermeiden möchten, jeden Dateinamen zu schreiben, dann denke ich "foreach" von OP genannt ist der Weg zu gehen. Das CMake-Team scheint jedoch zu empfehlen, * jeden Dateinamen * manuell zu schreiben. –

Antwort

39

Try this:

AUX_SOURCE_DIRECTORY

alle Dateien Quelle in einem Verzeichnis.

AUX_SOURCE_DIRECTORY(dir VARIABLE) 

Sammelt die Namen aller Quelldateien im angegebenen Verzeichnis und speichert die Liste in den Variablen zur Verfügung gestellt. Dieser Befehl soll von Projekten verwendet werden, die explizite Template-Instanziierung verwenden. Vorlagen Instanziierungsdateien können in einem "Templates" Unterverzeichnis gespeichert und automatisch mit diesem Befehl gesammelt werden, um manuelle Auflistung aller Instanziierungen zu vermeiden.

Es ist verlockend, diesen Befehl zu verwenden, um zu vermeiden, die Liste der Quelldateien für eine Bibliothek oder ein ausführbares Ziel zu schreiben. Während dies funktioniert, gibt es keine Möglichkeit für CMake, ein Build-System zu generieren, das weiß, wenn eine neue Quelldatei hinzugefügt wurde. Normalerweise weiß das generierte Build-System , wann es CMake erneut ausführen muss, da die CMakeLists.txt-Datei geändert wird, um eine neue Quelle hinzuzufügen. Wenn die Quelle nur dem -Verzeichnis hinzugefügt wird, ohne diese Datei zu ändern, müsste man manuell CM0ake erneut starten, um ein Build-System zu generieren, das die neue Datei enthält.

+11

Stelle sicher, dass du den letzten Teil liest, der mit "Es ist verlockend, diesen Befehl zu verwenden, um ... zu vermeiden" – SaoPauloooo

+1

@SaoPauloooo, wie es als nächstes geschrieben wird, "gibt es keine Möglichkeit für Cmake, ein Buildsystem zu generieren, das weiß, wann ein neues Quelldatei wurde hinzugefügt ". Dieser Befehl ist die naheliegendste Antwort auf die Frage von OP. Gut für mich. – whitequark

0

können Sie verwenden AUX_SOURCE_DIRECTORY als @whitequark beschrieben, aber es wird nicht wirklich funktionieren, wie Sie erwarten, wie CMake nicht in der Lage sein wird, zu bestimmen, wann neue Dateien hinzugefügt werden (die Art der springende Punkt ist eine Wildcard bei der Verwendung).

+2

AUX_SOURCE_DIRECTORY wird jetzt gut ausgeführt. Ich danke dir sehr. AUX_SOURCE_DIRECTORY ($ {PROJECT_INC_DIR} control/src CTR_SOURCES) ADD_EXECUTABLE ($ {exe_name} $ {CTR_SOURCES}) –

41

Wie wäre es mit dem guten alten Globbing?

FILE(GLOB MyCSources *.c) 
ADD_EXECUTABLE(MyExecutable ${MyCSources}) 
+0

Dies funktioniert gut, aber es den Nachteil nicht vermeiden (das CMake nicht wissen, wenn neue Dateien hinzugefügt werden) in die anderen zwei Antworten? – kylewm

+1

Nein, tut es nicht. Sie müssen CMake erneut ausführen, sobald eine neue Datei hinzugefügt wurde. –

+8

(was für meine Bedürfnisse gut war ... einfacher als das Bearbeiten der CMakeList jedes Mal, wenn Sie eine Quelldatei hinzufügen) – kylewm

1

Ja, Sie haben zwei Möglichkeiten. Nehmen wir an, Sie haben die Ordnerstruktur etwas Ähnliches.

├── autopilot 
      │   ├── _AutoPilot.cpp 
      │   ├── _AutoPilot.h 
      │   └── action 
      │    ├── ActionBase.cpp 
      │    ├── ActionBase.h 
      │    ├── APcopter 
      │    │   ├── APcopter_avoid.cpp 
      │    │   ├── APcopter_avoid.h 

Wenn Sie AUX_SOURCE_DIRECTORY verwenden Sie haben CMakeLists.txt jeden von Unterverzeichnisse hinzuzufügen. Dann müssen Sie alle diese Unterverzeichnisse einschließen und verknüpfen. Das ist eine ziemlich schwierige Aufgabe. So können Sie GLOB und die Arbeit sehr leicht machen. So wird es gemacht.

file(GLOB autopilot_sources ./*.cpp ./*/*.cpp ./*/*/*.cpp ./*/*/*/*.cpp ./*.c ./*/*.c ./*/*/*.c ./*/*/*/*.c) 
    SET(autopilot ${autopilot_sources}) 

Wenn Sie eine Bibliothek mit über Quellcode erstellen möchten, ist dies der Befehl:

ADD_LIBRARY (autopilot ${autopilot}) 
    TARGET_LINK_LIBRARIES (autopilot) 

Wenn Sie eine ausführbare Datei mit über Quellcode dieser erstellen möchten ist der Befehl:

ADD_EXECUTABLE(autopilot ${autopilot}) 
0

GLOB_RECURSE rekursiven Beispiel

Es macht im Grunde das * auch in Unterverzeichnissen gehen:

cmake_minimum_required(VERSION 3.0) 
file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "src/*.c") 
add_executable(main ${SOURCES}) 

Und dann könnten unsere Quellen beispielsweise angeordnet sein, wie:

src/main.c 
src/d/a.c 
src/d/a.h 

Und main.c#include "d/a.h" verwendet und a.c verwendet #include "a.h".

Mit GLOB_RECURSE auf dem CMake Toplevel (d "*.c" statt "src/*.c") ist wahrscheinlich eine schlechte Idee, da es .c Dateien von CMake erzeugt abholen kann sich die unter build/ gestellt werden.

Durchführbares Beispiel on GitHub.