Makefile:Loop循环的使用
Makefile有两种循环方式:
- foreach循环
- for循环
他们的语法格式分别是:
- $(foreach VAR,LIST,CMD 1;CMD 2;)
- for VAR in LIST; do CMD 1; CMD 2; done
如果一行显示不下,可以换行写,注意在行末尾用\表示继续后一行,就这样:
$(foreach VAR,LIST,\
CMD 1;\
CMD 2;\
)
for VAR in LIST; do \
CMD 1; \
CMD 2; \
done
举例来说:
SOURCE:=$(shell find ./ -name "*.c")
all: testfor testforeach
testfor:
@# LIST use variable
@for var in $(SOURCE); do echo $$var; done
@# LIST use shell command output
@for var in $(shell find ./ -name "*.c"); do echo $$var; done
@# Same as above but multiply line mode
@for var in $(shell find ./ -name "*.c"); do \
echo $$var; \
done
testforeach:
@$(foreach var,$(shell find ./ -name "*.c"),echo -n "this is ";echo -n $(var);echo " command";)
@# Same as above but multiply line mode
@$(foreach var,$(shell find ./ -name "*.c"),\
echo -n "this is ";\
echo -n $(var); \
echo " command";)
执行结果:
$ make
./b.c
./a.c
./b.c
./a.c
./b.c
./a.c
this is ./b.c command
this is ./a.c command
this is ./b.c command
this is ./a.c command
两种循环的差异:
- 对循环变量的引用上
for使用$$iterate, 而foreach使用$(iterate) - 对函数的支持,for循环无法支持函数运算,例如:
这个例子使用subst函数把循环变量的后缀从.c变成.txt
SOURCE:=a.c b.c
all: testfor testforeach
testfor:
@# LIST use variable
@for var in $(SOURCE); do \
echo $$var; \
echo $(subst .c,.txt,$$var); \
done
testforeach:
@$(foreach var,$(SOURCE),\
echo $(var); \
echo $(subst .c,.txt,$(var)); \
)
运行结果:
$ make
a.c
a.c
b.c
b.c
a.c
a.txt
b.c
b.txt
可见使用for循环没有达到我们的目的,输出还是.c后缀,而foreach则是能够完成所需功能,把.c后缀改成了.txt后缀。
鉴于此,通常情况下使用foreach更方便呢。