1

Bash can produce permutations (cartesian product):

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

I would like to do something similar with a makefile. Here is an example makefile:

all: 1a 1b 2a 2b

I would like something like this if possible:

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

However when I use an example like that it just creates "1 2a b" instead of combining them. Is this possible?

2 Answers2

2

No need for any complex loops or borrowing from shell. It is much simpler than that.

$(foreach p, $(NOV), $(addprefix $p, $(OSC)))
Mark Galeck
  • 6,155
  • 1
  • 28
  • 55
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" "$^"

Output:

$ 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

Note: the SHELL is needed because brace expansion isn't a POSIX feature. The shell used by GNU Make is /bin/sh by default. When Bash is run as /bin/sh, it doesn't support brace expansion.

Kaz
  • 55,781
  • 9
  • 100
  • 149
  • Make doesn't work without the shell. Every recipe line in a Makefile is shell syntax, for which a separate shell process is launched, so that you can't do a `cd` in one line and have it be in that directory in the next line. So basically, that is moot. The concrete aspect of this that is not "clean" is that a comma-separated data representation is used which doesn't play nicely as a Make word list. – Kaz Jan 27 '16 at 03:33
  • However, the final `EXP` variable does, at least, for what it's worth. I put the foreach approaches into the same Makefile. Side by side comparison. :) – Kaz Jan 27 '16 at 03:40