2017-08-09 99 views
0

我想將幾個目錄中的pdf文件複製到構建目錄中,然後使用pdfunite將它們編譯成一個pdf。以下使配方工作,但我必須運行它兩次,因爲第一次通過,我從pdfunite中得到一個錯誤 - 在構建目錄中找不到任何文件(PDFS變量爲空),即使它們剛剛在之前被複制過線。我該如何解決這個問題,以便它可以在一次傳遞中運行爲了清晰起見,我簡化了配方。我實際上是從各種文件夾中拉出來,並且隨時製作一些pdf文件,所以我無法輕鬆地連接來自各個子文件夾(示例中的文件夾1和文件夾2)的完整列表以傳遞給pdfunite。使通配符找不到我剛剛複製的文件

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

是構建過程中產生的這些PDF? – fukanchik

+0

是的,其中一些是(使用pandoc),但其他人只是複製。 –

回答

0

你的Makefile不符合化妝的理念線多對多的PDF文件。您使用make作爲另一種腳本語言,而make則不止這些。它比較目標和先決條件日期,基於此確定必須構建或重新構建哪些日期,並將配方傳遞到shell。因此,對於您的特定問題,您應該寧可嘗試類似:

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] 

的變量定義相當簡單:patsubst,如它的名字一樣,替換字符串。 target: pattern: prerequisitesstatic pattern rule。並且|之後的先決條件是order-only prerequisites

什麼這個Makefile說,基本上,是$(out)/notebook.pdf依賴於一組PDF文件$(build)/notebook/,而這些PDF文件取決於源PDF文件,在$(data)/folder1/$(data)/folder2/相同基本名稱。它還說目錄必須在填充之前創建。多虧了這一切,只有需要做的事情將會完成,不多也不少。它更符合品牌的哲學。

如果你有很多的源文件夾,並且不希望複製複製的規則,你可以使用更先進的功能,如:

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

我會做另一種方式。

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 

請檢查:PDFS=PDFS:=。如果您使用簡單的=,變量的值將在需要時計算(不會更早!)。

當您運行make它希望生成allall的要求是copy - 所以make做了一些mkdircp。之後,它返回all:需要的PDFS值,以便將evalute 現在 - 我們在$(build)/notebook :)