2015-02-06 41 views
1

目前,只有這樣,我知道如何環路Makefile s是隻調用shell的for循環:是否有Makefile級別的「for」循環?

BIN_TARGETS=foo bar baz 

bin: $(BIN_TARGETS) 

run: bin 
     for FILE in $(BIN_TARGETS) ; do ./$$FILE ; done 

的問題,這是make只會調用shell的for循環,呼應整個循環,然後每一個程序運行並輸出其輸出(如果有任何錯誤,他們只是在循環的末端,僅在循環中的最後一個節目報道):

$ make run 
for FILE in foo bar baz ; do ./$FILE ; done 
output of foo 
output of bar 
output of baz 

有什麼Makefile -level for循環即會entially是完全等效的這個?:

run: bin 
     ./foo 
     ./bar 
     ./baz 

這將輸出這樣的:

$ make run 
./foo 
output of foo 
./bar 
output of bar 
./baz 
output of baz 

,並因爲它發生會報告任何錯誤。

+0

「報告錯誤」 你的意思是 「中止」?因爲shell循環會輸出錯誤/ etc。當他們發生但是不會放棄他們。 – 2015-02-06 21:22:16

+0

@EtanReisner:是的,基本上。通過「報告」,我的意思是'Makefile:XX:配方'運行'失敗'make:*** [run] Error 27'消息。 – Matt 2015-02-06 21:23:54

+0

你可以通過使用'./$FILE ||'來獲得shell循環的失敗行爲。退出$?'作爲我相信的循環體。 – 2015-02-06 21:25:09

回答

1

make有一個循環,但沒有一個會做你想要的。

make有$(foreach)但這是一個make-level結構,它將循環使句法/等。不是shell級別的東西。

A define會讓你按照你想要的方式定義配方的主體,並在你的配方中使用它,但我不能想出一種方法來從make中生成多行定義。

這將工作(根據期望的行爲),但我無法得到這在創造運行期間創建。我想出了

define RECIPE 
./foo 
./bar 
./baz 
endef 

all: 
     $(RECIPE) 
+0

謝謝!我會研究'define',看看我能用它做些什麼。 – Matt 2015-02-06 21:42:41

0

一種方法是使用假目標與虛構的後綴:

run: $(addsuffix .run,$(BIN_TARGETS)) 

%.run: % 
     ./$* 

然而,這時候有這樣的事情foo.run多個可能的匹配變得混亂。唯一不同的是它編譯並運行一個文件,然後編譯並運行一個文件,而不是編譯所有文件,然後運行所有文件。

1

你可以這樣做:

BIN_TARGETS:=foo bar baz 

define CMD 
    $1 

endef 

bin: $(BIN_TARGETS) 

run: bin 
    $(foreach t, $(BIN_TARGETS), $(call CMD,./$(t))) 

CMD變量是必須提供的命令之間的正確分離。我還沒有找到更簡潔的方法。

如果foobarbaz包含:

#!/bin/bash 

echo output of $0 

然後運行make run輸出:

./foo 
output of ./foo 
./bar 
output of ./bar 
./baz 
output of ./baz