【发布时间】:2025-11-22 09:35:01
【问题描述】:
我正在尝试使用 Latexmk 编写一个使用 LaTeX 构建 PDF 输出的 Makefile。输出具有基本相同的规则,具有不同的先决条件,因此我尝试使用 GNU Make 的“二次扩展”来概括我的原始 Makefile。 (我还创建了 .PHONY 目标,也具有二级扩展,以使其更加用户友好。)但是,这导致先决条件规则始终运行,即使它们不需要成为。好在 Latexmk 足够聪明,可以避免做不必要的工作,但不知道是不是我做错了什么……
尝试抽象我正在尝试的内容:
,-> foo -> build/foo.pdf
all -{
`-> bar -> build/bar.pdf
即all 目标构建foo 和bar。这些目标打开各自的 PDF 文件,其先决条件为 build/X.pdf(其中 X 是 foo 或 bar)。这些是构建适当 PDF 文件的真正目标。
这是我想出的:
TARGETS = foo bar
BUILD_DIR = build
OUTPUTS = $(TARGETS:%=$(BUILD_DIR)/%.pdf)
commonSRC = src/preamble.tex src/header.tex # etc...
fooSRC = src/foo.tex $(commonSRC) # etc...
barSRC = src/bar.tex $(commonSRC) # etc...
all: $(TARGETS)
.SECONDEXPANSION:
$(TARGETS): $(BUILD_DIR)/$$@.pdf
open $<
# FIXME This isn't quite right: This rule is still getting called by the
# above rule, even when it doesn't need to be. Latexmk is clever enough
# not to do any extra work, but it shouldn't run at all.
.SECONDEXPANSION:
$(OUTPUTS): $$($$(subst .pdf,SRC,$$(@F))) $(BUILD_DIR)
latexmk -outdir=$(BUILD_DIR) -auxdir=$(BUILD_DIR) -pdf $<
$(BUILD_DIR):
mkdir $@
clean:
rm -rf $(BUILD_DIR)
.PHONY: all $(TARGETS) clean
要明确一点:只要XSRC 中枚举的文件(同样,X 是 foo 或 bar)比 PDF 更新,或者 PDF 不更新,build/X.pdf 的规则就应该运行不存在;但它不应该以其他方式运行。
【问题讨论】:
标签: makefile gnu-make expansion indirection