我想将几个目录中的pdf文件复制到构建目录中,然后使用pdfunite将它们编译成一个pdf。下面的配方工作,但我必须运行两次,因为第一次通过,我从pdfunite得到一个错误 - 在构建目录中找不到文件(PDFS变量是空的),即使它们只是在以前复制过线。我如何解决这个问题,以便一次通过?为了清晰起见,我简化了配方;我实际上是从各种文件夹中提取并在运行中制作一些pdf,因此我无法轻松地连接各种子文件夹(示例中的folder1和folder2)的完整文件列表以传递给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 :(得分: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
时,它想要构建all
。 all
的要求是copy
- 所以make
执行了一些mkdir
和cp
。返回all
后:需要PDFS
的值,以便评估现在 - 我们在$(build)/notebook
中有多个pdf:)
答案 1 :(得分:0)
您的Makefile不符合make的理念。您正在使用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 $< $@
$(PDFS2): $(build)/notebook/%.pdf: $(data)/folder2/%.pdf | $(build)/notebook
cp $< $@
$(build)/notebook $(out):
mkdir -p $@
$(out)/notebook.pdf: $(PDFS) | $(out)
pdfunite $(PDFS) $@
变量定义相当简单:正如其名称所示,patsubst
替换字符串。 target: pattern: prerequisites
是static pattern rule。 |
之后的先决条件是order-only prerequisites。
这个makefile基本上说,$(out)/notebook.pdf
取决于$(build)/notebook/
中的一组pdf文件,并且这些pdf文件依赖于$(data)/folder1/
中具有相同基本名称的源pdf文件和$(data)/folder2/
。它还说必须在填充之前创建目录。多亏了这一切,只需要做的就是做,不多也不少。而且它更符合make的理念。
如果您有许多源文件夹但又不想复制复制规则,则可以使用更高级的功能,例如:
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 $$< $$@
endef
$(foreach f,$(FOLDERS),$(eval $(call MY_rule,$(f))))
$(build)/notebook $(out):
mkdir -p $@
$(out)/notebook.pdf: $(PDFS) | $(out)
pdfunite $(PDFS) $@