在Makefile的先决条件中重复使用百分号作为子目录名称

5
我希望学习如何在我的 makefile 目标的先决条件中重复使用 % 符号,假设目标是 X.pdf,先决条件位于 X/X.tex 中。
具体来说,我目前拥有以下 makefile:
all: foo.pdf

%.pdf: %.tex
    pdflatex $*.tex

我还有一个名为foo.tex的文件,当我输入make时,它会通过运行pdflatex foo.tex来生成foo.pdf

现在由于各种原因我无法控制,我的目录结构已经发生了改变:

my_dir
|- Makefile
|- foo
   |- foo.tex

我希望修改我的Makefile文件,使其在制作X.pdf时查找X/X.tex文件。
我尝试了以下内容(使用'% /%.tex'指定查找foo/foo.tex):
all: foo.pdf

%.pdf: %/%.tex
    pdflatex $*/$*.tex

然而,这会产生以下结果:
No rule to make target `foo.pdf', needed by `all'. Stop.

所以%.pdf: $*/$*.tex也是如此。
如果我将%/%.tex更改为foo/%.tex,它会按预期工作,但我不想在其中硬编码foo,因为将来我会执行all: foo.pdf bar.pdf,并且它应该查找foo/foo.texbar/bar.tex
我对Makefile相当新(经验仅限于修改其他人的Makefile以满足我的需求),从未做过超过绝对基本的Makefile,因此如果有人能给我一个指针,那将有所帮助(我真的不知道在Makefile文档中搜索哪些单词-唯一看起来有希望的是%$*,但我无法让它们工作)。

这比应该做的更难;处理通配符是Make非常糟糕的事情之一。虽然可以完成,但很丑陋,因此如果@wisent的解决方案对您的目的足够好,您应该选择它。 - Beta
1个回答

2
你可以使用VPATH来指定一组目录,让make命令搜索这些目录。
示例makefile:
# Find all tex files
tex := $(shell find -iname '*.tex')

# Make targets out of them
PDFS := $(notdir $(tex:%.tex=%.pdf))
# specify search folder
VPATH := $(dir $(tex))

all : $(PDFS)

%.pdf : %.tex
        pdflatex $<

甚至更好的方法是使用小写的vpath:
vpath %.tex $(dir $(tex))

它只会在这些目录中寻找.tex文件。

如果没有foo.tex但是有foo/foo.tex,那么这将工作得足够好。如果有一个./foo.tex或者bar/baz/foo.tex存在,你会遇到麻烦的。 - Beta
幸运的是,我不会遇到这个问题(我的所有%.tex都保证在一个文件夹%内)。对于我的目的来说,这很有效(尽管我很惊讶,不能在Makefile的先决条件中直接使用“$*”等,我认为我遇到的困难是由于我是Makefile新手所致)。谢谢! - mathematical.coffee
1
你可以使用 $* IFF(如果且仅如果):(a) 你有足够新的GNU make版本,(b) 你启用了.SECONDEXPANSION特殊目标,以及(c) 你将它们转义为$$*。请参阅GNU make手册以获取有关二次扩展的文档。 - MadScientist
@MadScientist:我们能够看到一下使用你所描述的技术的解决方案吗?这似乎很有趣,也可能展示一些高级的 Make 技巧。 - Clayton Stanley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接