GNU Make для цикла с двумя переменными - PullRequest
9 голосов
/ 08 марта 2012

Я хочу написать что-то вроде этого:

$(foreach (var1, var2), ($(LIST1), $(LIST2)), cp $(var1) $(var2);)

Как мне сделать это в make-файле GNU?

Ответы [ 3 ]

9 голосов
/ 10 марта 2012

Предложение Beta использовать join находится на правильном пути, но проблема в том, что использовать его не так просто, чтобы создать командную строку, содержащую пробел, такую, как вы изначально хотели:*

потому что join объединяет слова: изначально он был предназначен для создания имен файлов.Однако вы можете подшутить;Вот пример использования объединения, которое дает вам искомый результат:

$(subst ^, ,$(join $(addprefix cp^,$(LIST1)),$(patsubst %,^%;,$(LIST2))))

Если вы считаете, что ваши списки могут содержать ^ символов, выберите другое.Дайте мне знать, если вам нужно это распаковано / объяснено.

3 голосов
/ 08 марта 2012
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 не имеет особого смысла.)

EDIT:
Ну, почему ты так не сказал?

LIST3 := $(join $(LIST1),$(LIST2))
1 голос
/ 30 октября 2015

Это хороший кандидат на gsml (стандартная библиотека GNU Make).Вы можете включить его, поместив файлы __gmsl и gml в текущий каталог (или в /usr/gnu/include, /usr/local/include/ и т. Д.) И добавив строку include gsml в ваш Makefile.Он включает в себя функцию 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;
...