2016-01-27 3 views
1

Bash может привести к перестановкам (cartesian product):Makefile перестановка

$ echo {1,2}{a,b} 
1a 1b 2a 2b 

Я хотел бы сделать что-то подобное с Makefile. Вот пример Makefile:

all: 1a 1b 2a 2b 

Я хотел бы что-то подобное, если это возможно:

NOV = 1 2 
OSC = a b 
all: $(NOV)$(OSC) 

Однако, когда я использую пример, как, что он просто создает «1 2а б» вместо комбинирования их. Это возможно?

ответ

0
SHELL := /bin/bash 

NOV := 1,2 
OSC := a,b 

NOVW := 1 2 
OSCW := a b 

EXP := $(shell printf "%s " {$(NOV)}{$(OSC)}) 
EXPW := $(foreach X,$(NOVW),$(foreach Y,$(OSCW),$(X)$(Y))) 

.PHONY: all a b $(EXP) $(EXPW) 

all: a b 

a: $(EXP) 
    @echo target a 
    @printf "my first prerequisite is %s\n" "$<" 
    @printf "all my prerequisites are %s\n" "$^" 

b: $(EXPW) 
    @echo target b 
    @printf "my first prerequisite is %s\n" "$<" 
    @printf "all my prerequisites are %s\n" "$^" 

Выход:

 
$ make 
target a 
my first prerequisite is 1a 
all my prerequisites are 1a 1b 2a 2b 
target b 
my first prerequisite is 1a 
all my prerequisites are 1a 1b 2a 2b 

Примечание: SHELL необходимо потому, что в фигурных скобках не является функцией POSIX. Оболочка, используемая GNU Make, равна /bin/sh по умолчанию. Когда Bash запущен как /bin/sh, он не поддерживает расширение скобки.

+0

Марка не работает без оболочки. Каждая строка рецепта в файле Makefile представляет собой синтаксис оболочки, для которого запускается отдельный процесс оболочки, так что вы не можете выполнить 'cd' в одной строке и быть в этом каталоге в следующей строке. Таким образом, в принципе, это спорный вопрос. Конкретный аспект этого, который не является «чистым», заключается в том, что используется представление данных с разделителями-запятыми, которое не играет хорошо как список «Список слов». – Kaz

+0

Однако конечная переменная 'EXP' делает, по крайней мере, то, что она стоит. Я помещал foreach в один и тот же Makefile. Сравнение бок о бок. :) – Kaz

1

Не требуется никаких сложных циклов или заимствований из оболочки. Это намного проще.

$(foreach p, $(NOV), $(addprefix $p, $(OSC)))