GNU machen mit vielen Zielverzeichnisse
-
06-09-2019 - |
Frage
Ich habe die Erzeugung von vielen HTML-Dateien in einem vorhandenen Makefile
zu integrieren.
Das Problem ist, dass die HTML-Dateien in vielen verschiedenen Verzeichnissen befinden müssen.
Meine Idee ist es, eine implizite Regel zu schreiben, die die Quelldatei konvertiert (* .st) in der entsprechenden HTML-Datei
%.html: %.st
$(HPC) -o $@ $<
und eine Regel, die auf allen HTML-Dateien
hängtall: $(html)
Wenn die HTML-Datei nicht im builddir make
ist nicht die implizite Regel finden: *** No rule to make target
.
Wenn ich die implizite Regel wie so ändern
$(rootdir)/build/doc/2009/06/01/%.html: %.st
$(HPC) -o $@ $<
es ist gefunden, aber dann muss ich für fast jede Datei in dem Projekt eine implizite Regel haben.
Nach implizite Regel Suchalgorithmus in der GNU make
Hand Regel Suche funktioniert wie folgt:
- Split t in ein Verzeichnis Teil, genannt d, und der Rest, genannt n. Zum Wenn beispielsweise t
src/foo.o', then d is
src ist / 'und n `foo.o'.- Erstellen Sie eine Liste der alle Muster Regeln eines von deren Zielen übereinstimmt t oder n. Wenn das Zielmuster enthält ein zerschneiden, wird abgeglichen gegen T; andernfalls gegen n.
Warum ist die implizite Regel nicht gefunden wird, und das, was die eleganteste Lösung wäre, vorausgesetzt, GNU make
verwendet wird?
Hier ist eine abgespeckte Version meiner Makefile
:
rootdir = /home/user/project/doc
HPC = /usr/local/bin/hpc
html = $(rootdir)/build/doc/2009/06/01/some.html
%.html: %.st
$(HPC) -o $@ $<
#This works, but requires a rule for every output dir
#$(rootdir)/build/doc/2009/06/01/%.html: %.st
# $(HPC) -o $@ $<
.PHONY: all
all: $(html)
Lösung
Wie Maria Shalnova ich wie rekursive make (obwohl ich mit „rekursive Make als schädlich“ nicht einverstanden ist), und im Allgemeinen ist es besser, etwas von einer Quelle HIER machen ES, nicht umgekehrt. Aber wenn Sie muss ich eine leichte Verbesserung vorschlagen: haben generateHtml erzeugen nur die Regel, nicht die Befehle
.Andere Tipps
Die beste Lösung, die ich bisher gefunden ist eine implizite Regel pro Zielverzeichnis über foreach-eval-Call , wie in der
Ihre aktive implizite Regel macht Die kommentierte out-Regel macht Eine Lösung ist Ihnen Quelle Layout zu machen sind Ihr Ziel / Ergebnis-Layout entsprechen. Eine andere Möglichkeit ist es, die Regeln zu erstellen, nach Bedarf mit $(rootdir)/build/doc/2009/06/01/some.html
auf $(rootdir)/build/doc/2009/06/01/some.st
abhängen. Wenn $(rootdir)/build/doc/2009/06/01/some.st
nicht existiert, dann wird die Regel nicht verwendet / gefunden werden. $(rootdir)/build/doc/2009/06/01/some.html
auf some.st
ab. eval
. Aber das wird ziemlich kompliziert: define HTML_template
$(1) : $(basename $(1))
cp $< $@
endef
$(foreach htmlfile,$(html),$(eval $(call HTML_template,$(htmlfile))))
Eine andere Möglichkeit ist es, das Kommando zu haben, sich mit dem Argument C mit jedem Ausgabeverzeichnis rekursiv make
zu nennen.
Rekursive make
ist etwas die Standardmethode mit Unterverzeichnissen beschäftigen, aber hüte dich vor den Auswirkungen in dem Artikel erwähnt „rekursiven Make als schädlich“