我尝试使用Sphinx在 Makefile 中构建一些PDF。生成的PDF已经破坏了引用,因此我想使用pdftk来修复它们。
所以我想为我构建的所有PDF做的是:
# Creates the PDF files.
$(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) source/pdf/ $(BUILDDIR)/pdf_broken
# Go through all PDFs and fix them.
pdftk $(BUILDDIR)/pdf_broken/thepdf.pdf output $(BUILDDIR)/pdf/thepdf.pdf
所以要通过制作来做到这一点我写了 Makefile :
# Build PDF (results in broken references)
$(BUILDDIR)/pdf_broken/%.pdf:
$(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) source/pdf/ $(BUILDDIR)/pdf_broken
# This fixes the broken pdfs and produces the final result.
$(BUILDDIR)/pdf/%.pdf: $(BUILDDIR)/pdf_broken/%.pdf
mkdir -p $(BUILDDIR)/pdf/
pdftk $^ output $@
pdf: $(BUILDDIR)/pdf/%.pdf
我正在使用模式匹配,因为我从阅读手册中了解到: http://www.tack.ch/gnu/make-3.82/make_91.html
根据我的理解,$<
应该是从上面的例子扩展的先决条件:
$(BUILDDIR)/pdf_broken/thepdf.pdf
然后$@
应该是目标:
$(BUILDDIR)/pdf/thepdf.pdf
所以我的食谱pdftk $^ output $@
应该运行命令:
pdftk $(BUILDDIR)/pdf_broken/thepdf.pdf output $(BUILDDIR)/pdf/thepdf.pdf
但这不是正在发生的事情。相反,这是运行:
pdftk build/pdf_broken/%.pdf output build/pdf/%.pdf
这显然给了我一个错误:
Error: Unable to find file.
Error: Failed to open PDF file:
build/pdf_broken/%.pdf
所以我的问题是,我对模式匹配的工作原理有什么看法,以及使用制作来解决这个问题的正确方法是什么?
答案 0 :(得分:1)
您应该查找模式规则。在任何情况下,看起来您只有一个命令来生成损坏目录中的所有文件。这应该有自己的规则,并且应该输出一个虚拟文件来指示它是完整的。修复pdf文件的规则应该依赖于正在创建的虚拟目标。
应该是这样的:
// get a list of expected output files:
PDF_SOURCES:=$(wildcard source/pdf/*)
PDF_OUTS:=$(patsubst $(PDF_SOURCES),source/pdf/%.pdf,$(BUILDDIR)/pdf/%.pdf);
// just for debugging:
$(info PDF_SOURCES = $(PDF_SOURCES))
$(info PDF_OUTS = $(PDF_OUTS))
// default rule
all: $(PDF_OUTS)
@echo done
// rule to build BUILDIR:
$(BUILDDIR)/pdf:
mkdir -p $@
// rule to build all broken files in one go:
// (note: generates a file .dosphynx, which is used to keep track
// of when the rule was run last. This rule will be run if the
// timestamp of any of the sources are newer.
.do_sphynx: $(PDF_SOURCES) | $(BUILDDIR)/pdf
$(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) source/pdf/ $(BUILDDIR)/pdf_broken
touch $@
// create a dependency of all output files on do_sphynx
$(PDF_OUTS): .do_sphynx
// patern rule to fix pdf files
$(BUILDDIR)/pdf/%.pdf : $(BUILDDIR)/pdf_broken/%.pdf
pdftk $< output $@
我没有对此进行测试,因此可能会出现语法错误..
----------------------编辑-------------
好的,既然在makefile读取时无法确定$(PDF_OUTS)
,也许你应该这样做:
// get a list of expected output files:
PDF_SOURCES:=$(wildcard source/pdf/*)
all: .do_fix
@echo done
$(BUILDDIR)/pdf:
mkdir -p $@
.do_sphynx: $(PDF_SOURCES) | $(BUILDDIR)/pdf
$(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) source/pdf/ $(BUILDDIR)/pdf_broken
touch $@
.do_fix: .do_sphynx
@for src in $$(ls source/pdf/*.pdf); do \
trg=$${src/#"source/pdf"/"$(BUILD_DIR)/pdf"}; \
[[ $$src -nt $$trg ]] && \
echo "$$src ==> $$trg" && pdftk $$src output $$trg; \
done
touch $@
一个注意事项 - 如果-nt
不存在,if中的$trg
比较器将返回true,因此它将涵盖文件丢失或目标早于源的情况。再次没有测试,但它应该工作。