我想执行以下命令:
./a.out 1
./a.out 2
./a.out 3
./a.out 4
.
.
. and so on
如何写这个东西作为一个循环在Makefile?
我想执行以下命令:
./a.out 1
./a.out 2
./a.out 3
./a.out 4
.
.
. and so on
如何写这个东西作为一个循环在Makefile?
当前回答
也许你可以用:
xxx:
for i in `seq 1 4`; do ./a.out $$i; done;
其他回答
使用make的主要原因是-j标志。Make -j5将同时运行5个shell命令。如果你有4个cpu,这是一个很好的makefile测试。
基本上,你想看到的是:
.PHONY: all
all: job1 job2 job3
.PHONY: job1
job1: ; ./a.out 1
.PHONY: job2
job2: ; ./a.out 2
.PHONY: job3
job3: ; ./a.out 3
这是-j友好的(一个好迹象)。你能认出那个锅炉盘吗?我们可以写成:
.PHONY: all job1 job2 job3
all: job1 job2 job3
job1 job2 job3: job%:
./a.out $*
为了达到同样的效果(是的,就make而言,这与前面的公式相同,只是更紧凑一点)。
进一步的参数化,这样你就可以在命令行上指定一个限制(因为make没有任何好的算术宏,所以我在这里作弊,使用$(shell…)))
LAST := 1000
NUMBERS := $(shell seq 1 ${LAST})
JOBS := $(addprefix job,${NUMBERS})
.PHONY: all ${JOBS}
all: ${JOBS} ; echo "$@ success"
${JOBS}: job%: ; ./a.out $*
您可以使用make -j5 LAST=550运行该命令,其中LAST默认为1000。
为了跨平台支持,让命令分隔符(用于在同一行上执行多个命令)成为可配置的。
例如,如果你在Windows平台上使用MinGW,命令分隔符是&:
NUMBERS = 1 2 3 4
CMDSEP = &
doit:
$(foreach number,$(NUMBERS),./a.out $(number) $(CMDSEP))
这将在一行中执行连接的命令:
./a.out 1 & ./a.out 2 & ./a.out 3 & ./a.out 4 &
正如前面提到的,在*nix平台上使用CMDSEP =;
如果您正在使用GNU make,您可以尝试一下
NUMBERS = 1 2 3 4 doit: $(foreach var,$(NUMBERS),./a.out $(var);)
哪个将生成并执行
./a.out 1; ./a.out 2; ./a.out 3; ./a.out 4;
您可以使用set -e作为for循环的前缀。例子:
all:
set -e; for a in 1 2 3; do /bin/false; echo $$a; done
Make将立即退出,退出代码<> 0。
如果你使用。/a,下面就可以做到这一点。out,你就在一个unix类型的平台上。
for number in 1 2 3 4 ; do \
./a.out $$number ; \
done
测试如下:
target:
for number in 1 2 3 4 ; do \
echo $$number ; \
done
生产:
1
2
3
4
对于更大的范围,使用:
target:
number=1 ; while [[ $$number -le 10 ]] ; do \
echo $$number ; \
((number = number + 1)) ; \
done
这将输出1到10(包含10),只需将while终止条件从10更改为1000,以获得更大的范围,如您的注释所示。
嵌套循环可以这样完成:
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
生产:
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
4 1
4 2
4 3