我想执行以下命令:

./a.out 1
./a.out 2
./a.out 3
./a.out 4
.
.
. and so on

如何写这个东西作为一个循环在Makefile?


当前回答

一个简单的、独立于shell/平台的纯宏解决方案是…

# GNU make (`gmake`) compatible; ref: <https://www.gnu.org/software/make/manual>
define EOL

$()
endef
%sequence = $(if $(word ${1},${2}),$(wordlist 1,${1},${2}),$(call %sequence,${1},${2} $(words _ ${2})))

.PHONY: target
target:
    $(foreach i,$(call %sequence,10),./a.out ${i}${EOL})

其他回答

这招对我很管用:

NUM=4

a-out:
    for (( i=1; i<=${NUM}; i++ )) \
    do \
        ./a.out $$i ; \
    done

您可以使用set -e作为for循环的前缀。例子:

all:
    set -e; for a in 1 2 3; do /bin/false; echo $$a; done

Make将立即退出,退出代码<> 0。

这并不是对这个问题的纯粹回答,而是一种解决这类问题的聪明方法:

而不是写一个复杂的文件,简单地委托控制,例如一个bash脚本: makefile

foo : bar.cpp baz.h
    bash script.sh

script.sh是这样的:

for number in 1 2 3 4
do
    ./a.out $number
done

为了跨平台支持,让命令分隔符(用于在同一行上执行多个命令)成为可配置的。

例如,如果你在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 =;

也许你可以用:

xxx:
    for i in `seq 1 4`; do ./a.out $$i; done;