您对make 如何处理列表的误解。如果你有一个变量:
names = stem1 stem2 stem3
然后make 将其作为列表处理但每次命名此变量时都会一次实例化整个列表内容。 它不会对列表内容进行一对一的操作,因为这将接近于无法控制,具体取决于具体情况。相反,它采用简单的文本替换,因此您的行
all: $(names:%=dir/prefix_%.txt) $(names:%=dir/another_%.txt)
被非常简单地解析和变量替换成一个字符串:
all: dir/prefix_stem1.txt dir/prefix_stem2.txt dir/prefix_stem3.txt ...etc...
迭代列表处理只发生在$(names:%=dir/prefix_%.txt) 内,以此类推,而行本身,在变量替换之后,只是输入到第二个解析步骤的文本。
按照你的规则:
$(names:%=dir/prefix_%.txt): $(names:%=sourcedir/yetanother_%.xlsx)
扩展到
dir/prefix_stem1.txt dir/prefix_stem2.txt dir/prefix_stem3.txt: sourcedir/yetanother_stem1.xlsx sourcedir/yetanother_stem2.xlsx sourcedir/yetanother_stem3.xlsx
这是三个规则的简写:
dir/prefix_stem1.txt: sourcedir/yetanother_stem1.xlsx sourcedir/yetanother_stem2.xlsx sourcedir/yetanother_stem3.xlsx
dir/prefix_stem2.txt: sourcedir/yetanother_stem1.xlsx sourcedir/yetanother_stem2.xlsx sourcedir/yetanother_stem3.xlsx
dir/prefix_stem3.txt: sourcedir/yetanother_stem1.xlsx sourcedir/yetanother_stem2.xlsx sourcedir/yetanother_stem3.xlsx
没有别的。显然你告诉 make 每个目标都依赖于所有的先决条件。
稍作调整和Static Pattern Rules,您就可以实现您的目标:
MY_TARGETS := $(names:%=dir/prefix_%.txt) # create full target names
$(MY_TARGETS) : dir/prefix_%.txt : sourcedir/yetanother_%.xslx