Makefile命令以文件存在为条件

时间:2013-03-23 02:22:45

标签: unix makefile latex

我有很多乳胶文件,我希望能够方便地编译它们。我的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.txtpaper_inc/b.pypaper.pdf的依赖项,但run_paper_inc/b.py不是。{/ p>

我不完全确定这是什么问题,因为它认为它应该有效。此外,我还尝试了以下几行%.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

1 个答案:

答案 0 :(得分:0)

你有两个问题。

第一:

run_%: %
    $<

来自the manual

  

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

这有点难以理解,但基本上当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))
    ...