How to write loop in a Makefile?
I want to execute the following commands:
./a.out 1
./a.out 2
./a.out 3
./a.out 4
.
.
. and so on
How to write this thing as a loop in a Makefile
?
The following will do it if, as I assume by your use of ./a.out
, you're on a UNIX-type platform.
for number in 1 2 3 4 ; do \
./a.out $$number ; \
done
Test as follows:
target:
for number in 1 2 3 4 ; do \
echo $$number ; \
done
produces:
1
2
3
4
For bigger ranges, use:
target:
number=1 ; while [[ $$number -le 10 ]] ; do \
echo $$number ; \
((number = number + 1)) ; \
done
This outputs 1 through 10 inclusive, just change the while
terminating condition from 10 to 1000 for a much larger range as indicated in your comment.
Nested loops can be done thus:
target:
num1=1 ; while [[ $$num1 -le 4 ]] ; do \
num2=1 ; while [[ $$num2 -le 3 ]] ; do \
echo $$num1 $$num2 ; \
((num2 = num2 + 1)) ; \
done ; \
((num1 = num1 + 1)) ; \
done
producing:
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
4 1
4 2
4 3
If you're using GNU make, you could try
NUMBERS = 1 2 3 4 doit: $(foreach var,$(NUMBERS),./a.out $(var);)
which will generate and execute
./a.out 1; ./a.out 2; ./a.out 3; ./a.out 4;
THE major reason to use make IMHO is the -j
flag. make -j5
will run 5 shell commands at once. This is good if you have 4 CPUs say, and a good test of any makefile.
Basically, you want make to see something like:
.PHONY: all
all: job1 job2 job3
.PHONY: job1
job1: ; ./a.out 1
.PHONY: job2
job2: ; ./a.out 2
.PHONY: job3
job3: ; ./a.out 3
This is -j
friendly (a good sign). Can you spot the boiler-plate? We could write:
.PHONY: all job1 job2 job3
all: job1 job2 job3
job1 job2 job3: job%:
./a.out $*
for the same effect (yes, this is the same as the previous formulation as far as make is concerned, just a bit more compact).
A further bit of parameterisation so that you can specify a limit on the command-line (tedious as make
does not have any good arithmetic macros, so I'll cheat here and use $(shell ...)
)
LAST := 1000
NUMBERS := $(shell seq 1 ${LAST})
JOBS := $(addprefix job,${NUMBERS})
.PHONY: all ${JOBS}
all: ${JOBS} ; echo "$@ success"
${JOBS}: job%: ; ./a.out $*
You run this with make -j5 LAST=550
, with LAST
defaulting to 1000.