我有一个产品清单:
这取决于不同的来源列表:
依赖性是一对一的(第一个列表的第n个元素将第二个列表的第n个元素作为其源),并且配方在所有情况下都是相同的。出于所有意图和目的,列表中没有结构 - 不可能编写允许从n生成列表的第n个元素的简单表达式。我知道的解决方案是
1 : z
[recipe]
2 : y
[identical recipe]
3 : x
[identical recipe]
4 : w
[identical recipe]
...但我不喜欢这样,因为它在修改列表或配方时更容易出错。我更愿意利用对应模式并以
开头SRCLIST = z y x w
DSTLIST = 1 2 3 4
然后以某种方式有像
这样的一般规则DSTLIST_n : SRCLIST_n
[recipe]
有没有办法做这样的事情?
答案 0 :(得分:1)
这有点难看,但我相信它应该有用。 (可能会有更好的方法,但这是我想出的第一件事。)
SRCLIST = z y x w
DSTLIST = 1 2 3 4
# Create a list of : the length of SRCLIST
MIDLIST = $(foreach s,$(SRCLIST),:)
$(info SRCLIST:$(SRCLIST))
$(info DSTLIST:$(DSTLIST))
$(info MIDLIST:$(MIDLIST))
# Join the three lists together (in two passes since $(join) only takes two lists)
JOINLIST = $(join $(join $(DSTLIST),$(MIDLIST)),$(SRCLIST))
$(info joined:$(JOINLIST))
# eval each of the created strings to create the prerequisite entries
$(foreach r,$(JOINLIST),$(eval $r))
# Set the rules to build all the targets.
$(DSTLIST):
echo '$@ for $^'
$ touch z y x w
$ make
SRCLIST:z y x w
DSTLIST:1 2 3 4
MIDLIST:: : : :
joined:1:z 2:y 3:x 4:w
echo '1 for z'
1 for z
echo '2 for y'
2 for y
echo '3 for x'
3 for x
echo '4 for w'
4 for w
我应该注意,这根本不会处理任何条目中的空格(但通常情况下,这对于此解决方案而言并非特定)。
你也可以随时创建一个Canned Recipe然后将其粘贴在每个明确写出的目标中,就像你原来的想法一样。
答案 1 :(得分:1)
受Etan的启发,这是我发现的工作:
SRCLIST = z y x w
DSTLIST = 1 2 3 4
# Make a list of ":" for combining
SEPARATOR = $(foreach s,$(SRCLIST),:)
# Define a parameterized rule which accepts the dst:src info as an argument
define dst-src
$1
[rule]
endef
# Define the list of dependencies
DST_SRC_RELNS = $(join $(join $(DSTCLIST),$(SEPARATOR)),$(SRCLIST))
# ^ DST_SRC_RELNS evaluates to z:1 y:2 x:3 w:4
# Print a preview of the rules the makefile generates itself
$(info $(foreach r,$(DST_SRC_RELNS),$(call dst-src,$r)))
# Generate the rules
$(foreach r,$(DST_SRC_RELNS),$(eval $(call dst-src,$r)))
我认为你可以通过在dst-src
内部实际编写规则来定义参数化规则$(eval ...)
,但我不喜欢这样做有两个原因:
newline
宏,使其成为可以识别的规则$(foreach ...)
中添加更多文字,让人类读者更难找出真正发生的事情答案 2 :(得分:1)
.SECONDEXPANSION
通常适用于这些类型的源查找表。
草图:
srcs := z x y w
targets := 1 2 3 4
.SECONDEXPANSION:
pairs := $(join ${targets},$(addprefix :,${srcs}))
lookup-src = $(patsubst $1:%,%,$(filter $1:%,${pairs}))
${targets}: $$(call lookup-src,$$@)
echo '[$^] -> [$@]'