问题
I want to write something along these lines:
$(foreach (var1, var2), ($(LIST1), $(LIST2)), cp $(var1) $(var2);)
How do I go about doing this in a GNU makefile?
回答1:
Beta's suggestion to use join is on the right track, but the problem is that it's not so easy to use it in a way that constructs a command line containing whitespace, such as the one you originally wanted:
$(foreach (var1, var2), ($(LIST1), $(LIST2)), cp $(var1) $(var2);)
because join joins words together: it was originally intended for constructing filenames. However you can play a trick; here's an example of a way to use join that gives you the output you are looking for:
$(subst ^, ,$(join $(addprefix cp^,$(LIST1)),$(patsubst %,^%;,$(LIST2))))
If you think your lists might contain ^
characters then choose something else. Let me know if you need this unpacked/explained.
回答2:
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
(Please note that a nested loop that does cp
doesn't make much sense.)
EDIT:
Well why didn't you say so?
LIST3 := $(join $(LIST1),$(LIST2))
回答3:
This is a good candidate for gsml (GNU Make Standard Library). You can include it by putting the files __gmsl
and gml
in the current directory (or in /usr/gnu/include
, /usr/local/include/
etc.) and adding the line include gsml
in your Makefile. It includes the pairmap
function, which does exactly what you want (i.e. zipWith
).
include gmsl
cp2 = cp $1 $2;
zip = $1 : $2
$(LIST2):
@echo $(call pairmap, zip, $(LIST1), $(LIST2))
$(call pairmap, cp2, $(LIST1), $(LIST2))
Outputs
$ make
A : 1 B : 2 C : 3 D : 4
cp A 1; cp B 2; cp C 3; cp D 4;
来源:https://stackoverflow.com/questions/9622606/gnu-make-for-loop-with-two-variables