3

我有许多乳胶文件,我希望能够方便地编译它们。我的makefile目前如下。

targets := $(patsubst %.tex, %.pdf, $(wildcard *.tex))
.PHONY: all

all: $(targets)

.SECONDEXPANSION:
%.pdf: %.tex $$(wildcard $$*_inc/*.*)
    pdflatex $<

这样,如果存在包含文件夹,则该文件夹中的所有内容都将被视为依赖项。

但是,我还想自动运行相关的 python 脚本。这些可能是绘图的创建或要包含的值的计算。我试图进行以下修改。

targets := $(patsubst %.tex, %.pdf, $(wildcard *.tex))

all: $(targets)
.PHONY: all run_%

.SECONDEXPANSION:
%.pdf: %.tex $$(wildcard $$*_inc/*.*) $$(patsubst %, run_%, $$(wildcard $$*_inc/*.py))
    pdflatex $<

run_%: %
    $<

但是,这并不像我期望的那样工作。我有以下文件夹结构。

|
|-Makefile
|-paper.tex
|-paper_inc/
|---a.txt
|---b.py

我希望它能够运行b.py,然后运行pdflatex paper.tex。但是,b.py是不运行的。如果我查看创建的依赖项,我会看到paper_inc/a.txt并且paper_inc/b.py是 的依赖项paper.pdf,但run_paper_inc/b.py不是。

我不完全确定这是什么问题,因为它觉得它应该起作用。此外,我还为%.pdf规则尝试了以下几行。

%.pdf: %.tex $$(wildcard $$*_inc/*.*) $$(addprefix run_,$$(wildcard $$*_inc/*.py))
%.pdf: %.tex $$(wildcard $$*_inc/*.*) $$(shell ls $$*_inc/*.py | sed 's/^/run/')
%.pdf: %.tex $$(wildcard $$*_inc/*.*) $$(shell ls $$*_inc/*.py | awk '{print "prefix "$0}')

但是,对于这些规则中的每一个,我都会收到错误消息make: *** No rule to make target 'paper.pdf'. Stop.

应该做些什么来解决这个错误,或者,我应该用什么来代替make

4

1 回答 1

0

你有两个问题。

第一的:

run_%: %
    $<

手册

当目标模式不包含斜杠(通常不包含)时,文件名中的目录名会在与目标前缀和后缀进行比较之前从文件名中删除。在将文件名与目标模式进行比较之后,目录名以及结束它们的斜线被添加到从模式规则的先决条件模式和文件名生成的先决条件文件名中。

这有点难以理解,但基本上当 Make 尝试构建时run_paper_inc/b.py,它会寻找匹配的模式规则b.py。上面的规则不符合。但这确实:

%.py:
    $(subst run_,,$@)

第二:

.SECONDEXPANSION:
%.pdf: ... $$(patsubst %, run_%, $$(wildcard $$*_inc/*.py))
    ...

Make 的一大缺点是它对通配符的处理很弱。在这种情况下%,不能同时用于模式规则和 patsubst。但是有一个办法:

.SECONDEXPANSION:
%.pdf: ... $$(addprefix run_,$$(wildcard %_inc/*.py))
    ...
于 2013-03-23T16:59:09.287 回答