makefile不扩展动态先决条件

时间:2018-04-19 09:58:04

标签: makefile gnu-make

我想要一个makefile,它会将一些字符串作为某些文件的前缀(NAMES),并从那里开始处理目标和必备文件名。例如,在下面的示例中,我们的想法是将2个csv文件(foo.csvbar.csv)转换为表格(尽管我只是回应目标和先决条件)。

NAMES = foo bar

PR = $(patsubst %,%.csv,$(NAMES))
TB = $(patsubst %,%.tsv,$(NAMES))

all: $(TB)

%.tsv: $(PR)
    @echo $< $@

打印:

foo.csv foo.tsv
foo.csv bar.tsv

因此,看起来makefile没有正确扩展PR中的先决条件,因为我希望在第二行看到bar.csv bar.tsv

但是,如果我打印$PR$TB,两者似乎都设置正确:

$(info $$PR is [${PR}])
$(info $$TB is [${TB}])
# prints
$PR is [foo.csv bar.csv]
$TB is [foo.tsv bar.tsv]

知道如何让它正常工作吗?

请注意,我在工作目录中有foo.csvbar.csv个文件。

1 个答案:

答案 0 :(得分:2)

问题在于您使用内置变量$<的方式。如果手动展开变量并重写makefile,则变为......

NAMES = foo bar

PR = $(patsubst %,%.csv,$(NAMES))
TB = $(patsubst %,%.tsv,$(NAMES))

all: foo.tsv bar.tsv

%.tsv: foo.csv bar.csv
    @echo $< $@

$<引用的the first prerequisite始终为foo.csv,无论目标是什么。

一种解决方案可能是使用scoped static pattern rule。所以......就像......

NAMES = foo bar

PR = $(patsubst %,%.csv,$(NAMES))
TB = $(patsubst %,%.tsv,$(NAMES))

all: $(TB)

# Tell make how to build a .tsv from a .csv but constrain the rule
# so that it only applies to .tsv files that are part of $(TB).
#
$(TB): %.tsv: %.csv
    @echo 'building target [$@] with $$< = [$<]'

上述结果为......

building target [foo.tsv] with $< = [foo.csv]
building target [bar.tsv] with $< = [bar.csv]