2017-08-09 2 views
0

Ich möchte PDF-Dateien aus mehreren Verzeichnissen in ein Build-Verzeichnis kopieren und dann mit pdfunite in ein PDF zusammenstellen. Das folgende make rezept funktioniert, aber ich muss es zweimal ausführen, weil beim ersten mal bekomme ich einen fehler von pdfunite - keine bausteine ​​im build-verzeichnis gefunden (die PDFS-variable ist leer), obwohl sie nur im vorherigen kopiert wurden Linien. Wie kann ich das beheben, so dass es in einem Durchgang funktioniert? Ich habe das Rezept für Klarheit vereinfacht; Ich ziehe tatsächlich von verschiedenen Ordnern und mache einige pdfs im laufenden Betrieb, so dass ich nicht einfach eine vollständige Liste von Dateien aus verschiedenen Unterordnern (Ordner1 und Ordner2 in dem Beispiel) verketten kann, um sie an pdfunite weiterzuleiten.make wildcard finde keine Dateien Ich habe einfach kopiert

notebook: 
    mkdir -p $(out) 
    mkdir -p $(build)/notebook 
    $(eval PR := $(sort $(wildcard $(data)/folder1/*.pdf))) 
    cp $(PR) $(build)/notebook 
    $(eval SR := $(sort $(wildcard $(data)/folder2/*.pdf))) 
    cp $(SR) $(build)/notebook 
    $(eval PDFS := $(sort $(wildcard $(build)/notebook/*.pdf))) 
    pdfunite $(PDFS) $(out)/notebook.pdf 
+0

Sind diese während des Build erzeugten PDF-Dateien? – fukanchik

+0

Ja, einige von ihnen sind (mit Pandoc), aber andere werden nur kopiert. –

Antwort

0

Ihr Makefile ist mit Make-Philosophie nicht im Einklang. Sie verwenden make als eine andere Skriptsprache, während make mehr ist. Es vergleicht Ziele und Vorbereitungsdaten, entscheidet auf dieser Grundlage, welche erstellt oder neu erstellt werden müssen und übergibt die Rezepte an die Shell. Also, für Ihr spezielles Problem, sollten Sie eher versuchen, so etwas wie:

PR := $(wildcard $(data)/folder1/*.pdf) 
SR := $(wildcard $(data)/folder2/*.pdf) 
PDFS1 := $(patsubst $(data)/folder1/%.pdf,$(build)/notebook/%.pdf,$(PR)) 
PDFS2 := $(patsubst $(data)/folder2/%.pdf,$(build)/notebook/%.pdf,$(SR)) 
PDFS := $(sort $(PDFS1) $(PDFS2)) 

.PHONY: notebook 

notebook: $(out)/notebook.pdf 

$(PDFS1): $(build)/notebook/%.pdf: $(data)/folder1/%.pdf | $(build)/notebook 
    cp $< [email protected] 

$(PDFS2): $(build)/notebook/%.pdf: $(data)/folder2/%.pdf | $(build)/notebook 
    cp $< [email protected] 

$(build)/notebook $(out): 
    mkdir -p [email protected] 

$(out)/notebook.pdf: $(PDFS) | $(out) 
    pdfunite $(PDFS) [email protected] 

Die Variablen Definitionen sind recht einfach: patsubst, wie der Name schon sagt, Streicher ersetzt. Die target: pattern: prerequisites ist eine static pattern rule. Und die Voraussetzungen nach | sind order-only prerequisites.

Was Make-Datei sagt, im Grunde ist, dass $(out)/notebook.pdf in $(build)/notebook/ auf einer Reihe von PDF-Dateien abhängig ist und dass diese PDF-Dateien sind abhängig von Quelle PDF-Dateien mit den gleichen Basisnamen in $(data)/folder1/ und $(data)/folder2/. Es besagt auch, dass Verzeichnisse erstellt werden müssen, bevor sie ausgefüllt werden. Dank all dem wird nur getan, was getan werden muss, nicht mehr und nicht weniger. Und es entspricht mehr der Philosophie von make.

Wenn Sie viele Quellordner haben und wollen nicht die Kopierregeln replizieren, können Sie erweiterte Funktionen wie verwenden:

FOLDERS := folder1 folder2 

.PHONY: notebook 

notebook: $(out)/notebook.pdf 

define MY_rule 
$(1)_SRCS := $$(wildcard $$(data)/$(1)/*.pdf) 
$(1)_DSTS := $$(patsubst $$(data)/$(1)/%.pdf,$$(build)/notebook/%.pdf,$$($(1)_SRCS)) 
PDFS  += $$($(1)_DSTS) 

$(1)_DSTS: $$(build)/notebook/%.pdf: $$(data)/$(1)/%.pdf | $$(build)/notebook 
    cp $$< [email protected] 
endef 

$(foreach f,$(FOLDERS),$(eval $(call MY_rule,$(f)))) 

$(build)/notebook $(out): 
    mkdir -p [email protected] 

$(out)/notebook.pdf: $(PDFS) | $(out) 
    pdfunite $(PDFS) [email protected] 
0

Ich würde einen anderen Weg gehen.

PR:=$(sort $(wildcard $(data)/folder1/*.pdf)) 
SR:=$(sort $(wildcard $(data)/folder2/*.pdf)) 
PDFS=$(sort $(wildcard $(build)/notebook/*.pdf)) 

all: copy 
    pdfunite $(PDFS) $(out)/notebook.pdf 

copy: 
    mkdir -p $(out) 
    mkdir -p $(build)/notebook 
    cp $(PR) $(build)/notebook 
    cp $(SR) $(build)/notebook 

.PHONY: all copy 

Bitte überprüfen Sie: PDFS= und nichtPDFS:=. Wenn Sie einfach = verwenden, wird der Wert der Variablen berechnet, wenn sie benötigt wird (früher!).

Wenn Sie make ausführen, möchten Sie all erstellen. Die all Anforderung ist copy - also make tut einige mkdir und cp. Nachdem es die all zurück: der Wert von PDFS benötigt wird, so jetzt wird evalute - Wir haben viele-viele pdf in $(build)/notebook :)

Verwandte Themen