2012-06-06 3 views
21

Die CMake documentation explizit besagt, dass file(GLOB ...) ist nicht empfohlen, um Quelldateien für einen Build zu sammeln, aber es ist nicht Erwähnung, was die empfohlene Methode tatsächlich ist.Wie sammle ich Quelldateien mit CMake ohne globbing?

Angabe jeder Quelldatei manuell klingt ein wenig zu manuell zu mir. Also, was ist die richtige Methode, um Quelldateien zu sammeln, wenn nicht file(GLOB ...)?

+0

Sie GLOB von cmake in einem Skript verwenden könnte und haben, dass die Dateinamen auskippen hinzufügen. – Damian

Antwort

17

Handbuch ist in der Tat die empfohlene Methode. Mit der Empfehlung gegen die Verwendung von GLOB warnt die Dokumentation lediglich vor einem Build-System, das von vorhandenen Dateien abhängig ist. Wenn Sie beispielsweise eine ausführbare Testdatei hinzufügen möchten, erstellen Sie mytest.cpp. Hoppla. Jetzt bricht deine Bibliothekszusammenstellung zusammen. Die Dokumentation für AUX_SOURCE_DIRECTORY (ähnlichen Zweck wie Globbing für für Quelldateien) gibt die folgende Warnung:

Es ist verlockend, diesen Befehl zu verwenden Schreiben die Liste der Quelle für eine Bibliothek oder ein ausführbares Ziel Dateien zu vermeiden. 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.

Wenn Sie sicher sind, dass Sie alle Inhalte eines Verzeichnisses haben möchten und nicht planen, neue hinzuzufügen, dann verwenden Sie unbedingt einen GLOB.

Vergessen Sie auch nicht, dass das manuelle Auflisten von Dateien nicht die Eingabe aller Dateinamen erfordert. Sie können beispielsweise ls *.cpp >> CMakeLists.txt eingeben und dann mit Ihrem Editor die Liste der Dateien an die richtige Stelle in der Datei verschieben.

+0

Art der Abhängigkeit von der IDE tbh. In Qt Creator wird CMake immer erneut ausgeführt, sodass die Verwendung von GLOB kein Problem darstellt. – Lap

+2

'printf" add_library (xxx $ (ls * .cpp)) ">> CMakeLists.txt' sollte auch nett sein! – Alex

+0

Ich denke nicht, dass Ihre Komplikation eine gültige ist, weil Test normalerweise im Testordner ist und den Quellbaum nicht durcheinander bringen sollte. – Arne

12

Ich benutze GLOB für genau dieses und jedes Mal, wenn ich eine Datei hinzufügen I

touch ../src/CMakeLists.txt 

Der nächste make Befehl erneut scannen, um die Verzeichnisse laufen.

"Es gibt keine Möglichkeit für CMake, ein Build-System zu generieren, das weiß, wann eine neue Quelldatei hinzugefügt wurde" Wirklich? Okay, also sagen Sie es!

Es ist nicht 100% automatisch, aber ein verdammter Anblick einfacher als Dateien manuell hinzufügen.

1

Ich verwende cog, ein Python-Modul. Hier ist ein Beispiel ist CPP-Datei zu sammeln:

Die CMakeLists.txt:

set(SRC_FILES "") 

# [[[cog 
# import cog, glob 
# for src in glob.glob('*.cpp'): 
#  if "skeleton" in src: continue 
#  cog.outl("SET(SRC_FILES ${SRC_FILES} %s)" % src) 
# ]]] 
# [[[end]]] 

add_library(mylib STATIC ${SRC_FILES}) 

Und dann laufen:

python -m cogapp -r CMakeLists.txt 

Die CMakeLists.txt Datei an Ort und Stelle aktualisiert werden.

Für die Installation von Zahnrädern und anderen Anwendungen lesen Sie bitte the article from the author.

0

Ich verwende eine konventionelle CMakeLists.txt und ein Python-Skript, um es zu aktualisieren. Ich führe das Python-Skript nach dem Hinzufügen von Dateien manuell aus.

import os 
import re  

def relFiles(base, sub): 
    fullSub = os.path.join(base,sub) 
    abs = [os.path.join(dp, f) for dp, dn, fn in os.walk(fullSub) for f in fn] 
    return [os.path.relpath(f, base) for f in abs] 

def updateAddLibrary(cmakelistsDir, subs): 
    cmakelists = os.path.join(cmakelistsDir, "CMakeLists.txt") 
    listings = [relFiles(cmakelistsDir, sub) for sub in subs] 
    files = [f for listing in listings for f in listing] #flatten 
    with open(cmakelists, 'r') as file: 
     text = file.read() 
    sources = "".join([" %s\n" % f.replace('\\', '/') for f in files]) 
    text = re.sub(r"add_library\s*\(\s*([^\s\)]+).*?\)", 
      r"add_library(\1\n%s)" % sources, 
      text, 1, re.DOTALL) 
    with open(cmakelists, "w") as file: 
     file.write(text) 

dir = os.path.dirname(os.path.abspath(__file__)) 
updateAddLibrary(dir, ['inc','src']) 

Beispiel vor:

... 
add_library(MyLib 
    inc/a.h 
) 
... 

nach:

... 
add_library(MyLib 
    inc/a.h 
    inc/sub/b.h 
    src/a.cpp 
)   
... 
Verwandte Themen