目前,我知道如何在Makefile
中循环的唯一方法就是调用shell的for循环:
BIN_TARGETS=foo bar baz
bin: $(BIN_TARGETS)
run: bin
for FILE in $(BIN_TARGETS) ; do ./$$FILE ; done
这个问题是make
只是调用shell的for循环,回显整个for循环,然后每个程序运行并输出它的输出(如果有任何错误,它们只报告在循环的结束,仅适用于循环中的最后一个程序):
$ make run
for FILE in foo bar baz ; do ./$FILE ; done
output of foo
output of bar
output of baz
是否有任何Makefile
- 级for
循环基本上与此完全相同?:
run: bin
./foo
./bar
./baz
将输出:
$ make run
./foo
output of foo
./bar
output of bar
./baz
output of baz
并会在发生任何错误时报告。
答案 0 :(得分:1)
make确实有一个循环,但没有一个可以做你想做的事。
make has $(foreach)
但是这是一个make-level结构,它将循环make语法/ etc。不是shell级别的东西。
define
可以让你按照自己想要的方式定义食谱的主体并在食谱中使用它,但是我无法想出一种从make中生成多行定义的方法。 / p>
这将起作用(就期望的行为而言)但我不能在make运行期间创建它。
define RECIPE
./foo
./bar
./baz
endef
all:
$(RECIPE)
答案 1 :(得分:1)
你可以这样做:
BIN_TARGETS:=foo bar baz
define CMD
$1
endef
bin: $(BIN_TARGETS)
run: bin
$(foreach t, $(BIN_TARGETS), $(call CMD,./$(t)))
CMD
变量是在命令之间提供正确分隔所必需的。我没有找到更简洁的方法。
如果foo
,bar
,baz
包含:
#!/bin/bash
echo output of $0
然后运行make run
输出:
./foo
output of ./foo
./bar
output of ./bar
./baz
output of ./baz
答案 2 :(得分:0)
我提出的一种方法是使用带有伪造后缀的虚假目标:
run: $(addsuffix .run,$(BIN_TARGETS))
%.run: %
./$*
然而,当foo.run
之类的内容存在多个可能的匹配时,这会变得混乱。唯一不同的是它编译并运行一个文件,然后运行下一个文件,而不是编译所有文件然后运行所有文件。