2016-08-01 24 views
0

Ich habe eine Reihe von Dateien (*.txt), die ich verwende ein Python-Skript zu analysieren und Code (*.cpp) aus generieren. Sobald die Codegenerierung abgeschlossen ist, möchte ich, dass der generierte Code in Objektdateien kompiliert wird (*.o).Zwei-Schritt-Kompilierungsverfahren mit gnu make

Ich möchte gnu-make verwenden, um dies einzurichten. Mein Problem ist, dass ich eine funktionierende Makefile-Syntax nicht herausfinden kann, um dies zu erreichen.

Hier sind einige weitere Details, die diese schwieriger macht:

Da ich weiß nicht, wie viele * .txt-Dateien in erster Linie vorhanden ist, ich möchte, dass sie entdecken, mit einem shell find Befehl.

files := $(shell find $(TXT_FILE_DIR) -type f -name '*.txt')

Allerdings möchte ich noch Gnu-make die feinen Abhängigkeit Funktionen hier arbeiten. Das heißt, wenn sich eine der txt-Dateien ändert, möchte ich make automatisch diese und nur diese Änderungen erkennen und neue Dateien für sie generieren und sie in .o Dateien neu kompilieren.

Ich suche nach einer Lösung, wo make parallel ausgeführt werden können (und dem Parameter -J respektieren) und das Python-Skript aufrufen, die die *.txt Dateien in *.cpp Dateien übersetzt.

Mein Betriebssystem ist Linux.

[neue Informationen]

Danke Grexis, für Ihre Antwort! Da ich jedoch eine etwas seltsame Zuordnung zwischen src- und dst-Pfaden habe, suche ich eigentlich nach einer anderen Lösung. Hier

ist ein Beispiel für die „Kuriosität“, wenn mein src und dst-Pfade zu übersetzen:

$(TXT_DIR)/a/XXX.*XXX/b/c/file1.txt -> $(CPP_DIR)/a/YYY/b/c/file1.cpp $(TXT_DIR)/a/XXX.*XXX/b/c/file2.txt -> $(CPP_DIR)/a/YYY/b/c/file2.cpp $(TXT_DIR)/b/XXX.*XXX/c/d/file3.txt -> $(CPP_DIR)/b/YYY/c/d/file3.cpp

Hinweis hier, dass der Weg zweimal manipuliert wird. Daher beide:

  1. $(TXT_DIR)XXX.*XXX mit $(CPP_DIR) und
  2. Der reguläre Ausdruck ersetzt wird, wird mit dem festen Zeichenkette ersetzt YYY

Aufgrund dass seine schwer, eine Mehrfachzeichenfolge Ersatz zu tun in gnu-make, zB gnu-make, unterstützt nur eine einzige% (stem) String Ersetzung auf einmal, ich denke ich muss eine fortgeschrittenere Gnu-make Syntax verwenden. Aus diesem Grund suche ich nach einer Möglichkeit, für jedes->.cpp Paar ein eigenes Rezept zu definieren. Ich habe folgendes versucht:

cleanPath = $(shell echo $(1) | sed s/XXX.*XXX/YYY/g) txt2cpp = $(subst $(TXT_DIR),$(CPP_DIR),$(patsubst %.txt,%.cpp,$(call cleanPath,$(1)))) txt2obj = $(subst $(TXT_DIR),$(OBJ_DIR),$(patsubst %.txt,%.o,$(call cleanPath,$(1)))) define analyse = $(2): $(1) python.py $(2) $(3) endef txt_files := $(shell find $(TXT_DIR) -type f -name '*.txt') cpps := $(foreach file,$(txt_files),$(eval $(call analyse,$(file),$(call txt2cpp,$(file)),$(call txt2obj,$(file))))) all: $(cpps)

Allerdings scheint es meine python.py Skript nie aufgerufen. Warum das?

Wenn ich die Berufung auf die python.py in einem shell -command umschließen, zum Beispiel $(shell python.py $(2) $(3)), die python.py Skript tatsächlich aufgerufen. Die Verwendung eines Befehls shell macht jedoch Parallelität unmöglich.Leider ist es nicht möglich, das Skript python.py parallel auszuführen.

Antwort

0

Es ist ein wenig unklar, ob jede Textdatei genau eine C++ - Quelle mit einem passenden Namen erzeugt (d. H. "Foo.txt" wird in "foo.cpp" und dann "foo.o" verarbeitet).

Angenommen, es handelt sich um eine direkte Beziehung, die Funktion, die Sie suchen, heißt Pattern Rules.

TXT_FILES := $(wildcard $(TXT_FILE_DIR)/*.txt) 
OBJ_FILES := $(patsubst $(TXT_FILE_DIR)/%.txt,$(OUT_DIR)/%.o,$(TXT_FILES)) 

main: $(OBJ_FILES) 
    $(CXX) $(LDFLAGS) -o [email protected] $^ 

$(SRC_DIR)/%.cpp: $(TXT_FILE_DIR)/%.txt 
    $(PYTHON) process.py $< 

$(OUT_DIR)/%.o: $(SRC_DIR)/%.cpp 
    $(CXX) -c $(CPPFLAGS) -o [email protected] $< 

Brechen Sie das obige Schnipsel auf. $(TXT_FILES) wird auf jede *.txt Datei in $(TXT_FILE_DIR) mit der Wildcard-Operation in make gesetzt. $(OBJ_FILES) verwendet eine Musterersetzung mit allen Werten in $(TXT_FILES). Jede obj-Datei wird dann als eine Abhängigkeit zu der ausführbaren Datei main hinzugefügt.

Wie in der Pattern Rules Link Dokumentation erklärte oben verknüpft, jede .o Datei muss die zugehörige .cpp Datei in $(SRC_DIR) (Die automatischen Variablen [email protected], $^ und $< werden auch in dem darin enthaltenen Link dokumentiert). Jede .cpp Datei wiederum benötigt eine .txt mit dem gleichen Namen.

Sie müssen wahrscheinlich den genauen Aufruf Ihres Python-Skripts optimieren. Wenn eine bestimmte Ausgabedatei angegeben werden muss, sollte die automatische Variable [email protected] verwendet werden.

Der Abschnitt oben zum Erkennen aller Quelldateien wurde von this answer abgeleitet.

+0

Ich mag diese Antwort, aber ich denke, dass es verbessert werden würde, indem man die Musterregeln in _statische Musterregeln_ ändert. Ganz einfach in diesem Fall: $ {OBJ_FILES}: $ {OUT_DIR} /%. O: $ {SRC_DIR} /% .cpp' – bobbogo