GNU Make 可以使用模式匹配来查找变量吗?

Can GNU Make use pattern matching to look up variables?

我正在尝试让 Make 构建一些数据分析,其中有由一个整体参数控制的文件列表。

明确地写成这样:

A_EXTS = a b c d e
B_EXTS = f g h i j
C_EXTS = k l m n o

A.dat : $(foreach EXT, ${A_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
    python analyse.py $^ > $@

B.dat : $(foreach EXT, ${B_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
    python analyse.py $^ > $@

C.dat : $(foreach EXT, ${C_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
    python analyse.py $^ > $@

显然这三个规则之间的唯一区别是 A vs B vs C.

我想试试

%.dat : $(foreach EXT, ${%_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
    python analyse.py $^ > $@

…但这行不通;例如make B.dat 运行 B.dat 的规则但忽略依赖关系; $^ 设置为空字符串。

prefix2_开头的文件是由另一个配方生成的,所以我不能只在配方中指定它们,它们需要在这里标记为依赖项。

是否可以在不重复相同规则的情况下表达这些依赖关系?

好吧,你不能像你想的那样做,但这与查找变量名无关:这是因为扩展顺序。

目标和先决条件中的变量在解析 makefile 时扩展,但 make 直到很久以后才扩展模式规则中的模式。这意味着当 make 在解析 makefile 时扩展 ${%_EXTS} 变量时,它不知道 % 的值稍后会在它实际尝试构建东西时。

您可以使用 secondary expansion to delay expansion of variables until make's second pass where it is actually finding target names. I pulled the logic out into a separate variable and used call 使其更具可读性:

.SECONDEXPANSION:

EXPANDDEPS = $(foreach EXT,${_EXTS},prefix1_${EXT}.dat prefix2_${EXT}.dat)

%.dat : $$(call EXPANDDEPS,$$*)
        python analyse.py $^ > $@