我想写一些关于以下方面的内容:
$(foreach (var1, var2), ($(LIST1), $(LIST2)), cp $(var1) $(var2);)
如何在 GNU makefile 中实现这个?
Beta 建议使用 join 是正确的方向,但问题在于如何以一种构建包含空格的命令行的方式来使用它,就像你最初想要的那样:
$(foreach (var1, var2), ($(LIST1), $(LIST2)), cp $(var1) $(var2);)
因为join可以将单词拼接在一起,它最初是用于构建文件名的。但是你可以使用一个技巧;以下是使用join以获得所需输出的示例:
$(subst ^, ,$(join $(addprefix cp^,$(LIST1)),$(patsubst %,^%;,$(LIST2))))
如果你认为你的列表可能包含^
字符,那么选择其他内容。如果需要进一步解释,请告诉我。
LIST1 := a b c
LIST2 := 1 2 3
# outside a rule:
$(foreach var1, a b c, $(foreach var2, 1 2 3, $(info $(var1)_$(var2))))
# inside a rule: first line starts with a TAB, all the rest are spaces
all:
@for x in $(LIST1);\
do \
for y in $(LIST2);\
do\
echo $$x $$y; \
done \
done
cp
并没有太多意义。LIST3 := $(join $(LIST1),$(LIST2))
a1 b2 c3
这样吗? - Beta这是一个很好的GNU Make标准库(gsml)候选项。您可以将文件__gmsl
和gml
放入当前目录(或/usr/gnu/include
,/usr/local/include/
等),并在Makefile中添加include gsml
行来包含它。它包括pairmap
函数,该函数正是您想要的(即zipWith
)。
include gmsl
cp2 = cp $1 $2;
zip = $1 : $2
$(LIST2):
@echo $(call pairmap, zip, $(LIST1), $(LIST2))
$(call pairmap, cp2, $(LIST1), $(LIST2))
输出
$ make
A : 1 B : 2 C : 3 D : 4
cp A 1; cp B 2; cp C 3; cp D 4;
seq
工具,它是一个 Unix 工具,在 Linux 和 Mac 上都可以使用。# Two lists
LIST1 = a1 a2 a3 a4
LIST2 = b1 b2 b3 b4
# This will generate
# LISTSEQ=1 2 3 4
LISTSEQ=$(shell seq $(words $(LIST1)))
# Print variable for example
define printvar
$(info $(1))
$(info $(2))
endef
# First line loops through 1 2 3 4
# and next line prints the corresponding value from LIST1 and LIST2
$(foreach j, $(LISTSEQ), \
$(call printvar,$(word $(j), $(LIST1)) $(word $(j), $(LIST2))) \
)
输出:
a1 b1
a2 b2
a3 b3
a4 b4