TARGETS = all clean install
$(TARGETS): %: $(patsubst %, %.%, $(DIRS))
$(foreach TGT, $(TARGETS), $(patsubst %, %.$(TGT), $(DIRS))):
$(MAKE) -C $(subst ., , $@)
这是UDT的Makefile,今天研究了一下,关键就是$(TARGETS): %: $(patsubst %, %.%, $(DIRS))这句比较难以理解,其实我们可以做些测试,比如将Makefile改成如下形式执行
DIRS = src app
TARGETS = all clean install
$(TARGETS): %: $(patsubst %, %.%, $(DIRS))
echo ---$@
执行后发现少了一个目标src.all,再修改Makefile
DIRS = src app
TARGETS = all clean install
$(TARGETS): %: $(patsubst %, %.%, $(DIRS))
echo ---$@
src.all:
echo src.all
执行后提示发现少了app.all,同样再添加app.all目标
DIRS = src app
TARGETS = all clean install
$(TARGETS): %: $(patsubst %, %.%, $(DIRS))
echo ---$@
src.all:
echo src.all
app.all:
echo app.all
最后执行通过,执行的结果如下
echo src.all
src.all
echo app.all
app.all
echo ---all
---all
从结果中可以看出第一个echo打印出的是all,说明TARGETS在作为目标的时候默认取第一个值-->all,而后面的%: $(patsubst %, %.%, $(DIRS))的作用显而易见,
就是产生两个字符串src.all和app.all,这两个字符串就是all的两个依赖,这个操作$(patsubst %, %.%, $(DIRS))大家都知道是干什么用的,就是产生两个字符串
src.%和app.%,则由此可以推断出$(TARGETS): %: $(patsubst %, %.%, $(DIRS))中间的%:作用就是把$(TARGETS)的默认值替换后面的src.%和app.%中%位置,
产生两个新的字符串src.all和app.all,而最上面给出的Makefile里面,foreach函数就是用来产生这src.all和app.all两个目标的。
当你手动执行make clean的时候,则就会产生另外两个依赖,src.clean和app.clean