Makefile make:自动执行目标

Makefile make:自动执行目标,makefile,gnu-make,Makefile,Gnu Make,在我的项目中,我有一套从源代码构建的程序: SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp) TARGETS = $(patsubst $(SRC_DIR)/%.cpp,$(BIN_DIR)/%,$(SRC_FILES)) 我的构建目标很简单,而且运行良好: all: $(TARGETS) @echo "- Done target $@" 现在,我需要一个run目标,这样所有这些程序都可以根据请求从shell运行。比方说,如果我有3个文件,我希望使

在我的项目中,我有一套从源代码构建的程序:

SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp)
TARGETS   = $(patsubst $(SRC_DIR)/%.cpp,$(BIN_DIR)/%,$(SRC_FILES))
我的构建目标很简单,而且运行良好:

all: $(TARGETS)
    @echo "- Done target $@"
现在,我需要一个
run
目标,这样所有这些程序都可以根据请求从shell运行。比方说,如果我有3个文件,我希望使其自动运行:

>$ ./test1
>$ ./test2
>$ ./test3

我试过这个:

run: $(TARGETS)
   $(addsuffix && ,$(TARGETS))
将生成以下命令:

./test1&& ./test2&&
但是由于后面的
&

(当然,我希望自动生成这些,因为可能有3…或30个。)

编辑:实际上,不需要使用
和&
分隔符,因此如下所示:

>$ ./test1; ./test2; ./test3;

也可以。

Makefile
开头附近有一些
.PHONY

 .PHONY: all run
你可能有

 run: $(TARGETS)
     $(addsuffix && ,$(TARGETS)) true
但这是一个肮脏的把戏

也许您想要将
test2
的输出生成到
test2.out
中,那么您可能需要

 TESTSCRIPTS= $(wildcard test*[0-9])
 run: $(patsubst %, %.out, $(TESTSCRIPTS))

 test%.out: test%
 # here some command to run the test%

作为Basile Starynkevitch完全正确答案的替代方案,还有(至少)两个其他选择

通过手动删除第一个条目,您可以避免运行不必要的命令(尽管可能是内置的)来结束列表(但这实际上可能比shell内置的成本更高)


尾随的
在这方面是非常重要的,因为
$(foreach)
的输出是一行,您需要
终止每个shell命令(或将其视为一个带参数的长命令)。

谢谢。哈!我喜欢
true
技巧。第二种解决方案不起作用,因为我的文件名是任意的。或者
$<$(addprefix&,$(wordlist 2,$(words$^,$)
$(foreach t,$(TARGETS),$)
,尽管后者会稍微改变语义。谢谢@Etan Reisner,smart,我喜欢第二种解决方案,因为
&
不是强制性的,因此,
foreach
似乎是最好的方法。考虑添加答案吗?你可以使用<代码>;<在这些答案中选择code>,而不是
&&
的好处
是指它在后面的位置有效,而
&&
不是这样的,因此您不需要
true
单词列表
游戏来让它工作,并且可以使用更简单的
foreach
解决方案。为了记录在案,除了下面的答案之外,
$(addsuffix;,$(TARGETS))
也可以完成这项工作。
 TESTSCRIPTS= $(wildcard test*[0-9])
 run: $(patsubst %, %.out, $(TESTSCRIPTS))

 test%.out: test%
 # here some command to run the test%
run: $(TARGETS)
        $< $(addprefix &&,$(wordlist 2,$(words $^),$^))
run: $(TARGETS)
        $(foreach t,$^,$t;)